[compiler-rt] r368492 - [Sanitizer][Darwin] Add interceptor for malloc_zone_from_ptr

Julian Lettner via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 9 14:46:32 PDT 2019


Author: yln
Date: Fri Aug  9 14:46:32 2019
New Revision: 368492

URL: http://llvm.org/viewvc/llvm-project?rev=368492&view=rev
Log:
[Sanitizer][Darwin] Add interceptor for malloc_zone_from_ptr

Ensure that malloc_default_zone and malloc_zone_from_ptr return the
sanitizer-installed malloc zone even when MallocStackLogging (MSL) is
requested. This prevents crashes in certain situations. Note that the
sanitizers and MSL cannot be used together. If both are enabled, MSL
functionality is essentially deactivated since it only hooks the default
allocator which is replaced by a custom sanitizer allocator.

rdar://53686175

Reviewed By: kubamracek

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

Added:
    compiler-rt/trunk/test/sanitizer_common/TestCases/Darwin/malloc_zone.cpp
Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_malloc_mac.inc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_malloc_mac.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_malloc_mac.inc?rev=368492&r1=368491&r2=368492&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_malloc_mac.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_malloc_mac.inc Fri Aug  9 14:46:32 2019
@@ -91,6 +91,15 @@ INTERCEPTOR(malloc_zone_t *, malloc_defa
   return &sanitizer_zone;
 }
 
+INTERCEPTOR(malloc_zone_t *, malloc_zone_from_ptr, const void *ptr) {
+  COMMON_MALLOC_ENTER();
+  size_t size = sanitizer_zone.size(&sanitizer_zone, ptr);
+  if (size) { // Claimed by sanitizer zone?
+    return &sanitizer_zone;
+  }
+  return REAL(malloc_zone_from_ptr)(ptr);
+}
+
 INTERCEPTOR(malloc_zone_t *, malloc_default_purgeable_zone, void) {
   // FIXME: ASan should support purgeable allocations.
   // https://github.com/google/sanitizers/issues/139
@@ -226,7 +235,7 @@ void __sanitizer_mz_free(malloc_zone_t *
 }
 
 #define GET_ZONE_FOR_PTR(ptr) \
-  malloc_zone_t *zone_ptr = malloc_zone_from_ptr(ptr); \
+  malloc_zone_t *zone_ptr = WRAP(malloc_zone_from_ptr)(ptr); \
   const char *zone_name = (zone_ptr == 0) ? 0 : zone_ptr->zone_name
 
 extern "C"

Added: compiler-rt/trunk/test/sanitizer_common/TestCases/Darwin/malloc_zone.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/Darwin/malloc_zone.cpp?rev=368492&view=auto
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/Darwin/malloc_zone.cpp (added)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/Darwin/malloc_zone.cpp Fri Aug  9 14:46:32 2019
@@ -0,0 +1,45 @@
+// Check that malloc_default_zone and malloc_zone_from_ptr return the
+// sanitizer-installed malloc zone even when MallocStackLogging (MSL) is
+// requested. This prevents crashes in certain situations. Note that the
+// sanitizers and MSL cannot be used together. If both are enabled, MSL
+// functionality is essentially deactivated since it only hooks the default
+// allocator which is replaced by a custom sanitizer allocator.
+//
+// MSL=lite creates its own special malloc zone, copies the passed zone name,
+// and leaks it.
+// RUN: echo "leak:create_and_insert_msl_lite_zone" >> lsan.supp
+//
+// RUN: %clangxx -g %s -o %t
+// RUN:                                                                   %run %t | FileCheck %s
+// RUN: %env MallocStackLogging=lite LSAN_OPTIONS=suppressions=lsan.supp  %run %t | FileCheck %s
+// RUN: %env MallocStackLogging=full                                      %run %t | FileCheck %s
+//
+// UBSan does not install a malloc zone.
+// XFAIL: ubsan
+//
+
+#include <malloc/malloc.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(void) {
+  malloc_zone_t *default_zone = malloc_default_zone();
+  printf("default zone name: %s\n", malloc_get_zone_name(default_zone));
+// CHECK: default zone name: {{a|l|t}}san
+
+  void *ptr1 = malloc(10);
+  void *ptr2 = malloc_zone_malloc(default_zone, 10);
+
+  malloc_zone_t* zone1 = malloc_zone_from_ptr(ptr1);
+  malloc_zone_t* zone2 = malloc_zone_from_ptr(ptr2);
+
+  printf("zone1: %d\n", zone1 == default_zone);
+  printf("zone2: %d\n", zone2 == default_zone);
+// CHECK: zone1: 1
+// CHECK: zone2: 1
+
+  free(ptr1);
+  malloc_zone_free(zone2, ptr2);
+
+  return 0;
+}




More information about the llvm-commits mailing list