[compiler-rt] 9d01612 - [Asan] Fix false leak report

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 14 13:32:51 PDT 2020


Author: Vitaly Buka
Date: 2020-09-14T13:32:41-07:00
New Revision: 9d01612db48fa27d18c6320974b8d711572e5c67

URL: https://github.com/llvm/llvm-project/commit/9d01612db48fa27d18c6320974b8d711572e5c67
DIFF: https://github.com/llvm/llvm-project/commit/9d01612db48fa27d18c6320974b8d711572e5c67.diff

LOG: [Asan] Fix false leak report

If user thread is in the allocator, the allocator
may have no pointer into future user's part of
the allocated block. AddrIsInside ignores such
pointers and lsan reports a false memory leak.

Reviewed By: morehouse

Differential Revision: https://reviews.llvm.org/D87552

Added: 
    compiler-rt/test/asan/TestCases/redzone_noleak.cpp

Modified: 
    compiler-rt/lib/asan/asan_allocator.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/asan/asan_allocator.cpp b/compiler-rt/lib/asan/asan_allocator.cpp
index 8cc7de3a9862..e4028dc10f48 100644
--- a/compiler-rt/lib/asan/asan_allocator.cpp
+++ b/compiler-rt/lib/asan/asan_allocator.cpp
@@ -1111,19 +1111,17 @@ void GetAllocatorGlobalRange(uptr *begin, uptr *end) {
   *end = *begin + sizeof(__asan::get_allocator());
 }
 
-uptr PointsIntoChunk(void* p) {
+uptr PointsIntoChunk(void *p) {
   uptr addr = reinterpret_cast<uptr>(p);
   __asan::AsanChunk *m = __asan::instance.GetAsanChunkByAddrFastLocked(addr);
   if (!m || atomic_load(&m->chunk_state, memory_order_acquire) !=
                 __asan::CHUNK_ALLOCATED)
     return 0;
-  uptr chunk = m->Beg();
-  if (m->AddrIsInside(addr, /*locked_version=*/true))
-    return chunk;
-  if (IsSpecialCaseOfOperatorNew0(chunk, m->UsedSize(/*locked_version*/ true),
-                                  addr))
-    return chunk;
-  return 0;
+  // AsanChunk presence means that we point into some block from underlying
+  // allocators. Don't check whether p points into user memory, since until
+  // the return from AsanAllocator::Allocator we may have no such
+  // pointer anywhere. But we must already have a pointer to GetBlockBegin().
+  return m->Beg();
 }
 
 uptr GetUserBegin(uptr chunk) {

diff  --git a/compiler-rt/test/asan/TestCases/redzone_noleak.cpp b/compiler-rt/test/asan/TestCases/redzone_noleak.cpp
new file mode 100644
index 000000000000..f122c05e5108
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/redzone_noleak.cpp
@@ -0,0 +1,28 @@
+// Test whether pointers into left redzone count memory are reachable.
+// If user thread is inside asan allocator code then we may have no
+// pointers into user part of memory yet. However we should have a pointer
+// into the allocated memory chunk.
+//
+// RUN: %clangxx_asan  %s -o %t
+// RUN: %run %t 2>&1
+
+#include <cstdlib>
+#include <stdio.h>
+#include <thread>
+
+void *pointers[1000];
+void **cur = pointers;
+
+void leak(int n, int offset) {
+  printf("%d %d\n", n, offset);
+  for (int i = 0; i < 3; ++i)
+    *(cur++) = (new int[n]) + offset;
+}
+
+int main(int argc, char **argv) {
+  for (int n = 1; n < 10000000; n = n * 2) {
+    leak(n, 0);
+    leak(n, -1);
+  }
+  return 0;
+}


        


More information about the llvm-commits mailing list