From: Julian Lettner Date: Fri, 9 Aug 2019 21:46:32 +0000 (+0000) Subject: [Sanitizer][Darwin] Add interceptor for malloc_zone_from_ptr X-Git-Tag: llvmorg-11-init~12217 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5ef4b190d9910fa6bfbd7406ea6629b53e4e8d79;p=platform%2Fupstream%2Fllvm.git [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 llvm-svn: 368492 --- diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc b/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc index 3f3581e..11adbe5 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc @@ -91,6 +91,15 @@ INTERCEPTOR(malloc_zone_t *, malloc_default_zone, void) { 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 *zone, void *ptr) { } #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" diff --git a/compiler-rt/test/sanitizer_common/TestCases/Darwin/malloc_zone.cpp b/compiler-rt/test/sanitizer_common/TestCases/Darwin/malloc_zone.cpp new file mode 100644 index 0000000..fd6ef03 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Darwin/malloc_zone.cpp @@ -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 +#include +#include + +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; +}