llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-compiler-rt-sanitizer Author: Vitaly Buka (vitalybuka) <details> <summary>Changes</summary> We can't distinguish UAR and UAS, but by definition UAR is already UAS. --- Full diff: https://github.com/llvm/llvm-project/pull/76133.diff 5 Files Affected: - (modified) compiler-rt/lib/hwasan/hwasan_report.cpp (+36-10) - (added) compiler-rt/test/hwasan/TestCases/stack-overflow.c (+26) - (modified) compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c (+2) - (modified) compiler-rt/test/hwasan/TestCases/stack-uar.c (+5-3) - (added) compiler-rt/test/hwasan/TestCases/stack-underflow.c (+26) ``````````diff diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp index dc34cded48e12c..253b64773fe384 100644 --- a/compiler-rt/lib/hwasan/hwasan_report.cpp +++ b/compiler-rt/lib/hwasan/hwasan_report.cpp @@ -221,29 +221,55 @@ static void PrintStackAllocations(const StackAllocationsRingBuffer *sa, for (LocalInfo &local : frame.locals) { if (!local.has_frame_offset || !local.has_size || !local.has_tag_offset) continue; + if (!(local.name && internal_strlen(local.name)) && + !(local.function_name && internal_strlen(local.name)) && + !local.decl_file) + continue; tag_t obj_tag = base_tag ^ local.tag_offset; if (obj_tag != addr_tag) continue; - // Calculate the offset from the object address to the faulting - // address. Because we only store bits 4-19 of FP (bits 0-3 are - // guaranteed to be zero), the calculation is performed mod 2^20 and may - // harmlessly underflow if the address mod 2^20 is below the object - // address. - uptr obj_offset = - (untagged_addr - fp - local.frame_offset) & (kRecordFPModulus - 1); - if (obj_offset >= local.size) - continue; + uptr local_beg = (fp + local.frame_offset) | + (untagged_addr & ~(uptr(kRecordFPModulus) - 1)); + uptr local_end = local_beg + local.size; + if (!found_local) { Printf("\nPotentially referenced stack objects:\n"); found_local = true; } + + uptr offset; + const char *whence; + const char *cause; + if (local_beg <= untagged_addr && untagged_addr < local_end) { + offset = untagged_addr - local_beg; + whence = "inside"; + cause = "use-after-scope"; + } else if (untagged_addr >= local_end) { + offset = untagged_addr - local_end; + whence = "after"; + cause = "stack-buffer-overflow"; + } else { + offset = local_beg - untagged_addr; + whence = "before"; + cause = "stack-buffer-overflow"; + } + Decorator d; + Printf("%s", d.Error()); + Printf("Cause: %s\n", cause); + Printf("%s", d.Default()); + Printf("%s", d.Location()); + Printf("%p is located %zd bytes %s a %zd-byte region [%p,%p)\n", + untagged_addr, offset, whence, local_end - local_beg, local_beg, + local_end); + Printf("%s", d.Allocation()); StackTracePrinter::GetOrInit()->RenderSourceLocation( &location, local.decl_file, local.decl_line, 0, common_flags()->symbolize_vs_style, common_flags()->strip_path_prefix); - Printf(" %s in %s %s\n", local.name, local.function_name, + Printf("declared as %s in %s %s\n", local.name, local.function_name, location.data()); location.clear(); + Printf("%s\n", d.Default()); } frame.Clear(); } diff --git a/compiler-rt/test/hwasan/TestCases/stack-overflow.c b/compiler-rt/test/hwasan/TestCases/stack-overflow.c new file mode 100644 index 00000000000000..ba3e00551f5e00 --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/stack-overflow.c @@ -0,0 +1,26 @@ +// RUN: %clang_hwasan -g %s -o %t && not %run %t 2>&1 | FileCheck %s + +// Stack histories currently are not recorded on x86. +// XFAIL: target=x86_64{{.*}} + +__attribute((noinline)) +void buggy() { + char c[64]; + char *volatile p = c; + p[65] = 0; +} + +int main() { + buggy(); + // CHECK: WRITE of size 1 at + // CHECK: #0 {{.*}} in buggy{{.*}}stack-overflow.c:[[@LINE-6]] + // CHECK: Cause: stack tag-mismatch + // CHECK: is located in stack of thread + // CHECK: Potentially referenced stack objects: + // CHECK: Cause: stack-buffer-overflow + // CHECK-NEXT: 0x{{.*}} is located 1 bytes after a 64-byte region + // CHECK-NEXT: declared as c in buggy {{.*}}stack-overflow.c: + // CHECK: Memory tags around the buggy address + + // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in buggy +} diff --git a/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c b/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c index b06568e12eba7c..7a2a11593e7afe 100644 --- a/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c +++ b/compiler-rt/test/hwasan/TestCases/stack-uar-dynamic.c @@ -21,6 +21,8 @@ char *buggy(int b) { int main() { char *p = buggy(1); // CHECK: Potentially referenced stack objects: + // CHECK-NEXT: use-after-scope + // CHECK-NEXT: 0x{{.*}} is located 0 bytes inside a 64-byte region // CHECK-NEXT: c in buggy p[0] = 0; } diff --git a/compiler-rt/test/hwasan/TestCases/stack-uar.c b/compiler-rt/test/hwasan/TestCases/stack-uar.c index 48440a47d5f5f4..b2a40a19251ab6 100644 --- a/compiler-rt/test/hwasan/TestCases/stack-uar.c +++ b/compiler-rt/test/hwasan/TestCases/stack-uar.c @@ -50,15 +50,17 @@ int main() { // CHECK: Cause: stack tag-mismatch // CHECK: is located in stack of thread // CHECK: Potentially referenced stack objects: - // CHECK-NEXT: {{zzz|yyy}} in buggy {{.*}}stack-uar.c: - // CHECK-NEXT: Memory tags around the buggy address + // CHECK: Cause: use-after-scope + // CHECK-NEXT: 0x{{.*}} is located 0 bytes inside a 2048-byte region + // CHECK-NEXT: declared as {{zzz|yyy}} in buggy {{.*}}stack-uar.c: + // CHECK: Memory tags around the buggy address // NOSYM: Previously allocated frames: // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uar.c.tmp+0x{{.*}}){{$}} // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uar.c.tmp+0x{{.*}}){{$}} // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uar.c.tmp+0x{{.*}}){{$}} // NOSYM-NEXT: record_addr:0x{{.*}} record:0x{{.*}} ({{.*}}/stack-uar.c.tmp+0x{{.*}}){{$}} - // NOSYM-NEXT: Memory tags around the buggy address + // NOSYM: Memory tags around the buggy address // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in main } diff --git a/compiler-rt/test/hwasan/TestCases/stack-underflow.c b/compiler-rt/test/hwasan/TestCases/stack-underflow.c new file mode 100644 index 00000000000000..131140ce35e616 --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/stack-underflow.c @@ -0,0 +1,26 @@ +// RUN: %clang_hwasan -g %s -o %t && not %run %t 2>&1 | FileCheck %s + +// Stack histories currently are not recorded on x86. +// XFAIL: target=x86_64{{.*}} + +__attribute((noinline)) +void buggy() { + char c[64]; + char *volatile p = c; + p[-2] = 0; +} + +int main() { + buggy(); + // CHECK: WRITE of size 1 at + // CHECK: #0 {{.*}} in buggy{{.*}}stack-underflow.c:[[@LINE-6]] + // CHECK: Cause: stack tag-mismatch + // CHECK: is located in stack of thread + // CHECK: Potentially referenced stack objects: + // CHECK: Cause: stack-buffer-overflow + // CHECK-NEXT: 0x{{.*}} is located 2 bytes before a 64-byte region + // CHECK-NEXT: declared as c in buggy {{.*}}stack-underflow.c: + // CHECK: Memory tags around the buggy address + + // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in buggy +} `````````` </details> https://github.com/llvm/llvm-project/pull/76133 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits