summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKuba Brecka <kuba.brecka@gmail.com>2015-07-06 19:07:55 +0000
committerKuba Brecka <kuba.brecka@gmail.com>2015-07-06 19:07:55 +0000
commite1d19d19744ad2f217ed7acb183d649f947ef2cc (patch)
tree20fee8cdebc082c705a7e29bca035ca9349b2a05
parent5944ed42daed51cd9a2827cb5eeb4d3bbf0500c7 (diff)
downloadcompiler-rt-e1d19d19744ad2f217ed7acb183d649f947ef2cc.tar.gz
[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 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@241487 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/asan/asan_mac.cc26
-rw-r--r--test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc18
2 files changed, 40 insertions, 4 deletions
diff --git a/lib/asan/asan_mac.cc b/lib/asan/asan_mac.cc
index 37ec51ccb..3e028378d 100644
--- a/lib/asan/asan_mac.cc
+++ b/lib/asan/asan_mac.cc
@@ -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.
diff --git a/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc b/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc
index 9210bafda..486223473 100644
--- a/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc
+++ b/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc
@@ -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>