Skip to content

Commit 544384c

Browse files
ylnJulian Lettner
authored and
Julian Lettner
committed
[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 (cherry picked from commit 5ef4b19)
1 parent 2485c7f commit 544384c

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_malloc_mac.inc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ INTERCEPTOR(malloc_zone_t *, malloc_default_zone, void) {
9191
return &sanitizer_zone;
9292
}
9393

94+
INTERCEPTOR(malloc_zone_t *, malloc_zone_from_ptr, const void *ptr) {
95+
COMMON_MALLOC_ENTER();
96+
size_t size = sanitizer_zone.size(&sanitizer_zone, ptr);
97+
if (size) { // Claimed by sanitizer zone?
98+
return &sanitizer_zone;
99+
}
100+
return REAL(malloc_zone_from_ptr)(ptr);
101+
}
102+
94103
INTERCEPTOR(malloc_zone_t *, malloc_default_purgeable_zone, void) {
95104
// FIXME: ASan should support purgeable allocations.
96105
// https://github.com/google/sanitizers/issues/139
@@ -226,7 +235,7 @@ void __sanitizer_mz_free(malloc_zone_t *zone, void *ptr) {
226235
}
227236

228237
#define GET_ZONE_FOR_PTR(ptr) \
229-
malloc_zone_t *zone_ptr = malloc_zone_from_ptr(ptr); \
238+
malloc_zone_t *zone_ptr = WRAP(malloc_zone_from_ptr)(ptr); \
230239
const char *zone_name = (zone_ptr == 0) ? 0 : zone_ptr->zone_name
231240

232241
extern "C"
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Check that malloc_default_zone and malloc_zone_from_ptr return the
2+
// sanitizer-installed malloc zone even when MallocStackLogging (MSL) is
3+
// requested. This prevents crashes in certain situations. Note that the
4+
// sanitizers and MSL cannot be used together. If both are enabled, MSL
5+
// functionality is essentially deactivated since it only hooks the default
6+
// allocator which is replaced by a custom sanitizer allocator.
7+
//
8+
// MSL=lite creates its own special malloc zone, copies the passed zone name,
9+
// and leaks it.
10+
// RUN: echo "leak:create_and_insert_msl_lite_zone" >> lsan.supp
11+
//
12+
// RUN: %clangxx -g %s -o %t
13+
// RUN: %run %t | FileCheck %s
14+
// RUN: %env MallocStackLogging=lite LSAN_OPTIONS=suppressions=lsan.supp %run %t | FileCheck %s
15+
// RUN: %env MallocStackLogging=full %run %t | FileCheck %s
16+
//
17+
// UBSan does not install a malloc zone.
18+
// XFAIL: ubsan
19+
//
20+
21+
#include <malloc/malloc.h>
22+
#include <stdlib.h>
23+
#include <stdio.h>
24+
25+
int main(void) {
26+
malloc_zone_t *default_zone = malloc_default_zone();
27+
printf("default zone name: %s\n", malloc_get_zone_name(default_zone));
28+
// CHECK: default zone name: {{a|l|t}}san
29+
30+
void *ptr1 = malloc(10);
31+
void *ptr2 = malloc_zone_malloc(default_zone, 10);
32+
33+
malloc_zone_t* zone1 = malloc_zone_from_ptr(ptr1);
34+
malloc_zone_t* zone2 = malloc_zone_from_ptr(ptr2);
35+
36+
printf("zone1: %d\n", zone1 == default_zone);
37+
printf("zone2: %d\n", zone2 == default_zone);
38+
// CHECK: zone1: 1
39+
// CHECK: zone2: 1
40+
41+
free(ptr1);
42+
malloc_zone_free(zone2, ptr2);
43+
44+
return 0;
45+
}

0 commit comments

Comments
 (0)