diff --git a/compiler-rt/lib/hwasan/hwasan_report.cc b/compiler-rt/lib/hwasan/hwasan_report.cc index 60eb5c1a498b..4c6c8b931bfb 100644 --- a/compiler-rt/lib/hwasan/hwasan_report.cc +++ b/compiler-rt/lib/hwasan/hwasan_report.cc @@ -46,19 +46,21 @@ class Decorator: public __sanitizer::SanitizerCommonDecorator { const char *Thread() { return Green(); } }; -bool FindHeapAllocation(HeapAllocationsRingBuffer *rb, +// Returns the index of the rb element that matches tagged_addr (plus one), +// or zero if found nothing. +uptr FindHeapAllocation(HeapAllocationsRingBuffer *rb, uptr tagged_addr, HeapAllocationRecord *har) { - if (!rb) return false; + if (!rb) return 0; for (uptr i = 0, size = rb->size(); i < size; i++) { auto h = (*rb)[i]; if (h.tagged_addr <= tagged_addr && h.tagged_addr + h.requested_size > tagged_addr) { *har = h; - return true; + return i + 1; } } - return false; + return 0; } void PrintAddressDescription(uptr tagged_addr, uptr access_size) { @@ -110,7 +112,7 @@ void PrintAddressDescription(uptr tagged_addr, uptr access_size) { Thread::VisitAllLiveThreads([&](Thread *t) { // Scan all threads' ring buffers to find if it's a heap-use-after-free. HeapAllocationRecord har; - if (FindHeapAllocation(t->heap_allocations(), tagged_addr, &har)) { + if (uptr D = FindHeapAllocation(t->heap_allocations(), tagged_addr, &har)) { Printf("%s", d.Location()); Printf("%p is located %zd bytes inside of %zd-byte region [%p,%p)\n", untagged_addr, untagged_addr - UntagAddr(har.tagged_addr), @@ -127,6 +129,11 @@ void PrintAddressDescription(uptr tagged_addr, uptr access_size) { GetStackTraceFromId(har.alloc_context_id).Print(); t->Announce(); + // Print a developer note: the index of this heap object + // in the thread's deallocation ring buffer. + Printf("hwasan_dev_note_heap_rb_distance: %zd %zd\n", D, + flags()->heap_history_size); + num_descriptions_printed++; } diff --git a/compiler-rt/test/hwasan/TestCases/uaf_with_rb_distance.c b/compiler-rt/test/hwasan/TestCases/uaf_with_rb_distance.c new file mode 100644 index 000000000000..25aae5256c41 --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/uaf_with_rb_distance.c @@ -0,0 +1,27 @@ +// Checks how we print the developer note "hwasan_dev_note_heap_rb_distance". +// RUN: %clang_hwasan %s -o %t +// RUN: not %run %t 10 2>&1 | FileCheck %s --check-prefix=D10 +// RUN: not %run %t 42 2>&1 | FileCheck %s --check-prefix=D42 + +// REQUIRES: stable-runtime + +#include +#include +#include + + +void *p[100]; + +int main(int argc, char **argv) { + __hwasan_enable_allocator_tagging(); + int distance = argc >= 2 ? atoi(argv[1]) : 1; + for (int i = 0; i < 100; i++) + p[i] = malloc(i); + for (int i = 0; i < 100; i++) + free(p[i]); + + *(int*)p[distance] = 0; +} + +// D10: hwasan_dev_note_heap_rb_distance: 90 1023 +// D42: hwasan_dev_note_heap_rb_distance: 58 1023