[Openmp-commits] [mlir] [openmp] [libcxx] [compiler-rt] [llvm] [lldb] [libc] [clang] [flang] [hwasan] Classify stack overflow, and use after scope (PR #76133)
Vitaly Buka via Openmp-commits
openmp-commits at lists.llvm.org
Thu Dec 21 17:35:41 PST 2023
https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/76133
>From 89636904337efe75ef6e0743e4f098f0d5b5ab56 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Wed, 20 Dec 2023 23:58:05 -0800
Subject: [PATCH 1/4] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?=
=?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.4
[skip ci]
---
compiler-rt/lib/hwasan/hwasan_report.cpp | 26 ++++++++++++++-----
.../test/hwasan/TestCases/Linux/syscalls.cpp | 2 +-
.../hwasan/TestCases/heap-buffer-overflow.c | 7 ++---
3 files changed, 24 insertions(+), 11 deletions(-)
diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp
index 5e8aa315801bcd..dc34cded48e12c 100644
--- a/compiler-rt/lib/hwasan/hwasan_report.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_report.cpp
@@ -205,6 +205,7 @@ static void PrintStackAllocations(const StackAllocationsRingBuffer *sa,
tag_t addr_tag, uptr untagged_addr) {
uptr frames = Min((uptr)flags()->stack_history_size, sa->size());
bool found_local = false;
+ InternalScopedString location;
for (uptr i = 0; i < frames; i++) {
const uptr *record_addr = &(*sa)[i];
uptr record = *record_addr;
@@ -233,11 +234,16 @@ static void PrintStackAllocations(const StackAllocationsRingBuffer *sa,
if (obj_offset >= local.size)
continue;
if (!found_local) {
- Printf("Potentially referenced stack objects:\n");
+ Printf("\nPotentially referenced stack objects:\n");
found_local = true;
}
- Printf(" %s in %s %s:%d\n", local.name, local.function_name,
- local.decl_file, local.decl_line);
+ 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,
+ location.data());
+ location.clear();
}
frame.Clear();
}
@@ -363,7 +369,7 @@ static void PrintTagsAroundAddr(uptr addr, GetTag get_tag,
InternalScopedString s;
addr = MemToShadow(addr);
s.AppendF(
- "Memory tags around the buggy address (one tag corresponds to %zd "
+ "\nMemory tags around the buggy address (one tag corresponds to %zd "
"bytes):\n",
kShadowAlignment);
PrintTagInfoAroundAddr(addr, kShadowLines, s,
@@ -648,19 +654,23 @@ void BaseReport::PrintHeapOrGlobalCandidate() const {
if (candidate.heap.is_allocated) {
uptr offset;
const char *whence;
+ const char *cause;
if (candidate.heap.begin <= untagged_addr &&
untagged_addr < candidate.heap.end) {
offset = untagged_addr - candidate.heap.begin;
whence = "inside";
+ cause = "heap-use-after-free";
} else if (candidate.after) {
offset = untagged_addr - candidate.heap.end;
whence = "after";
+ cause = "heap-buffer-overflow";
} else {
offset = candidate.heap.begin - untagged_addr;
whence = "before";
+ cause = "heap-buffer-underflow";
}
Printf("%s", d.Error());
- Printf("\nCause: heap-buffer-overflow\n");
+ Printf("\nCause: %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",
@@ -803,8 +813,10 @@ void BaseReport::PrintAddressDescription() const {
}
// Print the remaining threads, as an extra information, 1 line per thread.
- if (flags()->print_live_threads_info)
+ if (flags()->print_live_threads_info) {
+ Printf("\n");
hwasanThreadList().VisitAllLiveThreads([&](Thread *t) { t->Announce(); });
+ }
if (!num_descriptions_printed)
// We exhausted our possibilities. Bail out.
@@ -1020,7 +1032,7 @@ void ReportTagMismatch(StackTrace *stack, uptr tagged_addr, uptr access_size,
// See the frame breakdown defined in __hwasan_tag_mismatch (from
// hwasan_tag_mismatch_{aarch64,riscv64}.S).
void ReportRegisters(const uptr *frame, uptr pc) {
- Printf("Registers where the failure occurred (pc %p):\n", pc);
+ Printf("\nRegisters where the failure occurred (pc %p):\n", pc);
// We explicitly print a single line (4 registers/line) each iteration to
// reduce the amount of logcat error messages printed. Each Printf() will
diff --git a/compiler-rt/test/hwasan/TestCases/Linux/syscalls.cpp b/compiler-rt/test/hwasan/TestCases/Linux/syscalls.cpp
index 154b6989899352..eee43f458fac10 100644
--- a/compiler-rt/test/hwasan/TestCases/Linux/syscalls.cpp
+++ b/compiler-rt/test/hwasan/TestCases/Linux/syscalls.cpp
@@ -26,7 +26,7 @@ int main(int argc, char *argv[]) {
__sanitizer_syscall_pre_recvmsg(0, buf - 1, 0);
// CHECK: HWAddressSanitizer: tag-mismatch on address [[PTR:0x[a-f0-9]+]]
- // CHECK: Cause: heap-buffer-overflow
+ // CHECK: Cause: heap-buffer-underflow
// CHECK: [[PTR]] is located 1 bytes before a 1000-byte region
free(buf);
diff --git a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c
index 4e6638be584b0d..c1c7d458b9424f 100644
--- a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c
+++ b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c
@@ -29,7 +29,8 @@ int main(int argc, char **argv) {
if (size == 1000000) {
fprintf(stderr, "is a large allocated heap chunk; size: 1003520 offset: %d\n",
offset);
- fprintf(stderr, "Cause: heap-buffer-overflow\n");
+ fprintf(stderr, "Cause: heap-buffer-%s\n",
+ offset == -30 ? "underflow" : "overflow");
fprintf(stderr, "is located %s a 1000000-byte region\n",
offset == -30 ? "30 bytes before" : "0 bytes after");
return -1;
@@ -44,11 +45,11 @@ int main(int argc, char **argv) {
// CHECK80: Cause: heap-buffer-overflow
// CHECK80: is located 50 bytes after a 30-byte region
//
-// CHECKm30: Cause: heap-buffer-overflow
+// CHECKm30: Cause: heap-buffer-underflow
// CHECKm30: is located 30 bytes before a 30-byte region
//
// CHECKMm30: is a large allocated heap chunk; size: 1003520 offset: -30
-// CHECKMm30: Cause: heap-buffer-overflow
+// CHECKMm30: Cause: heap-buffer-underflow
// CHECKMm30: is located 30 bytes before a 1000000-byte region
//
// CHECKM: is a large allocated heap chunk; size: 1003520 offset: 1000000
>From bd2a5987e9c6e3e48dd091cbe08601b26ba4d303 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Thu, 21 Dec 2023 00:06:16 -0800
Subject: [PATCH 2/4] update tests
Created using spr 1.3.4
---
compiler-rt/lib/hwasan/hwasan_report.cpp | 2 +-
compiler-rt/test/hwasan/TestCases/stack-underflow.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp
index 253b64773fe384..ae8884390ac796 100644
--- a/compiler-rt/lib/hwasan/hwasan_report.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_report.cpp
@@ -251,7 +251,7 @@ static void PrintStackAllocations(const StackAllocationsRingBuffer *sa,
} else {
offset = local_beg - untagged_addr;
whence = "before";
- cause = "stack-buffer-overflow";
+ cause = "stack-buffer-underflow";
}
Decorator d;
Printf("%s", d.Error());
diff --git a/compiler-rt/test/hwasan/TestCases/stack-underflow.c b/compiler-rt/test/hwasan/TestCases/stack-underflow.c
index 131140ce35e616..7f790afc553fd1 100644
--- a/compiler-rt/test/hwasan/TestCases/stack-underflow.c
+++ b/compiler-rt/test/hwasan/TestCases/stack-underflow.c
@@ -17,7 +17,7 @@ int main() {
// CHECK: Cause: stack tag-mismatch
// CHECK: is located in stack of thread
// CHECK: Potentially referenced stack objects:
- // CHECK: Cause: stack-buffer-overflow
+ // CHECK: Cause: stack-buffer-underflow
// 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
>From 995ecd32254a051661d7cda466c6c7cc7714ef94 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Thu, 21 Dec 2023 17:34:09 -0800
Subject: [PATCH 3/4] Update hwasan_report.cpp
---
compiler-rt/lib/hwasan/hwasan_report.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp
index 3d192d14975319..b35c731ea1e3ad 100644
--- a/compiler-rt/lib/hwasan/hwasan_report.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_report.cpp
@@ -228,6 +228,8 @@ static void PrintStackAllocations(const StackAllocationsRingBuffer *sa,
tag_t obj_tag = base_tag ^ local.tag_offset;
if (obj_tag != addr_tag)
continue;
+ // Guess top bits of local variable from the faulting address, because
+ // we only store bits 4-19 of FP (bits 0-3 are guaranteed to be zero).
uptr local_beg = (fp + local.frame_offset) |
(untagged_addr & ~(uptr(kRecordFPModulus) - 1));
uptr local_end = local_beg + local.size;
>From ee7914a221cca48a369c09fa29f9b354c56e466d Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Thu, 21 Dec 2023 17:35:31 -0800
Subject: [PATCH 4/4] Update hwasan_report.cpp
---
compiler-rt/lib/hwasan/hwasan_report.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp
index b35c731ea1e3ad..5b3a99adfea7c5 100644
--- a/compiler-rt/lib/hwasan/hwasan_report.cpp
+++ b/compiler-rt/lib/hwasan/hwasan_report.cpp
@@ -779,8 +779,6 @@ void BaseReport::PrintAddressDescription() const {
// Check stack first. If the address is on the stack of a live thread, we
// know it cannot be a heap / global overflow.
for (const auto &sa : allocations.stack) {
- // TODO(fmayer): figure out how to distinguish use-after-return and
- // stack-buffer-overflow.
Printf("%s", d.Error());
Printf("\nCause: stack tag-mismatch\n");
Printf("%s", d.Location());
More information about the Openmp-commits
mailing list