Add allocator_frees_and_returns_null_on_realloc_zero=false flag for compatibility...
authorFilipe Cabecinhas <me@filcab.net>
Wed, 29 Mar 2017 18:17:22 +0000 (18:17 +0000)
committerFilipe Cabecinhas <me@filcab.net>
Wed, 29 Mar 2017 18:17:22 +0000 (18:17 +0000)
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

compiler-rt/lib/asan/asan_allocator.cc
compiler-rt/lib/asan/asan_flags.inc
compiler-rt/test/asan/TestCases/realloc.cc [new file with mode: 0644]

index 4be1f1c..6db2b4d 100644 (file)
@@ -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);
 }
index 4712efb..f316afd 100644 (file)
@@ -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 (file)
index 0000000..fcf383b
--- /dev/null
@@ -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);
+}