[compiler-rt] r241487 - [asan] Add OS X 10.11's new dyld interposition support

Kuba Brecka kuba.brecka at gmail.com
Mon Jul 6 12:07:55 PDT 2015


Author: kuba.brecka
Date: Mon Jul  6 14:07:55 2015
New Revision: 241487

URL: http://llvm.org/viewvc/llvm-project?rev=241487&view=rev
Log:
[asan] Add OS X 10.11's new dyld interposition support

On OS X 10.11 (which is currently a public beta), the dynamic linker has been improved so that it doesn't require the use of DYLD_INSERT_LIBRARIES in order for interposition/wrappers to work. This patch adds support of this behavior into ASan – we no longer need to re-exec in case the env. variable is not set.

Reviewed at http://reviews.llvm.org/D10924


Modified:
    compiler-rt/trunk/lib/asan/asan_mac.cc
    compiler-rt/trunk/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc

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=241487&r1=241486&r2=241487&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_mac.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_mac.cc Mon Jul  6 14:07:55 2015
@@ -99,6 +99,23 @@ void DisableReexec() {
   reexec_disabled = true;
 }
 
+bool DyldNeedsEnvVariable() {
+// If running on OS X 10.11+ or iOS 9.0+, dyld will interpose even if
+// DYLD_INSERT_LIBRARIES is not set.
+
+#if SANITIZER_IOSSIM
+  // GetMacosVersion will not work for the simulator, whose kernel version
+  // is tied to the host. Use a weak linking hack for the simulator.
+  // This API was introduced in the same version of the OS as the dyld
+  // optimization.
+
+  // Check for presence of a symbol that is available on OS X 10.11+, iOS 9.0+.
+  return (dlsym(RTLD_NEXT, "mach_memory_info") == nullptr);
+#else
+  return (GetMacosVersion() <= MACOS_VERSION_YOSEMITE);
+#endif
+}
+
 void MaybeReexec() {
   if (reexec_disabled) return;
 
@@ -114,8 +131,10 @@ void MaybeReexec() {
   uptr fname_len = internal_strlen(info.dli_fname);
   const char *dylib_name = StripModuleName(info.dli_fname);
   uptr dylib_name_len = internal_strlen(dylib_name);
-  if (!dyld_insert_libraries ||
-      !REAL(strstr)(dyld_insert_libraries, dylib_name)) {
+
+  bool lib_is_in_env =
+      dyld_insert_libraries && REAL(strstr)(dyld_insert_libraries, dylib_name);
+  if (DyldNeedsEnvVariable() && !lib_is_in_env) {
     // DYLD_INSERT_LIBRARIES is not set or does not contain the runtime
     // library.
     char program_name[1024];
@@ -152,6 +171,9 @@ void MaybeReexec() {
     CHECK("execv failed" && 0);
   }
 
+  if (!lib_is_in_env)
+    return;
+
   // DYLD_INSERT_LIBRARIES is set and contains the runtime library. Let's remove
   // the dylib from the environment variable, because interceptors are installed
   // and we don't want our children to inherit the variable.

Modified: compiler-rt/trunk/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc?rev=241487&r1=241486&r2=241487&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc Mon Jul  6 14:07:55 2015
@@ -7,11 +7,25 @@
 // RUN:   | sed -e 's/.*"\(.*libclang_rt.asan_osx_dynamic.dylib\)".*/\1/'` \
 // RUN:   %T/dyld_insert_libraries_reexec/libclang_rt.asan_osx_dynamic.dylib
 // RUN: %clangxx_asan %s -o %T/dyld_insert_libraries_reexec/a.out
+
 // RUN: env DYLD_INSERT_LIBRARIES=@executable_path/libclang_rt.asan_osx_dynamic.dylib \
 // RUN:   ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1 %run %T/dyld_insert_libraries_reexec/a.out 2>&1 \
 // RUN:   | FileCheck %s
-// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1 %run %T/dyld_insert_libraries_reexec/a.out 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-NOINSERT %s
+
+// RUN: IS_OSX_10_11_OR_HIGHER=$([ `sw_vers -productVersion | cut -d'.' -f2` -lt 11 ]; echo $?)
+
+// On OS X 10.10 and lower, if the dylib is not DYLD-inserted, ASan will re-exec.
+// RUN: if [ $IS_OSX_10_11_OR_HIGHER == 0 ]; then \
+// RUN:   env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1 %run %T/dyld_insert_libraries_reexec/a.out 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-NOINSERT %s; \
+// RUN:   fi
+
+// On OS X 10.11 and higher, we don't need to DYLD-insert anymore, and the interceptors
+// still installed correctly. Let's just check that things work and we don't try to re-exec.
+// RUN: if [ $IS_OSX_10_11_OR_HIGHER == 1 ]; then \
+// RUN:   env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1 %run %T/dyld_insert_libraries_reexec/a.out 2>&1 \
+// RUN:   | FileCheck %s; \
+// RUN:   fi
 
 #include <stdio.h>
 






More information about the llvm-commits mailing list