[compiler-rt] r295730 - [compiler-rt][asan] Add support for desallocation of unhandled pointers

Etienne Bergeron via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 21 08:09:39 PST 2017


Author: etienneb
Date: Tue Feb 21 10:09:38 2017
New Revision: 295730

URL: http://llvm.org/viewvc/llvm-project?rev=295730&view=rev
Log:
[compiler-rt][asan] Add support for desallocation of unhandled pointers

Summary: On windows 10, the ucrt DLL is performing allocations before the function hooking and there are multiple allocations not handled by Asan. When a free occur at the end of the process, asan is reporting desallocations not malloc-ed.

Reviewers: rnk, kcc

Reviewed By: rnk, kcc

Subscribers: kcc, llvm-commits, kubamracek, chrisha, dberris

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

Added:
    compiler-rt/trunk/test/asan/TestCases/Windows/dll_heap_allocation.cc
Modified:
    compiler-rt/trunk/lib/asan/asan_allocator.cc
    compiler-rt/trunk/lib/asan/asan_internal.h
    compiler-rt/trunk/lib/asan/asan_linux.cc
    compiler-rt/trunk/lib/asan/asan_mac.cc
    compiler-rt/trunk/lib/asan/asan_win.cc
    compiler-rt/trunk/test/asan/lit.cfg

