Index: lib/asan/asan_mac.cc =================================================================== --- lib/asan/asan_mac.cc +++ lib/asan/asan_mac.cc @@ -99,6 +99,23 @@ 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 @@ 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 @@ 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. Index: test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc =================================================================== --- test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc +++ 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