[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
This commit is contained in:
Fangrui Song 2021-03-29 13:35:10 -07:00
parent 188592ff08
commit 1daa48f005
2 changed files with 28 additions and 6 deletions

View File

@ -123,14 +123,18 @@ void Deallocate(void *p) {
void *Reallocate(const StackTrace &stack, void *p, uptr new_size,
uptr alignment) {
RegisterDeallocation(p);
if (new_size > max_malloc_size) {
allocator.Deallocate(GetAllocatorCache(), p);
return ReportAllocationSizeTooBig(new_size, stack);
ReportAllocationSizeTooBig(new_size, stack);
return nullptr;
}
p = allocator.Reallocate(GetAllocatorCache(), p, new_size, alignment);
RegisterAllocation(stack, p, new_size);
return p;
RegisterDeallocation(p);
void *new_p =
allocator.Reallocate(GetAllocatorCache(), p, new_size, alignment);
if (new_p)
RegisterAllocation(stack, new_p, new_size);
else if (new_size != 0)
RegisterAllocation(stack, p, new_size);
return new_p;
}
void GetAllocatorCacheRange(uptr *begin, uptr *end) {

View File

@ -0,0 +1,18 @@
// RUN: %clang_lsan %s -o %t
// RUN: %env_lsan_opts=allocator_may_return_null=1:max_allocation_size_mb=1:use_stacks=0 not %run %t 2>&1 | FileCheck %s
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
// CHECK: {{Leak|Address}}Sanitizer failed to allocate 0x100001 bytes
// CHECK: {{Leak|Address}}Sanitizer: detected memory leaks
// CHECK: {{Leak|Address}}Sanitizer: 9 byte(s) leaked in 1 allocation(s).
int main() {
char *p = malloc(9);
fprintf(stderr, "nine: %p\n", p);
assert(realloc(p, 0x100001) == NULL); // 1MiB+1
p = 0;
}