summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFilipe Cabecinhas <me@filcab.net>2017-03-29 18:17:22 +0000
committerFilipe Cabecinhas <me@filcab.net>2017-03-29 18:17:22 +0000
commite144b723727f4264cc0a22656191156cf1b8edb1 (patch)
tree9208c90b3b7cf79dda87f1232296178400f1349e
parent762f928a7a64133a1c5dab73d469440bb2e21b26 (diff)
downloadbcm5719-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.cc8
-rw-r--r--compiler-rt/lib/asan/asan_flags.inc4
-rw-r--r--compiler-rt/test/asan/TestCases/realloc.cc21
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);
+}
OpenPOWER on IntegriCloud