[compiler-rt] r272943 - [sanitizers] introduce yet another API function: __sanitizer_install_malloc_and_free_hooks

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 16 13:06:08 PDT 2016


Author: kcc
Date: Thu Jun 16 15:06:06 2016
New Revision: 272943

URL: http://llvm.org/viewvc/llvm-project?rev=272943&view=rev
Log:
[sanitizers] introduce yet another API function: __sanitizer_install_malloc_and_free_hooks

Modified:
    compiler-rt/trunk/include/sanitizer/allocator_interface.h
    compiler-rt/trunk/lib/asan/asan_internal.h
    compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc
    compiler-rt/trunk/lib/lsan/lsan_allocator.cc
    compiler-rt/trunk/lib/msan/msan.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_interface.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc
    compiler-rt/trunk/test/sanitizer_common/TestCases/malloc_hook.cc

Modified: compiler-rt/trunk/include/sanitizer/allocator_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/allocator_interface.h?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/allocator_interface.h (original)
+++ compiler-rt/trunk/include/sanitizer/allocator_interface.h Thu Jun 16 15:06:06 2016
@@ -59,6 +59,23 @@ extern "C" {
        deallocation of "ptr". */
   void __sanitizer_malloc_hook(const volatile void *ptr, size_t size);
   void __sanitizer_free_hook(const volatile void *ptr);
+
+  /* Installs a pair of hooks for malloc/free.
+     Several (currently, 5) hook pairs may be installed, they are executed
+     in the order they were installed and after calling
+     __sanitizer_malloc_hook/__sanitizer_free_hook.
+     Unlike __sanitizer_malloc_hook/__sanitizer_free_hook these hooks can be
+     chained and do not rely on weak symbols working on the platform, but
+     require __sanitizer_install_malloc_and_free_hooks to be called at startup
+     and thus will not be called on malloc/free very early in the process.
+     Returns the number of hooks currently installed or 0 on failure.
+     Not thread-safe, should be called in the main thread before starting
+     other threads.
+  */
+  int __sanitizer_install_malloc_and_free_hooks(
+      void (*malloc_hook)(const volatile void *, size_t),
+      void (*free_hook)(const volatile void *));
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif

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=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_internal.h Thu Jun 16 15:06:06 2016
@@ -110,10 +110,16 @@ bool PlatformHasDifferentMemcpyAndMemmov
 
 // Add convenient macro for interface functions that may be represented as
 // weak hooks.
-#define ASAN_MALLOC_HOOK(ptr, size) \
-  if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(ptr, size)
-#define ASAN_FREE_HOOK(ptr) \
-  if (&__sanitizer_free_hook) __sanitizer_free_hook(ptr)
+#define ASAN_MALLOC_HOOK(ptr, size)                                   \
+  do {                                                                \
+    if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(ptr, size); \
+    RunMallocHooks(ptr, size);                                        \
+  } while (false)
+#define ASAN_FREE_HOOK(ptr)                                 \
+  do {                                                      \
+    if (&__sanitizer_free_hook) __sanitizer_free_hook(ptr); \
+    RunFreeHooks(ptr);                                      \
+  } while (false)
 #define ASAN_ON_ERROR() \
   if (&__asan_on_error) __asan_on_error()
 

Modified: compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc Thu Jun 16 15:06:06 2016
@@ -343,6 +343,7 @@ INTERFACE_FUNCTION(__sanitizer_unaligned
 INTERFACE_FUNCTION(__sanitizer_unaligned_store32)
 INTERFACE_FUNCTION(__sanitizer_unaligned_store64)
 INTERFACE_FUNCTION(__sanitizer_verify_contiguous_container)
+INTERFACE_FUNCTION(__sanitizer_install_malloc_and_free_hooks)
 
 // TODO(timurrrr): Add more interface functions on the as-needed basis.
 

Modified: compiler-rt/trunk/lib/lsan/lsan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_allocator.cc?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_allocator.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan_allocator.cc Thu Jun 16 15:06:06 2016
@@ -99,11 +99,13 @@ void *Allocate(const StackTrace &stack,
     memset(p, 0, size);
   RegisterAllocation(stack, p, size);
   if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(p, size);
+  RunMallocHooks(p, size);
   return p;
 }
 
 void Deallocate(void *p) {
   if (&__sanitizer_free_hook) __sanitizer_free_hook(p);
+  RunFreeHooks(p);
   RegisterDeallocation(p);
   allocator.Deallocate(&cache, p);
 }

Modified: compiler-rt/trunk/lib/msan/msan.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.h?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.h (original)
+++ compiler-rt/trunk/lib/msan/msan.h Thu Jun 16 15:06:06 2016
@@ -309,15 +309,21 @@ void MsanTSDDtor(void *tsd);
 
 }  // namespace __msan
 
-#define MSAN_MALLOC_HOOK(ptr, size)     \
-  if (&__sanitizer_malloc_hook) {       \
-    UnpoisonParam(2);                   \
-    __sanitizer_malloc_hook(ptr, size); \
-  }
-#define MSAN_FREE_HOOK(ptr)     \
-  if (&__sanitizer_free_hook) { \
-    UnpoisonParam(1);           \
-    __sanitizer_free_hook(ptr); \
-  }
+#define MSAN_MALLOC_HOOK(ptr, size)       \
+  do {                                    \
+    if (&__sanitizer_malloc_hook) {       \
+      UnpoisonParam(2);                   \
+      __sanitizer_malloc_hook(ptr, size); \
+    }                                     \
+    RunMallocHooks(ptr, size);            \
+  } while (false)
+#define MSAN_FREE_HOOK(ptr)       \
+  do {                            \
+    if (&__sanitizer_free_hook) { \
+      UnpoisonParam(1);           \
+      __sanitizer_free_hook(ptr); \
+    }                             \
+    RunFreeHooks(ptr);            \
+  } while (false)
 
 #endif  // MSAN_H

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_interface.h?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_interface.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_interface.h Thu Jun 16 15:06:06 2016
@@ -29,6 +29,10 @@ SANITIZER_INTERFACE_ATTRIBUTE uptr __san
 SANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_free_bytes();
 SANITIZER_INTERFACE_ATTRIBUTE uptr __sanitizer_get_unmapped_bytes();
 
+SANITIZER_INTERFACE_ATTRIBUTE int __sanitizer_install_malloc_and_free_hooks(
+    void (*malloc_hook)(const void *, uptr),
+    void (*free_hook)(const void *));
+
 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
     /* OPTIONAL */ void __sanitizer_malloc_hook(void *ptr, uptr size);
 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc Thu Jun 16 15:06:06 2016
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "sanitizer_common.h"
+#include "sanitizer_allocator_interface.h"
 #include "sanitizer_allocator_internal.h"
 #include "sanitizer_flags.h"
 #include "sanitizer_libc.h"
@@ -421,6 +422,44 @@ void PrintCmdline() {
   Printf("\n\n");
 }
 
+// Malloc hooks.
+static const int kMaxMallocFreeHooks = 5;
+struct MallocFreeHook {
+  void (*malloc_hook)(const void *, uptr);
+  void (*free_hook)(const void *);
+};
+
+static MallocFreeHook MFHooks[kMaxMallocFreeHooks];
+
+void RunMallocHooks(const void *ptr, uptr size) {
+  for (int i = 0; i < kMaxMallocFreeHooks; i++) {
+    auto hook = MFHooks[i].malloc_hook;
+    if (!hook) return;
+    hook(ptr, size);
+  }
+}
+
+void RunFreeHooks(const void *ptr) {
+  for (int i = 0; i < kMaxMallocFreeHooks; i++) {
+    auto hook = MFHooks[i].free_hook;
+    if (!hook) return;
+    hook(ptr);
+  }
+}
+
+static int InstallMallocFreeHooks(void (*malloc_hook)(const void *, uptr),
+                                  void (*free_hook)(const void *)) {
+  if (!malloc_hook || !free_hook) return 0;
+  for (int i = 0; i < kMaxMallocFreeHooks; i++) {
+    if (MFHooks[i].malloc_hook == nullptr) {
+      MFHooks[i].malloc_hook = malloc_hook;
+      MFHooks[i].free_hook = free_hook;
+      return i + 1;
+    }
+  }
+  return 0;
+}
+
 } // namespace __sanitizer
 
 using namespace __sanitizer;  // NOLINT