Modified: compiler-rt/trunk/lib/asan/asan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator.cc?rev=295730&r1=295729&r2=295730&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator.cc Tue Feb 21 10:09:38 2017
@@ -554,7 +554,17 @@ struct Allocator {
     uptr chunk_beg = p - kChunkHeaderSize;
     AsanChunk *m = reinterpret_cast<AsanChunk *>(chunk_beg);
 
+    // On Windows, uninstrumented DLLs may allocate memory before ASan hooks
+    // malloc. Don't report an invalid free in this case.
+    if (SANITIZER_WINDOWS &&
+        !get_allocator().PointerIsMine(ptr)) {
+      if (!IsSystemHeapAddress(p))
+        ReportFreeNotMalloced(p, stack);
+      return;
+    }
+
     ASAN_FREE_HOOK(ptr);
+
     // Must mark the chunk as quarantined before any changes to its metadata.
     // Do not quarantine given chunk if we failed to set CHUNK_QUARANTINE flag.
     if (!AtomicallySetQuarantineFlagIfAllocated(m, ptr, stack)) return;

Modified: compiler-rt/trunk/lib/asan/asan_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=295730&r1=295729&r2=295730&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_internal.h Tue Feb 21 10:09:38 2017
@@ -64,6 +64,9 @@ void AsanInitFromRtl();
 
 // asan_win.cc
 void InitializePlatformExceptionHandlers();
+// Returns whether an address is a valid allocated system heap block.
+// 'addr' must point to the beginning of the block.
+bool IsSystemHeapAddress(uptr addr);
 
 // asan_rtl.cc
 void NORETURN ShowStatsAndAbort();

Modified: compiler-rt/trunk/lib/asan/asan_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_linux.cc?rev=295730&r1=295729&r2=295730&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_linux.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_linux.cc Tue Feb 21 10:09:38 2017
@@ -70,6 +70,7 @@ namespace __asan {
 
 void InitializePlatformInterceptors() {}
 void InitializePlatformExceptionHandlers() {}
+bool IsSystemHeapAddress (uptr addr) { return false; }
 
 void *AsanDoesNotSupportStaticLinkage() {
   // This will fail to link with -static.

Modified: compiler-rt/trunk/lib/asan/asan_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.cc?rev=295730&r1=295729&r2=295730&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_mac.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_mac.cc Tue Feb 21 10:09:38 2017
@@ -48,6 +48,7 @@ namespace __asan {
 
 void InitializePlatformInterceptors() {}
 void InitializePlatformExceptionHandlers() {}
+bool IsSystemHeapAddress (uptr addr) { return false; }
 
 // No-op. Mac does not support static linkage anyway.
 void *AsanDoesNotSupportStaticLinkage() {

Modified: compiler-rt/trunk/lib/asan/asan_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win.cc?rev=295730&r1=295729&r2=295730&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win.cc Tue Feb 21 10:09:38 2017
@@ -277,6 +277,10 @@ void InitializePlatformExceptionHandlers
 #endif
 }
 
+bool IsSystemHeapAddress(uptr addr) {
+  return ::HeapValidate(GetProcessHeap(), 0, (void*)addr) != FALSE;
+}
+
 // We want to install our own exception handler (EH) to print helpful reports
 // on access violations and whatnot.  Unfortunately, the CRT initializers assume
 // they are run before any user code and drop any previously-installed EHs on

Added: compiler-rt/trunk/test/asan/TestCases/Windows/dll_heap_allocation.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Windows/dll_heap_allocation.cc?rev=295730&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Windows/dll_heap_allocation.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Windows/dll_heap_allocation.cc Tue Feb 21 10:09:38 2017
@@ -0,0 +1,30 @@
+
+// RUN: %clang_cl -LD %s -Fe%t.dll -DHEAP_LIBRARY -MD
+// RUN: %clang_cl %s %t.lib -Fe%t -fsanitize=address -MT
+// RUN: %run %t 2>&1 | FileCheck %s
+
+// Check that ASan does not fail when releasing allocations that occurred within
+// an uninstrumented DLL.
+
+#ifdef HEAP_LIBRARY
+#include <memory>
+#include <windows.h>
+
+std::unique_ptr<int> __declspec(dllexport) myglobal(new int(42));
+BOOL WINAPI DllMain(PVOID h, DWORD reason, PVOID reserved) {
+  return TRUE;
+}
+
+#else
+
+#include <memory>
+extern std::unique_ptr<int> __declspec(dllimport) myglobal;
+int main(int argc, char **argv) {
+  printf("myglobal: %d\n", *myglobal);
+  return 0;
+}
+
+#endif
+
+// CHECK: myglobal: 42
+// CHECK-NOT: ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed

Modified: compiler-rt/trunk/test/asan/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/lit.cfg?rev=295730&r1=295729&r2=295730&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/lit.cfg (original)
+++ compiler-rt/trunk/test/asan/lit.cfg Tue Feb 21 10:09:38 2017
@@ -132,16 +132,22 @@ if config.asan_dynamic:
 
 # Windows-specific tests might also use the clang-cl.exe driver.
 if platform.system() == 'Windows':
-  clang_cl_asan_cxxflags = ["-fsanitize=address",
-                            "-Wno-deprecated-declarations",
-                            "-WX",
-                            "-D_HAS_EXCEPTIONS=0",
-                            "-Zi"] + target_cflags
+  clang_cl_cxxflags = ["-Wno-deprecated-declarations",
+                       "-WX",
+                       "-D_HAS_EXCEPTIONS=0",
+                       "-Zi"] + target_cflags
+  clang_cl_asan_cxxflags = ["-fsanitize=address"] + clang_cl_cxxflags
   if config.asan_dynamic:
     clang_cl_asan_cxxflags.append("-MD")
-  clang_invocation = build_invocation(clang_cl_asan_cxxflags)
-  clang_cl_invocation = clang_invocation.replace("clang.exe","clang-cl.exe")
-  config.substitutions.append( ("%clang_cl_asan ", clang_cl_invocation) )
+
+  clang_cl_invocation = build_invocation(clang_cl_cxxflags)
+  clang_cl_invocation = clang_cl_invocation.replace("clang.exe","clang-cl.exe")
+  config.substitutions.append( ("%clang_cl ", clang_cl_invocation) )
+
+  clang_cl_asan_invocation = build_invocation(clang_cl_asan_cxxflags)
+  clang_cl_asan_invocation = clang_cl_asan_invocation.replace("clang.exe","clang-cl.exe")
+  config.substitutions.append( ("%clang_cl_asan ", clang_cl_asan_invocation) )
+
   base_lib = os.path.join(config.compiler_rt_libdir, "clang_rt.asan%%s-%s.lib" % config.target_arch)
   config.substitutions.append( ("%asan_lib", base_lib % "") )
   config.substitutions.append( ("%asan_cxx_lib", base_lib % "_cxx") )




More information about the llvm-commits mailing list