Skip to content

Commit 1daa48f

Browse files
committed
[lsan] realloc: don't deallocate if requested size is too large
This is the behavior required by the standards. Differential Revision: https://reviews.llvm.org/D99480
1 parent 188592f commit 1daa48f

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

compiler-rt/lib/lsan/lsan_allocator.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,18 @@ void Deallocate(void *p) {
123123

124124
void *Reallocate(const StackTrace &stack, void *p, uptr new_size,
125125
uptr alignment) {
126-
RegisterDeallocation(p);
127126
if (new_size > max_malloc_size) {
128-
allocator.Deallocate(GetAllocatorCache(), p);
129-
return ReportAllocationSizeTooBig(new_size, stack);
127+
ReportAllocationSizeTooBig(new_size, stack);
128+
return nullptr;
130129
}
131-
p = allocator.Reallocate(GetAllocatorCache(), p, new_size, alignment);
132-
RegisterAllocation(stack, p, new_size);
133-
return p;
130+
RegisterDeallocation(p);
131+
void *new_p =
132+
allocator.Reallocate(GetAllocatorCache(), p, new_size, alignment);
133+
if (new_p)
134+
RegisterAllocation(stack, new_p, new_size);
135+
else if (new_size != 0)
136+
RegisterAllocation(stack, p, new_size);
137+
return new_p;
134138
}
135139

136140
void GetAllocatorCacheRange(uptr *begin, uptr *end) {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %clang_lsan %s -o %t
2+
// RUN: %env_lsan_opts=allocator_may_return_null=1:max_allocation_size_mb=1:use_stacks=0 not %run %t 2>&1 | FileCheck %s
3+
4+
#include <assert.h>
5+
#include <stdio.h>
6+
#include <stdlib.h>
7+
8+
// CHECK: {{Leak|Address}}Sanitizer failed to allocate 0x100001 bytes
9+
10+
// CHECK: {{Leak|Address}}Sanitizer: detected memory leaks
11+
// CHECK: {{Leak|Address}}Sanitizer: 9 byte(s) leaked in 1 allocation(s).
12+
13+
int main() {
14+
char *p = malloc(9);
15+
fprintf(stderr, "nine: %p\n", p);
16+
assert(realloc(p, 0x100001) == NULL); // 1MiB+1
17+
p = 0;
18+
}

0 commit comments

Comments
 (0)