Skip to content

Commit 47e0ef3

Browse files
committedJan 27, 2017
Stop intercepting some malloc-related functions on FreeBSD and macOS
Summary: In https://bugs.freebsd.org/215125 I was notified that some configure scripts attempt to test for the Linux-specific `mallinfo` and `mallopt` functions by compiling and linking small programs which references the functions, and observing whether that results in errors. FreeBSD and macOS do not have the `mallinfo` and `mallopt` functions, so normally these tests would fail, but when sanitizers are enabled, they incorrectly succeed, because the sanitizers define interceptors for these functions. This also applies to some other malloc-related functions, such as `memalign`, `pvalloc` and `cfree`. Fix this by not intercepting `mallinfo`, `mallopt`, `memalign`, `pvalloc` and `cfree` for FreeBSD and macOS, in all sanitizers. Reviewers: emaste, kcc Subscribers: hans, joerg, llvm-commits, kubamracek Differential Revision: https://reviews.llvm.org/D27654 llvm-svn: 293337
1 parent 9d0eb99 commit 47e0ef3

File tree

5 files changed

+92
-19
lines changed

5 files changed

+92
-19
lines changed
 

‎compiler-rt/lib/asan/asan_malloc_linux.cc

+13-5
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,14 @@ INTERCEPTOR(void, free, void *ptr) {
5050
asan_free(ptr, &stack, FROM_MALLOC);
5151
}
5252

53+
#if SANITIZER_INTERCEPT_CFREE
5354
INTERCEPTOR(void, cfree, void *ptr) {
5455
GET_STACK_TRACE_FREE;
5556
if (UNLIKELY(IsInDlsymAllocPool(ptr)))
5657
return;
5758
asan_free(ptr, &stack, FROM_MALLOC);
5859
}
60+
#endif // SANITIZER_INTERCEPT_CFREE
5961

6062
INTERCEPTOR(void*, malloc, uptr size) {
6163
if (UNLIKELY(!asan_inited))
@@ -91,29 +93,32 @@ INTERCEPTOR(void*, realloc, void *ptr, uptr size) {
9193
return asan_realloc(ptr, size, &stack);
9294
}
9395

96+
#if SANITIZER_INTERCEPT_MEMALIGN
9497
INTERCEPTOR(void*, memalign, uptr boundary, uptr size) {
9598
GET_STACK_TRACE_MALLOC;
9699
return asan_memalign(boundary, size, &stack, FROM_MALLOC);
97100
}
98101

99-
INTERCEPTOR(void*, aligned_alloc, uptr boundary, uptr size) {
100-
GET_STACK_TRACE_MALLOC;
101-
return asan_memalign(boundary, size, &stack, FROM_MALLOC);
102-
}
103-
104102
INTERCEPTOR(void*, __libc_memalign, uptr boundary, uptr size) {
105103
GET_STACK_TRACE_MALLOC;
106104
void *res = asan_memalign(boundary, size, &stack, FROM_MALLOC);
107105
DTLS_on_libc_memalign(res, size);
108106
return res;
109107
}
108+
#endif // SANITIZER_INTERCEPT_MEMALIGN
109+
110+
INTERCEPTOR(void*, aligned_alloc, uptr boundary, uptr size) {
111+
GET_STACK_TRACE_MALLOC;
112+
return asan_memalign(boundary, size, &stack, FROM_MALLOC);
113+
}
110114

111115
INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
112116
GET_CURRENT_PC_BP_SP;
113117
(void)sp;
114118
return asan_malloc_usable_size(ptr, pc, bp);
115119
}
116120

