[compiler-rt] 2a60ab7 - [hwasan] print exact mismatch offset for short granules.

Florian Mayer via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 28 11:01:45 PDT 2021


Author: Florian Mayer
Date: 2021-06-28T19:01:31+01:00
New Revision: 2a60ab76a796637d49bf1c7191f5b5a0c92f81bc

URL: https://github.com/llvm/llvm-project/commit/2a60ab76a796637d49bf1c7191f5b5a0c92f81bc
DIFF: https://github.com/llvm/llvm-project/commit/2a60ab76a796637d49bf1c7191f5b5a0c92f81bc.diff

LOG: [hwasan] print exact mismatch offset for short granules.

Reviewed By: eugenis

Differential Revision: https://reviews.llvm.org/D104463

Added: 
    

Modified: 
    compiler-rt/lib/hwasan/hwasan_report.cpp
    compiler-rt/test/hwasan/TestCases/heap-buffer-overflow-into.c
    compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c
    compiler-rt/test/hwasan/TestCases/mem-intrinsics.c

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp
index 715b4e05992a6..b6f968ea10457 100644
--- a/compiler-rt/lib/hwasan/hwasan_report.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_report.cpp
@@ -630,9 +630,24 @@ void ReportTagMismatch(StackTrace *stack, uptr tagged_addr, uptr access_size,
   Printf("%s of size %zu at %p tags: %02x/%02x (ptr/mem) in thread T%zd\n",
          is_store ? "WRITE" : "READ", access_size, untagged_addr, ptr_tag,
          mem_tag, t->unique_id());
+  if (mem_tag < kShadowAlignment) {
+    tag_t *granule_ptr = reinterpret_cast<tag_t *>((untagged_addr + offset) &
+                                                   ~(kShadowAlignment - 1));
+    // If offset is 0, (untagged_addr + offset) is not aligned to granules.
+    // This is the offset of the leftmost accessed byte within the bad granule.
+    u8 in_granule_offset = (untagged_addr + offset) & (kShadowAlignment - 1);
+    // The first mismatch was a short granule that matched the ptr_tag.
+    if (granule_ptr[kShadowAlignment - 1] == ptr_tag) {
+      // If the access starts after the end of the short granule, then the first
+      // bad byte is the first byte of the access; otherwise it is the first
+      // byte past the end of the short granule
+      if (mem_tag > in_granule_offset) {
+        offset += mem_tag - in_granule_offset;
+      }
+    }
+  }
   if (offset != 0)
-    Printf("Invalid access starting at offset [%zu, %zu)\n", offset,
-           Min(access_size, static_cast<uptr>(offset) + (1 << kShadowScale)));
+    Printf("Invalid access starting at offset %zu\n", offset);
   Printf("%s", d.Default());
 
   stack->Print();

diff  --git a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow-into.c b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow-into.c
index af4256b84db03..8526c81f4cd7d 100644
--- a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow-into.c
+++ b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow-into.c
@@ -1,5 +1,8 @@
 // RUN: %clang_hwasan  %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK
+// RUN: not %run %t 5 10 2>&1 | FileCheck %s --check-prefix=CHECK5
+// RUN: not %run %t 7 10 2>&1 | FileCheck %s --check-prefix=CHECK7
+// RUN: not %run %t 8 20 2>&1 | FileCheck %s --check-prefix=CHECK8
+// RUN: not %run %t 32 20 2>&1 | FileCheck %s --check-prefix=CHECK32
 
 // REQUIRES: stable-runtime
 
@@ -10,8 +13,20 @@
 
 int main(int argc, char **argv) {
   __hwasan_enable_allocator_tagging();
-  char *volatile x = (char *)malloc(10);
-  memset(x + 5, 0, 26);
-  // CHECK: is located 5 bytes inside 10-byte region
+  if (argc < 2) {
+    fprintf(stderr, "Invalid number of arguments.");
+    abort();
+  }
+  int read_offset = argc < 2 ? 5 : atoi(argv[1]);
+  int size = argc < 3 ? 10 : atoi(argv[2]);
+  char *volatile x = (char *)malloc(size);
+  memset(x + read_offset, 0, 26);
+  // CHECK5: Invalid access starting at offset 5
+  // CHECK5: is located 5 bytes inside 10-byte region
+  // CHECK7: Invalid access starting at offset 3
+  // CHECK7: is located 7 bytes inside 10-byte region
+  // CHECK8: Invalid access starting at offset 12
+  // CHECK8: is located 8 bytes inside 20-byte region
+  // CHECK32: is located 12 bytes to the right of 20-byte region
   free(x);
 }

diff  --git a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c
index 67398141209af..8e8719a7f65c4 100644
--- a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c
+++ b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c
@@ -52,12 +52,14 @@ int main(int argc, char **argv) {
 // CHECKM: is located 0 bytes to the right of 1000000-byte region
 //
 // CHECK31: tags: [[TAG:..]]/0e (ptr/mem)
+// CHECK31-NOT: Invalid access starting at offset
 // CHECK31: is located 1 bytes to the right of 30-byte region
 // CHECK31: Memory tags around the buggy address
 // CHECK31: [0e]
 // CHECK31: Tags for short granules around the buggy address
 // CHECK31: {{\[}}[[TAG]]]
 //
+// CHECK20-NOT: Invalid access starting at offset
 // CHECK20: is located 10 bytes to the right of 20-byte region [0x{{.*}}0,0x{{.*}}4)
   free(x);
 }

diff  --git a/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c b/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c
index 28568c828cea1..44b9fd67cbcc6 100644
--- a/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c
+++ b/compiler-rt/test/hwasan/TestCases/mem-intrinsics.c
@@ -23,7 +23,7 @@ int main() {
   write(STDOUT_FILENO, "recovered\n", 10);
   // WRITE: ERROR: HWAddressSanitizer: tag-mismatch on address
   // WRITE: WRITE of size 32 at {{.*}} tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem)
-  // WRITE: Invalid access starting at offset [16, 32)
+  // WRITE: Invalid access starting at offset 16
   // WRITE: Memory tags around the buggy address (one tag corresponds to 16 bytes):
   // WRITE: =>{{.*}}[[PTR_TAG]]{{[[:space:]]\[}}[[MEM_TAG]]
   // WRITE-NOT: recovered


        


More information about the llvm-commits mailing list