[compiler-rt] 1daa48f - [lsan] realloc: don't deallocate if requested size is too large

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 29 13:35:17 PDT 2021


Author: Fangrui Song
Date: 2021-03-29T13:35:10-07:00
New Revision: 1daa48f005bd477ba8711ecdf91a1f1515f01383

URL: https://github.com/llvm/llvm-project/commit/1daa48f005bd477ba8711ecdf91a1f1515f01383
DIFF: https://github.com/llvm/llvm-project/commit/1daa48f005bd477ba8711ecdf91a1f1515f01383.diff

LOG: [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

Added: 
    compiler-rt/test/lsan/TestCases/realloc_too_big.c

Modified: 
    compiler-rt/lib/lsan/lsan_allocator.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/lsan/lsan_allocator.cpp b/compiler-rt/lib/lsan/lsan_allocator.cpp
index 70422957e6f3..91e34ebb3214 100644
--- a/compiler-rt/lib/lsan/lsan_allocator.cpp
+++ b/compiler-rt/lib/lsan/lsan_allocator.cpp
@@ -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) {

diff  --git a/compiler-rt/test/lsan/TestCases/realloc_too_big.c b/compiler-rt/test/lsan/TestCases/realloc_too_big.c
new file mode 100644
index 000000000000..e4d2431a3dfa
--- /dev/null
+++ b/compiler-rt/test/lsan/TestCases/realloc_too_big.c
@@ -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;
+}


        


More information about the llvm-commits mailing list