diff --git a/compiler-rt/lib/hwasan/hwasan_report.cpp b/compiler-rt/lib/hwasan/hwasan_report.cpp --- a/compiler-rt/lib/hwasan/hwasan_report.cpp +++ b/compiler-rt/lib/hwasan/hwasan_report.cpp @@ -341,13 +341,22 @@ uptr mem = ShadowToMem(reinterpret_cast(candidate)); HwasanChunkView chunk = FindHeapChunkByAddress(mem); if (chunk.IsAllocated()) { + uptr offset; + const char *whence; + if (untagged_addr < chunk.End() && untagged_addr >= chunk.Beg()) { + offset = untagged_addr - chunk.Beg(); + whence = "inside"; + } else if (candidate == left) { + offset = untagged_addr - chunk.End(); + whence = "to the right of"; + } else { + offset = chunk.Beg() - untagged_addr; + whence = "to the left of"; + } Printf("%s", d.Location()); - Printf("%p is located %zd bytes to the %s of %zd-byte region [%p,%p)\n", - untagged_addr, - candidate == left ? untagged_addr - chunk.End() - : chunk.Beg() - untagged_addr, - candidate == left ? "right" : "left", chunk.UsedSize(), - chunk.Beg(), chunk.End()); + Printf("%p is located %zd bytes %s %zd-byte region [%p,%p)\n", + untagged_addr, offset, whence, chunk.UsedSize(), chunk.Beg(), + chunk.End()); Printf("%s", d.Allocation()); Printf("allocated here:\n"); Printf("%s", d.Default()); diff --git a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow-into.c b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow-into.c new file mode 100644 --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow-into.c @@ -0,0 +1,17 @@ +// RUN: %clang_hwasan %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK + +// REQUIRES: stable-runtime + +#include +#include +#include +#include + +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 + free(x); +}