diff options
author | Filipe Cabecinhas <me@filcab.net> | 2017-03-29 18:17:22 +0000 |
---|---|---|
committer | Filipe Cabecinhas <me@filcab.net> | 2017-03-29 18:17:22 +0000 |
commit | e144b723727f4264cc0a22656191156cf1b8edb1 (patch) | |
tree | 9208c90b3b7cf79dda87f1232296178400f1349e | |
parent | 762f928a7a64133a1c5dab73d469440bb2e21b26 (diff) | |
download | bcm5719-llvm-e144b723727f4264cc0a22656191156cf1b8edb1.tar.gz bcm5719-llvm-e144b723727f4264cc0a22656191156cf1b8edb1.zip |
Add allocator_frees_and_returns_null_on_realloc_zero=false flag for compatibility with allocators which allow a realloc(p, 0) and don't free the pointer.
Summary:
I know of two implementations that do this (ASan is not protecting against accessing the returned memory for now, just like malloc(0)):
SIE libc on the PS4
dlmalloc has a flag for this
This allows us to properly support this behaviour.
Reviewers: vsk, kcc
Subscribers: llvm-commits, kubamracek
Differential Revision: https://reviews.llvm.org/D31295
llvm-svn: 299016
-rw-r--r-- | compiler-rt/lib/asan/asan_allocator.cc | 8 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_flags.inc | 4 | ||||
-rw-r--r-- | compiler-rt/test/asan/TestCases/realloc.cc | 21 |
3 files changed, 31 insertions, 2 deletions
diff --git a/compiler-rt/lib/asan/asan_allocator.cc b/compiler-rt/lib/asan/asan_allocator.cc index 4be1f1ce2fa..6db2b4db533 100644 --- a/compiler-rt/lib/asan/asan_allocator.cc +++ b/compiler-rt/lib/asan/asan_allocator.cc @@ -800,8 +800,12 @@ void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack) { if (!p) return instance.Allocate(size, 8, stack, FROM_MALLOC, true); if (size == 0) { - instance.Deallocate(p, 0, stack, FROM_MALLOC); - return nullptr; + if (flags()->allocator_frees_and_returns_null_on_realloc_zero) { + instance.Deallocate(p, 0, stack, FROM_MALLOC); + return nullptr; + } + // Allocate a size of 1 if we shouldn't free() on Realloc to 0 + size = 1; } return instance.Reallocate(p, size, stack); } diff --git a/compiler-rt/lib/asan/asan_flags.inc b/compiler-rt/lib/asan/asan_flags.inc index 4712efb8622..f316afdb31a 100644 --- a/compiler-rt/lib/asan/asan_flags.inc +++ b/compiler-rt/lib/asan/asan_flags.inc @@ -148,3 +148,7 @@ ASAN_FLAG(bool, halt_on_error, true, "(WARNING: USE AT YOUR OWN RISK!)") ASAN_FLAG(bool, use_odr_indicator, false, "Use special ODR indicator symbol for ODR violation detection") +ASAN_FLAG(bool, allocator_frees_and_returns_null_on_realloc_zero, true, + "realloc(p, 0) is equivalent to free(p) by default (Same as the " + "POSIX standard). If set to false, realloc(p, 0) will return a " + "pointer to an allocated space which can not be used.") diff --git a/compiler-rt/test/asan/TestCases/realloc.cc b/compiler-rt/test/asan/TestCases/realloc.cc new file mode 100644 index 00000000000..fcf383b1a73 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/realloc.cc @@ -0,0 +1,21 @@ +// RUN: %clangxx_asan -O0 %s -o %t +// Default is true (free on realloc to 0 size) +// RUN: %run %t 2>&1 | FileCheck %s +// RUN: %env_asan_opts=allocator_frees_and_returns_null_on_realloc_zero=true %run %t 2>&1 | FileCheck %s +// RUN: %env_asan_opts=allocator_frees_and_returns_null_on_realloc_zero=false %run %t 2>&1 | FileCheck %s --check-prefix=NO-FREE + +#include <stdio.h> +#include <stdlib.h> + +int main() { + void *p = malloc(42); + p = realloc(p, 0); + if (p) { + // NO-FREE: Allocated something on realloc(p, 0) + fprintf(stderr, "Allocated something on realloc(p, 0)\n"); + } else { + // CHECK: realloc(p, 0) returned nullptr + fprintf(stderr, "realloc(p, 0) returned nullptr\n"); + } + free(p); +} |