[llvm-commits] [compiler-rt] r148696 - in /compiler-rt/trunk/lib/asan: asan_interceptors.cc asan_mac.cc asan_mac.h tests/asan_test.cc

Alexander Potapenko glider at google.com
Mon Jan 23 02:09:54 PST 2012


Author: glider
Date: Mon Jan 23 04:09:54 2012
New Revision: 148696

URL: http://llvm.org/viewvc/llvm-project?rev=148696&view=rev
Log:
Wrap CFStringCreateCopy to prevent copying constant CF strings.
This should fix http://code.google.com/p/address-sanitizer/issues/detail?id=10


Modified:
    compiler-rt/trunk/lib/asan/asan_interceptors.cc
    compiler-rt/trunk/lib/asan/asan_mac.cc
    compiler-rt/trunk/lib/asan/asan_mac.h
    compiler-rt/trunk/lib/asan/tests/asan_test.cc

Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=148696&r1=148695&r2=148696&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Mon Jan 23 04:09:54 2012
@@ -94,6 +94,7 @@
 dispatch_barrier_async_f_f real_dispatch_barrier_async_f;
 dispatch_group_async_f_f real_dispatch_group_async_f;
 pthread_workqueue_additem_np_f real_pthread_workqueue_additem_np;
+CFStringCreateCopy_f real_CFStringCreateCopy;
 #endif
 
 sigaction_f             real_sigaction;
@@ -648,6 +649,14 @@
   if (FLAG_v >= 2) {
     INTERCEPT_FUNCTION(pthread_workqueue_additem_np);
   }
+  // Normally CFStringCreateCopy should not copy constant CF strings.
+  // Replacing the default CFAllocator causes constant strings to be copied
+  // rather than just returned, which leads to bugs in big applications like
+  // Chromium and WebKit, see
+  // http://code.google.com/p/address-sanitizer/issues/detail?id=10
+  // Until this problem is fixed we need to check that the string is
+  // non-constant before calling CFStringCreateCopy.
+  INTERCEPT_FUNCTION(CFStringCreateCopy);
 #else
   // On Darwin siglongjmp tailcalls longjmp, so we don't want to intercept it
   // there.

Modified: compiler-rt/trunk/lib/asan/asan_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.cc?rev=148696&r1=148695&r2=148696&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_mac.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_mac.cc Mon Jan 23 04:09:54 2012
@@ -42,6 +42,7 @@
 extern dispatch_barrier_async_f_f real_dispatch_barrier_async_f;
 extern dispatch_group_async_f_f real_dispatch_group_async_f;
 extern pthread_workqueue_additem_np_f real_pthread_workqueue_additem_np;
+extern CFStringCreateCopy_f real_CFStringCreateCopy;
 
 void GetPcSpBp(void *context, uintptr_t *pc, uintptr_t *sp, uintptr_t *bp) {
   ucontext_t *ucontext = (ucontext_t*)context;
@@ -514,4 +515,45 @@
                                            itemhandlep, gencountp);
 }
 
+// CF_RC_BITS, the layout of CFRuntimeBase and __CFStrIsConstant are internal
+// and subject to change in further CoreFoundation versions. Apple does not
+// guarantee any binary compatibility from release to release.
+
+// See http://opensource.apple.com/source/CF/CF-635.15/CFInternal.h
+#if defined(__BIG_ENDIAN__)
+#define CF_RC_BITS 0
+#endif
+
+#if defined(__LITTLE_ENDIAN__)
+#define CF_RC_BITS 3
+#endif
+
+// See http://opensource.apple.com/source/CF/CF-635.15/CFRuntime.h
+typedef struct __CFRuntimeBase {
+  uintptr_t _cfisa;
+  uint8_t _cfinfo[4];
+#if __LP64__
+  uint32_t _rc;
+#endif
+} CFRuntimeBase;
+
+// See http://opensource.apple.com/source/CF/CF-635.15/CFString.c
+int __CFStrIsConstant(CFStringRef str) {
+  CFRuntimeBase *base = (CFRuntimeBase*)str;
+#if __LP64__
+  return base->_rc == 0;
+#else
+  return (base->_cfinfo[CF_RC_BITS]) == 0;
+#endif
+}
+
+extern "C"
+CFStringRef WRAP(CFStringCreateCopy)(CFAllocatorRef alloc, CFStringRef str) {
+  if (__CFStrIsConstant(str)) {
+    return str;
+  } else {
+    return real_CFStringCreateCopy(alloc, str);
+  }
+}
+
 #endif  // __APPLE__

Modified: compiler-rt/trunk/lib/asan/asan_mac.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.h?rev=148696&r1=148695&r2=148696&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_mac.h (original)
+++ compiler-rt/trunk/lib/asan/asan_mac.h Mon Jan 23 04:09:54 2012
@@ -22,6 +22,7 @@
 #include <dispatch/dispatch.h>
 #include <mach/mach_error.h>
 #include <setjmp.h>
+#include <CoreFoundation/CFString.h>
 
 typedef void* pthread_workqueue_t;
 typedef void* pthread_workitem_handle_t;
@@ -44,7 +45,8 @@
 typedef int (*pthread_workqueue_additem_np_f)(pthread_workqueue_t workq,
     void *(*workitem_func)(void *), void * workitem_arg,
     pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp);
-
+typedef CFStringRef (*CFStringCreateCopy_f)(CFAllocatorRef alloc,
+                                            CFStringRef str);
 
 // A wrapper for the ObjC blocks used to support libdispatch.
 typedef struct {
@@ -90,6 +92,7 @@
 int WRAP(pthread_workqueue_additem_np)(pthread_workqueue_t workq,
     void *(*workitem_func)(void *), void * workitem_arg,
     pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp);
+CFStringRef WRAP(CFStringCreateCopy)(CFAllocatorRef alloc, CFStringRef str);
 }
 
 #endif  // ASAN_MAC_H

Modified: compiler-rt/trunk/lib/asan/tests/asan_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/asan_test.cc?rev=148696&r1=148695&r2=148696&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/tests/asan_test.cc (original)
+++ compiler-rt/trunk/lib/asan/tests/asan_test.cc Mon Jan 23 04:09:54 2012
@@ -1898,7 +1898,7 @@
 }
 
 // Test that CFStringCreateCopy does not copy constant strings.
-TEST(AddressSanitizerMac, DISABLED_CFStringCreateCopy) {
+TEST(AddressSanitizerMac, CFStringCreateCopy) {
   CFStringRef str = CFSTR("Hello world!\n");
   CFStringRef str2 = CFStringCreateCopy(0, str);
   EXPECT_EQ(str, str2);





More information about the llvm-commits mailing list