diff options
| author | Alexander Potapenko <glider@google.com> | 2012-07-05 14:46:56 +0000 |
|---|---|---|
| committer | Alexander Potapenko <glider@google.com> | 2012-07-05 14:46:56 +0000 |
| commit | 25b567dd0d2219d2b2d5c1f8838c098b00ca9c80 (patch) | |
| tree | a7095ee550061d2169a76db87371a522b44723d2 | |
| parent | 38b1ec4317eabc0c09e5976a967f31be2e5ac308 (diff) | |
| download | bcm5719-llvm-25b567dd0d2219d2b2d5c1f8838c098b00ca9c80.tar.gz bcm5719-llvm-25b567dd0d2219d2b2d5c1f8838c098b00ca9c80.zip | |
Fix http://code.google.com/p/address-sanitizer/issues/detail?id=87 by making sure we replace the default CFAllocator only after __CFInitialize has been called.
llvm-svn: 159749
| -rw-r--r-- | compiler-rt/lib/asan/asan_mac.cc | 11 | ||||
| -rw-r--r-- | compiler-rt/lib/asan/asan_malloc_mac.cc | 23 |
2 files changed, 30 insertions, 4 deletions
diff --git a/compiler-rt/lib/asan/asan_mac.cc b/compiler-rt/lib/asan/asan_mac.cc index 2d5a967b686..f58852c21d6 100644 --- a/compiler-rt/lib/asan/asan_mac.cc +++ b/compiler-rt/lib/asan/asan_mac.cc @@ -295,8 +295,6 @@ INTERCEPTOR(void, dispatch_async_f, dispatch_queue_t dq, void *ctxt, asan_dispatch_call_block_and_release); } -DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr) - INTERCEPTOR(void, dispatch_sync_f, dispatch_queue_t dq, void *ctxt, dispatch_function_t func) { GET_STACK_TRACE_HERE(kStackTraceMax); @@ -428,6 +426,12 @@ INTERCEPTOR(CFStringRef, CFStringCreateCopy, CFAllocatorRef alloc, } } +DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr) + +extern "C" +void __CFInitialize(); +DECLARE_REAL_AND_INTERCEPTOR(void, __CFInitialize) + namespace __asan { void InitializeMacInterceptors() { @@ -453,6 +457,9 @@ void InitializeMacInterceptors() { // Some of the library functions call free() directly, so we have to // intercept it. CHECK(INTERCEPT_FUNCTION(free)); + if (FLAG_replace_cfallocator) { + CHECK(INTERCEPT_FUNCTION(__CFInitialize)); + } } } // namespace __asan diff --git a/compiler-rt/lib/asan/asan_malloc_mac.cc b/compiler-rt/lib/asan/asan_malloc_mac.cc index 0f510bf53b1..75f77887bf6 100644 --- a/compiler-rt/lib/asan/asan_malloc_mac.cc +++ b/compiler-rt/lib/asan/asan_malloc_mac.cc @@ -78,6 +78,21 @@ INTERCEPTOR(void, free, void *ptr) { } } +// We can't always replace the default CFAllocator with cf_asan right in +// ReplaceSystemMalloc(), because it is sometimes called before +// __CFInitialize(), when the default allocator is invalid and replacing it may +// crash the program. Instead we wait for the allocator to initialize and jump +// in just after __CFInitialize(). Nobody is going to allocate memory using +// CFAllocators before that, so we won't miss anything. +// +// See http://code.google.com/p/address-sanitizer/issues/detail?id=87 +// and http://opensource.apple.com/source/CF/CF-550.43/CFRuntime.c +INTERCEPTOR(void, __CFInitialize) { + CHECK(FLAG_replace_cfallocator); + REAL(__CFInitialize)(); + if (cf_asan) CFAllocatorSetDefault(cf_asan); +} + namespace { // TODO(glider): the mz_* functions should be united with the Linux wrappers, // as they are basically copied from there. @@ -300,7 +315,7 @@ boolean_t mi_zone_locked(malloc_zone_t *zone) { } // unnamed namespace -extern bool kCFUseCollectableAllocator; // is GC on? +extern int __CFRuntimeClassTableSize; namespace __asan { void ReplaceSystemMalloc() { @@ -377,7 +392,11 @@ void ReplaceSystemMalloc() { /*deallocate*/ &cf_free, /*preferredSize*/ 0 }; cf_asan = CFAllocatorCreate(kCFAllocatorUseContext, &asan_context); - CFAllocatorSetDefault(cf_asan); + // If __CFInitialize() hasn't been called yet, cf_asan will be installed + // as the default allocator after __CFInitialize() finishes (see the + // interceptor for __CFInitialize() above). Otherwise (if + // __CFRuntimeClassTableSize is initialized) install cf_asan right now. + if (__CFRuntimeClassTableSize) CFAllocatorSetDefault(cf_asan); } } } // namespace __asan |

