mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
[hwasan] On every use-after-free print a developer note: the index of this heap object in the thread's deallocation ring buffer. Mostly useful to hwasan developers, will hopefully let us know the good size of the deallocation ring buffer
llvm-svn: 342014
This commit is contained in:
@@ -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++;
|
||||
}
|
||||
|
||||
|
||||
27
compiler-rt/test/hwasan/TestCases/uaf_with_rb_distance.c
Normal file
27
compiler-rt/test/hwasan/TestCases/uaf_with_rb_distance.c
Normal file
@@ -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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sanitizer/hwasan_interface.h>
|
||||
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user