[compiler-rt] [HWASAN] Prevent SEGV in report near inacceccible memory (PR #66861)

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 19 23:43:53 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-compiler-rt-sanitizer

<details>
<summary>Changes</summary>

We can't use IsAccessibleMemoryRange on short granule check because of
performance impact. However we can prevent crashing if report prints out
"Tags for short granules around the buggy address".


---
Full diff: https://github.com/llvm/llvm-project/pull/66861.diff


2 Files Affected:

- (modified) compiler-rt/lib/hwasan/hwasan_report.cpp (+3-2) 
- (added) compiler-rt/test/hwasan/TestCases/report-unmapped.cpp (+39) 


``````````diff
diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp
index 442c5b736611dfb..2a6055a49a706b7 100644
--- a/compiler-rt/lib/hwasan/hwasan_report.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_report.cpp
@@ -357,8 +357,9 @@ static void PrintTagsAroundAddr(tag_t *tag_ptr) {
       "to %zd bytes):\n",
       kShadowAlignment);
   PrintTagInfoAroundAddr(tag_ptr, 3, [](InternalScopedString &s, tag_t *tag) {
-    if (*tag >= 1 && *tag <= kShadowAlignment) {
-      uptr granule_addr = ShadowToMem(reinterpret_cast<uptr>(tag));
+    uptr granule_addr = ShadowToMem(reinterpret_cast<uptr>(tag));
+    if (*tag >= 1 && *tag <= kShadowAlignment &&
+        IsAccessibleMemoryRange(granule_addr, kShadowAlignment)) {
       s.AppendF("%02x",
                 *reinterpret_cast<u8 *>(granule_addr + kShadowAlignment - 1));
     } else {
diff --git a/compiler-rt/test/hwasan/TestCases/report-unmapped.cpp b/compiler-rt/test/hwasan/TestCases/report-unmapped.cpp
new file mode 100644
index 000000000000000..ceaf7ecff90bcbf
--- /dev/null
+++ b/compiler-rt/test/hwasan/TestCases/report-unmapped.cpp
@@ -0,0 +1,39 @@
+// RUN: %clangxx_hwasan %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+#include <sanitizer/hwasan_interface.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+  const size_t kPS = sysconf(_SC_PAGESIZE);
+
+  void *r = nullptr;
+  int res = posix_memalign(&r, kPS, 2 * kPS);
+  if (res) {
+    perror("Failed to mmap: ");
+    abort();
+  }
+  
+  r = __hwasan_tag_pointer(r, 0);
+  __hwasan_tag_memory(r, 1,  2 * kPS);
+  
+  // Disable access to the page just after tag-mismatch report address.
+  res = mprotect((char*)r + kPS, kPS, PROT_NONE);
+  if (res) {
+    perror("Failed to mprotect: ");
+    abort();
+  }
+
+  // Trigger tag-mismatch report address.
+  return *((char*)r + kPS - 1);
+}
+
+// CHECK: ERROR: HWAddressSanitizer: tag-mismatch on address
+// CHECK: Memory tags around the buggy address
+// CHECK: Tags for short granules around
+
+// Check that report is complete.
+// CHECK: SUMMARY: HWAddressSanitizer

``````````

</details>


https://github.com/llvm/llvm-project/pull/66861


More information about the llvm-commits mailing list