@@ -443,4 +482,11 @@ SANITIZER_INTERFACE_ATTRIBUTE
 void __sanitizer_set_death_callback(void (*callback)(void)) {
   SetUserDieCallback(callback);
 }
+
+SANITIZER_INTERFACE_ATTRIBUTE
+int __sanitizer_install_malloc_and_free_hooks(void (*malloc_hook)(const void *,
+                                                                  uptr),
+                                              void (*free_hook)(const void *)) {
+  return InstallMallocFreeHooks(malloc_hook, free_hook);
+}
 } // extern "C"

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Thu Jun 16 15:06:06 2016
@@ -103,6 +103,8 @@ void NoHugePagesInRegion(uptr addr, uptr
 void DontDumpShadowMemory(uptr addr, uptr length);
 // Check if the built VMA size matches the runtime one.
 void CheckVMASize();
+void RunMallocHooks(const void *ptr, uptr size);
+void RunFreeHooks(const void *ptr);
 
 // InternalScopedBuffer can be used instead of large stack arrays to
 // keep frame size low.

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc Thu Jun 16 15:06:06 2016
@@ -228,6 +228,7 @@ void invoke_malloc_hook(void *ptr, uptr
   if (ctx == 0 || !ctx->initialized || thr->ignore_interceptors)
     return;
   __sanitizer_malloc_hook(ptr, size);
+  RunMallocHooks(ptr, size);
 }
 
 void invoke_free_hook(void *ptr) {
@@ -235,6 +236,7 @@ void invoke_free_hook(void *ptr) {
   if (ctx == 0 || !ctx->initialized || thr->ignore_interceptors)
     return;
   __sanitizer_free_hook(ptr);
+  RunFreeHooks(ptr);
 }
 
 void *internal_alloc(MBlockType typ, uptr sz) {

Modified: compiler-rt/trunk/test/sanitizer_common/TestCases/malloc_hook.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/malloc_hook.cc?rev=272943&r1=272942&r2=272943&view=diff
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/malloc_hook.cc (original)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/malloc_hook.cc Thu Jun 16 15:06:06 2016
@@ -10,22 +10,28 @@
 extern "C" {
 const volatile void *global_ptr;
 
+#define WRITE(s) write(1, s, sizeof(s))
+
 // Note: avoid calling functions that allocate memory in malloc/free
 // to avoid infinite recursion.
 void __sanitizer_malloc_hook(const volatile void *ptr, size_t sz) {
   if (__sanitizer_get_ownership(ptr) && sz == 4) {
-    write(1, "MallocHook\n", sizeof("MallocHook\n"));
+    WRITE("MallocHook\n");
     global_ptr = ptr;
   }
 }
 void __sanitizer_free_hook(const volatile void *ptr) {
   if (__sanitizer_get_ownership(ptr) && ptr == global_ptr)
-    write(1, "FreeHook\n", sizeof("FreeHook\n"));
+    WRITE("FreeHook\n");
 }
 }  // extern "C"
 
 volatile int *x;
 
+void MallocHook1(const volatile void *ptr, size_t sz) { WRITE("MH1\n"); }
+void MallocHook2(const volatile void *ptr, size_t sz) { WRITE("MH2\n"); }
+void FreeHook1(const volatile void *ptr) { WRITE("FH1\n"); }
+void FreeHook2(const volatile void *ptr) { WRITE("FH2\n"); }
 // Call this function with uninitialized arguments to poison
 // TLS shadow for function parameters before calling operator
 // new and, eventually, user-provided hook.
@@ -34,9 +40,13 @@ __attribute__((noinline)) void allocate(
 }
 
 int main() {
+  __sanitizer_install_malloc_and_free_hooks(MallocHook1, FreeHook1);
+  __sanitizer_install_malloc_and_free_hooks(MallocHook2, FreeHook2);
   int *undef1, *undef2;
   allocate(undef1, undef2);
   // CHECK: MallocHook
+  // CHECK: MH1
+  // CHECK: MH2
   // Check that malloc hook was called with correct argument.
   if (global_ptr != (void*)x) {
     _exit(1);
@@ -44,5 +54,7 @@ int main() {
   *x = 0;
   delete x;
   // CHECK: FreeHook
+  // CHECK: FH1
+  // CHECK: FH2
   return 0;
 }




More information about the llvm-commits mailing list