summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2012-07-05 14:46:56 +0000
committerAlexander Potapenko <glider@google.com>2012-07-05 14:46:56 +0000
commit25b567dd0d2219d2b2d5c1f8838c098b00ca9c80 (patch)
treea7095ee550061d2169a76db87371a522b44723d2
parent38b1ec4317eabc0c09e5976a967f31be2e5ac308 (diff)
downloadbcm5719-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.cc11
-rw-r--r--compiler-rt/lib/asan/asan_malloc_mac.cc23
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
OpenPOWER on IntegriCloud