Skip to content

Commit

Permalink
[lsan] Invoke hooks on realloc
Browse files Browse the repository at this point in the history
Previously lsan would not invoke hooks on reallocations.
An accompanying regression test is included in sanitizer_common.

This change also moves hook calls to a location where subsequent
calls (via an external caller) to __sanitizer_get_allocated_size
via hooks will return a valid size.

This allows a faster version of __sanitizer_get_allocated_size
to be implemented, which can skip checks.

Test to ensure RunFreeHooks' call order will come with
__sanitizer_get_allocated_size_fast

Differential Revision: https://reviews.llvm.org/D151175
  • Loading branch information
Northbadge committed May 23, 2023
1 parent da60b9e commit 90418dc
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 7 deletions.
4 changes: 2 additions & 2 deletions compiler-rt/lib/lsan/lsan_allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,14 @@ static void RegisterAllocation(const StackTrace &stack, void *p, uptr size) {
m->stack_trace_id = StackDepotPut(stack);
m->requested_size = size;
atomic_store(reinterpret_cast<atomic_uint8_t *>(m), 1, memory_order_relaxed);
RunMallocHooks(p, size);
}

static void RegisterDeallocation(void *p) {
if (!p) return;
ChunkMetadata *m = Metadata(p);
CHECK(m);
RunFreeHooks(p);
atomic_store(reinterpret_cast<atomic_uint8_t *>(m), 0, memory_order_relaxed);
}

Expand Down Expand Up @@ -104,7 +106,6 @@ void *Allocate(const StackTrace &stack, uptr size, uptr alignment,
if (cleared && allocator.FromPrimary(p))
memset(p, 0, size);
RegisterAllocation(stack, p, size);
RunMallocHooks(p, size);
return p;
}

Expand All @@ -119,7 +120,6 @@ static void *Calloc(uptr nmemb, uptr size, const StackTrace &stack) {
}

void Deallocate(void *p) {
RunFreeHooks(p);
RegisterDeallocation(p);
allocator.Deallocate(GetAllocatorCache(), p);
}
Expand Down
18 changes: 13 additions & 5 deletions compiler-rt/test/sanitizer_common/TestCases/malloc_hook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const volatile void *global_ptr;
// Note: avoid calling functions that allocate memory in malloc/free
// to avoid infinite recursion.
void __sanitizer_malloc_hook(const volatile void *ptr, size_t sz) {
if (__sanitizer_get_ownership(ptr) && sz == 4) {
if (__sanitizer_get_ownership(ptr) && sz == sizeof(int)) {
WRITE("MallocHook\n");
global_ptr = ptr;
}
Expand All @@ -42,7 +42,7 @@ void FreeHook2(const volatile void *ptr) { WRITE("FH2\n"); }
// TLS shadow for function parameters before calling operator
// new and, eventually, user-provided hook.
__attribute__((noinline)) void allocate(int *unused1, int *unused2) {
x = new int;
x = reinterpret_cast<int *>(malloc(sizeof(int)));
}

int main() {
Expand All @@ -57,9 +57,17 @@ int main() {
if (global_ptr != (void*)x) {
_exit(1);
}
*x = 0;
delete x;
// CHECK: FreeHook

// Check that realloc invokes hooks
// We realloc to 128 here to avoid potential oversizing by allocators
// making this a no-op.
x = reinterpret_cast<int *>(realloc((int *)x, sizeof(int) * 128));
// CHECK-DAG: FreeHook{{[[:space:]].*}}FH1{{[[:space:]].*}}FH2
// CHECK-DAG: MH1{{[[:space:]].*}}MH2

x[0] = 0;
x[127] = -1;
free((void *)x);
// CHECK: FH1
// CHECK: FH2
return 0;
Expand Down

0 comments on commit 90418dc

Please sign in to comment.