121+
#if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
117122
// We avoid including malloc.h for portability reasons.
118123
// man mallinfo says the fields are "long", but the implementation uses int.
119124
// It doesn't matter much -- we just need to make sure that the libc's mallinfo
@@ -131,6 +136,7 @@ INTERCEPTOR(struct fake_mallinfo, mallinfo, void) {
131136
INTERCEPTOR(int, mallopt, int cmd, int value) {
132137
return -1;
133138
}
139+
#endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
134140

135141
INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {
136142
GET_STACK_TRACE_MALLOC;
@@ -143,10 +149,12 @@ INTERCEPTOR(void*, valloc, uptr size) {
143149
return asan_valloc(size, &stack);
144150
}
145151

152+
#if SANITIZER_INTERCEPT_PVALLOC
146153
INTERCEPTOR(void*, pvalloc, uptr size) {
147154
GET_STACK_TRACE_MALLOC;
148155
return asan_pvalloc(size, &stack);
149156
}
157+
#endif // SANITIZER_INTERCEPT_PVALLOC
150158

151159
INTERCEPTOR(void, malloc_stats, void) {
152160
__asan_print_accumulated_stats();

‎compiler-rt/lib/lsan/lsan_interceptors.cc

+40-14
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "sanitizer_common/sanitizer_flags.h"
2020
#include "sanitizer_common/sanitizer_internal_defs.h"
2121
#include "sanitizer_common/sanitizer_linux.h"
22+
#include "sanitizer_common/sanitizer_platform_interceptors.h"
2223
#include "sanitizer_common/sanitizer_platform_limits_posix.h"
2324
#include "sanitizer_common/sanitizer_tls_get_addr.h"
2425
#include "lsan.h"
@@ -86,11 +87,26 @@ INTERCEPTOR(void*, realloc, void *q, uptr size) {
8687
return Reallocate(stack, q, size, 1);
8788
}
8889

90+
#if SANITIZER_INTERCEPT_MEMALIGN
8991
INTERCEPTOR(void*, memalign, uptr alignment, uptr size) {
9092
ENSURE_LSAN_INITED;
9193
GET_STACK_TRACE_MALLOC;
9294
return Allocate(stack, size, alignment, kAlwaysClearMemory);
9395
}
96+
#define LSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)
97+
98+
INTERCEPTOR(void *, __libc_memalign, uptr alignment, uptr size) {
99+
ENSURE_LSAN_INITED;
100+
GET_STACK_TRACE_MALLOC;
101+
void *res = Allocate(stack, size, alignment, kAlwaysClearMemory);
102+
DTLS_on_libc_memalign(res, size);
103+
return res;
104+
}
105+
#define LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN INTERCEPT_FUNCTION(__libc_memalign)
106+
#else
107+
#define LSAN_MAYBE_INTERCEPT_MEMALIGN
108+
#define LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN
109+
#endif // SANITIZER_INTERCEPT_MEMALIGN
94110

95111
INTERCEPTOR(void*, aligned_alloc, uptr alignment, uptr size) {
96112
ENSURE_LSAN_INITED;
@@ -106,14 +122,6 @@ INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {
106122
return 0;
107123
}
108124

109-
INTERCEPTOR(void *, __libc_memalign, uptr alignment, uptr size) {
110-
ENSURE_LSAN_INITED;
111-
GET_STACK_TRACE_MALLOC;
112-
void *res = Allocate(stack, size, alignment, kAlwaysClearMemory);
113-
DTLS_on_libc_memalign(res, size);
114-
return res;
115-
}
116-
117125
INTERCEPTOR(void*, valloc, uptr size) {
118126
ENSURE_LSAN_INITED;
119127
GET_STACK_TRACE_MALLOC;
@@ -127,6 +135,7 @@ INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
127135
return GetMallocUsableSize(ptr);
128136
}
129137

138+
#if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
130139
struct fake_mallinfo {
131140
int x[10];
132141
};
@@ -136,11 +145,18 @@ INTERCEPTOR(struct fake_mallinfo, mallinfo, void) {
136145
internal_memset(&res, 0, sizeof(res));
137146
return res;
138147
}
148+
#define LSAN_MAYBE_INTERCEPT_MALLINFO INTERCEPT_FUNCTION(mallinfo)
139149

140150
INTERCEPTOR(int, mallopt, int cmd, int value) {
141151
return -1;
142152
}
153+
#define LSAN_MAYBE_INTERCEPT_MALLOPT INTERCEPT_FUNCTION(mallopt)
154+
#else
155+
#define LSAN_MAYBE_INTERCEPT_MALLINFO
156+
#define LSAN_MAYBE_INTERCEPT_MALLOPT
157+
#endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
143158

159+
#if SANITIZER_INTERCEPT_PVALLOC
144160
INTERCEPTOR(void*, pvalloc, uptr size) {
145161
ENSURE_LSAN_INITED;
146162
GET_STACK_TRACE_MALLOC;
@@ -152,8 +168,17 @@ INTERCEPTOR(void*, pvalloc, uptr size) {
152168
}
153169
return Allocate(stack, size, GetPageSizeCached(), kAlwaysClearMemory);
154170
}
171+
#define LSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)
172+
#else
173+
#define LSAN_MAYBE_INTERCEPT_PVALLOC
174+
#endif // SANITIZER_INTERCEPT_PVALLOC
155175

176+
#if SANITIZER_INTERCEPT_CFREE
156177
INTERCEPTOR(void, cfree, void *p) ALIAS(WRAPPER_NAME(free));
178+
#define LSAN_MAYBE_INTERCEPT_CFREE INTERCEPT_FUNCTION(cfree)
179+
#else
180+
#define LSAN_MAYBE_INTERCEPT_CFREE
181+
#endif // SANITIZER_INTERCEPT_CFREE
157182

158183
#define OPERATOR_NEW_BODY \
159184
ENSURE_LSAN_INITED; \
@@ -277,17 +302,18 @@ namespace __lsan {
277302
void InitializeInterceptors() {
278303
INTERCEPT_FUNCTION(malloc);
279304
INTERCEPT_FUNCTION(free);
280-
INTERCEPT_FUNCTION(cfree);
305+
LSAN_MAYBE_INTERCEPT_CFREE;
281306
INTERCEPT_FUNCTION(calloc);
282307
INTERCEPT_FUNCTION(realloc);
283-
INTERCEPT_FUNCTION(memalign);
308+
LSAN_MAYBE_INTERCEPT_MEMALIGN;
309+
LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN;
310+
INTERCEPT_FUNCTION(aligned_alloc);
284311
INTERCEPT_FUNCTION(posix_memalign);
285-
INTERCEPT_FUNCTION(__libc_memalign);
286312
INTERCEPT_FUNCTION(valloc);
287-
INTERCEPT_FUNCTION(pvalloc);
313+
LSAN_MAYBE_INTERCEPT_PVALLOC;
288314
INTERCEPT_FUNCTION(malloc_usable_size);
289-
INTERCEPT_FUNCTION(mallinfo);
290-
INTERCEPT_FUNCTION(mallopt);
315+
LSAN_MAYBE_INTERCEPT_MALLINFO;
316+
LSAN_MAYBE_INTERCEPT_MALLOPT;
291317
INTERCEPT_FUNCTION(pthread_create);
292318
INTERCEPT_FUNCTION(pthread_join);
293319

‎compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h

+5
Original file line numberDiff line numberDiff line change
@@ -316,4 +316,9 @@
316316
#define SANITIZER_INTERCEPT_UTMP SI_NOT_WINDOWS && !SI_MAC && !SI_FREEBSD
317317
#define SANITIZER_INTERCEPT_UTMPX SI_LINUX_NOT_ANDROID || SI_MAC || SI_FREEBSD
318318

319+
#define SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO (!SI_FREEBSD && !SI_MAC)
320+
#define SANITIZER_INTERCEPT_MEMALIGN (!SI_FREEBSD && !SI_MAC)
321+
#define SANITIZER_INTERCEPT_PVALLOC (!SI_FREEBSD && !SI_MAC)
322+
#define SANITIZER_INTERCEPT_CFREE (!SI_FREEBSD && !SI_MAC)
323+
319324
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H

‎compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_testlib.cc

+10
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,15 @@ void *realloc(void *p, size_t size) {
139139
return p;
140140
}
141141

142+
#if SANITIZER_INTERCEPT_MEMALIGN
142143
void *memalign(size_t alignment, size_t size) {
143144
if (UNLIKELY(!thread_inited))
144145
thread_init();
145146
void *p = allocator.Allocate(&cache, size, alignment);
146147
SANITIZER_MALLOC_HOOK(p, size);
147148
return p;
148149
}
150+
#endif // SANITIZER_INTERCEPT_MEMALIGN
149151

150152
int posix_memalign(void **memptr, size_t alignment, size_t size) {
151153
if (UNLIKELY(!thread_inited))
@@ -165,18 +167,26 @@ void *valloc(size_t size) {
165167
return p;
166168
}
167169

170+
#if SANITIZER_INTERCEPT_CFREE
168171
void cfree(void *p) ALIAS("free");
172+
#endif // SANITIZER_INTERCEPT_CFREE
173+
#if SANITIZER_INTERCEPT_PVALLOC
169174
void *pvalloc(size_t size) ALIAS("valloc");
175+
#endif // SANITIZER_INTERCEPT_PVALLOC
176+
#if SANITIZER_INTERCEPT_MEMALIGN
170177
void *__libc_memalign(size_t alignment, size_t size) ALIAS("memalign");
178+
#endif // SANITIZER_INTERCEPT_MEMALIGN
171179

172180
void malloc_usable_size() {
173181
}
174182

183+
#if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
175184
void mallinfo() {
176185
}
177186

178187
void mallopt() {
179188
}
189+
#endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
180190
} // extern "C"
181191

182192
namespace std {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Test that on non-glibc platforms, a number of malloc-related functions are
2+
// not intercepted.
3+
4+
// RUN: not %clang_asan -Dtestfunc=mallinfo %s -o %t
5+
// RUN: not %clang_asan -Dtestfunc=mallopt %s -o %t
6+
// RUN: not %clang_asan -Dtestfunc=memalign %s -o %t
7+
// RUN: not %clang_asan -Dtestfunc=pvalloc %s -o %t
8+
// RUN: not %clang_asan -Dtestfunc=cfree %s -o %t
9+
10+
#include <stdlib.h>
11+
12+
// For glibc, cause link failures by referencing a nonexistent function.
13+
#ifdef __GLIBC__
14+
#undef testfunc
15+
#define testfunc nonexistent_function
16+
#endif
17+
18+
void testfunc(void);
19+
20+
int main(void)
21+
{
22+
testfunc();
23+
return 0;
24+
}

0 commit comments

Comments
 (0)