forked from OSchip/llvm-project
[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 llvm-svn: 241487
This commit is contained in:
parent
bfa848cfa1
commit
76cc55a94d
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
Loading…
Reference in New Issue