@@ -943,6 +943,9 @@ static void DisableMmapExcGuardExceptions() {
943943 set_behavior (mach_task_self (), task_exc_guard_none);
944944}
945945
946+ static void VerifyInterceptorsWorking ();
947+ static void StripEnv ();
948+
946949void InitializePlatformEarly () {
947950 // Only use xnu_fast_mmap when on x86_64 and the kernel supports it.
948951 use_xnu_fast_mmap =
@@ -953,17 +956,54 @@ void InitializePlatformEarly() {
953956#endif
954957 if (GetDarwinKernelVersion () >= DarwinKernelVersion (19 , 0 ))
955958 DisableMmapExcGuardExceptions ();
959+
960+ # if !SANITIZER_GO
961+ MonotonicNanoTime (); // Call to initialize mach_timebase_info
962+ VerifyInterceptorsWorking ();
963+ StripEnv ();
964+ # endif
956965}
957966
958967#if !SANITIZER_GO
959968static const char kDyldInsertLibraries [] = " DYLD_INSERT_LIBRARIES" ;
960969LowLevelAllocator allocator_for_env;
961970
971+ static bool ShouldCheckInterceptors () {
972+ // Restrict "interceptors working?" check to ASan and TSan.
973+ const char *sanitizer_names[] = {" AddressSanitizer" , " ThreadSanitizer" };
974+ size_t count = sizeof (sanitizer_names) / sizeof (sanitizer_names[0 ]);
975+ for (size_t i = 0 ; i < count; i++) {
976+ if (internal_strcmp (sanitizer_names[i], SanitizerToolName) == 0 )
977+ return true ;
978+ }
979+ return false ;
980+ }
981+
982+ static void VerifyInterceptorsWorking () {
983+ if (!common_flags ()->verify_interceptors || !ShouldCheckInterceptors ())
984+ return ;
985+
986+ // Verify that interceptors really work. We'll use dlsym to locate
987+ // "puts", if interceptors are working, it should really point to
988+ // "wrap_puts" within our own dylib.
989+ Dl_info info_puts, info_runtime;
990+ RAW_CHECK (dladdr (dlsym (RTLD_DEFAULT, " puts" ), &info_puts));
991+ RAW_CHECK (dladdr ((void *)__sanitizer_report_error_summary, &info_runtime));
992+ if (internal_strcmp (info_puts.dli_fname , info_runtime.dli_fname ) != 0 ) {
993+ Report (
994+ " ERROR: Interceptors are not working. This may be because %s is "
995+ " loaded too late (e.g. via dlopen). Please launch the executable "
996+ " with:\n %s=%s\n " ,
997+ SanitizerToolName, kDyldInsertLibraries , info_runtime.dli_fname );
998+ RAW_CHECK (" interceptors not installed" && 0 );
999+ }
1000+ }
1001+
9621002// Change the value of the env var |name|, leaking the original value.
9631003// If |name_value| is NULL, the variable is deleted from the environment,
9641004// otherwise the corresponding "NAME=value" string is replaced with
9651005// |name_value|.
966- void LeakyResetEnv (const char *name, const char *name_value) {
1006+ static void LeakyResetEnv (const char *name, const char *name_value) {
9671007 char **env = GetEnviron ();
9681008 uptr name_len = internal_strlen (name);
9691009 while (*env != 0 ) {
@@ -988,100 +1028,28 @@ void LeakyResetEnv(const char *name, const char *name_value) {
9881028 }
9891029}
9901030
991- SANITIZER_WEAK_CXX_DEFAULT_IMPL
992- bool ReexecDisabled () {
993- return false ;
994- }
995-
996- static bool DyldNeedsEnvVariable () {
997- // If running on OS X 10.11+ or iOS 9.0+, dyld will interpose even if
998- // DYLD_INSERT_LIBRARIES is not set.
999- return GetMacosAlignedVersion () < MacosVersion (10 , 11 );
1000- }
1001-
1002- void MaybeReexec () {
1003- // FIXME: This should really live in some "InitializePlatform" method.
1004- MonotonicNanoTime ();
1031+ static void StripEnv () {
1032+ if (!common_flags ()->strip_env )
1033+ return ;
10051034
1006- if (ReexecDisabled ()) return ;
1035+ char *dyld_insert_libraries =
1036+ const_cast <char *>(GetEnv (kDyldInsertLibraries ));
1037+ if (!dyld_insert_libraries)
1038+ return ;
10071039
1008- // Make sure the dynamic runtime library is preloaded so that the
1009- // wrappers work. If it is not, set DYLD_INSERT_LIBRARIES and re-exec
1010- // ourselves.
10111040 Dl_info info;
1012- RAW_CHECK (dladdr ((void *)((uptr)&__sanitizer_report_error_summary), &info));
1013- char *dyld_insert_libraries =
1014- const_cast <char *>(GetEnv (kDyldInsertLibraries ));
1015- uptr old_env_len = dyld_insert_libraries ?
1016- internal_strlen (dyld_insert_libraries) : 0 ;
1017- uptr fname_len = internal_strlen (info.dli_fname );
1041+ RAW_CHECK (dladdr ((void *)__sanitizer_report_error_summary, &info));
10181042 const char *dylib_name = StripModuleName (info.dli_fname );
1019- uptr dylib_name_len = internal_strlen (dylib_name);
1020-
1021- bool lib_is_in_env = dyld_insert_libraries &&
1022- internal_strstr (dyld_insert_libraries, dylib_name);
1023- if (DyldNeedsEnvVariable () && !lib_is_in_env) {
1024- // DYLD_INSERT_LIBRARIES is not set or does not contain the runtime
1025- // library.
1026- InternalMmapVector<char > program_name (1024 );
1027- uint32_t buf_size = program_name.size ();
1028- _NSGetExecutablePath (program_name.data (), &buf_size);
1029- char *new_env = const_cast <char *>(info.dli_fname );
1030- if (dyld_insert_libraries) {
1031- // Append the runtime dylib name to the existing value of
1032- // DYLD_INSERT_LIBRARIES.
1033- new_env = (char *)allocator_for_env.Allocate (old_env_len + fname_len + 2 );
1034- internal_strncpy (new_env, dyld_insert_libraries, old_env_len);
1035- new_env[old_env_len] = ' :' ;
1036- // Copy fname_len and add a trailing zero.
1037- internal_strncpy (new_env + old_env_len + 1 , info.dli_fname ,
1038- fname_len + 1 );
1039- // Ok to use setenv() since the wrappers don't depend on the value of
1040- // asan_inited.
1041- setenv (kDyldInsertLibraries , new_env, /* overwrite*/ 1 );
1042- } else {
1043- // Set DYLD_INSERT_LIBRARIES equal to the runtime dylib name.
1044- setenv (kDyldInsertLibraries , info.dli_fname , /* overwrite*/ 0 );
1045- }
1046- VReport (1 , " exec()-ing the program with\n " );
1047- VReport (1 , " %s=%s\n " , kDyldInsertLibraries , new_env);
1048- VReport (1 , " to enable wrappers.\n " );
1049- execv (program_name.data (), *_NSGetArgv ());
1050-
1051- // We get here only if execv() failed.
1052- Report (" ERROR: The process is launched without DYLD_INSERT_LIBRARIES, "
1053- " which is required for the sanitizer to work. We tried to set the "
1054- " environment variable and re-execute itself, but execv() failed, "
1055- " possibly because of sandbox restrictions. Make sure to launch the "
1056- " executable with:\n %s=%s\n " , kDyldInsertLibraries , new_env);
1057- RAW_CHECK (" execv failed" && 0 );
1058- }
1059-
1060- // Verify that interceptors really work. We'll use dlsym to locate
1061- // "puts", if interceptors are working, it should really point to
1062- // "wrap_puts" within our own dylib.
1063- Dl_info info_puts;
1064- void *dlopen_addr = dlsym (RTLD_DEFAULT, " puts" );
1065- RAW_CHECK (dladdr (dlopen_addr, &info_puts));
1066- if (internal_strcmp (info.dli_fname , info_puts.dli_fname ) != 0 ) {
1067- Report (
1068- " ERROR: Interceptors are not working. This may be because %s is "
1069- " loaded too late (e.g. via dlopen). Please launch the executable "
1070- " with:\n %s=%s\n " ,
1071- SanitizerToolName, kDyldInsertLibraries , info.dli_fname );
1072- RAW_CHECK (" interceptors not installed" && 0 );
1073- }
1074-
1043+ bool lib_is_in_env = internal_strstr (dyld_insert_libraries, dylib_name);
10751044 if (!lib_is_in_env)
10761045 return ;
10771046
1078- if (!common_flags ()->strip_env )
1079- return ;
1080-
10811047 // DYLD_INSERT_LIBRARIES is set and contains the runtime library. Let's remove
10821048 // the dylib from the environment variable, because interceptors are installed
10831049 // and we don't want our children to inherit the variable.
10841050
1051+ uptr old_env_len = internal_strlen (dyld_insert_libraries);
1052+ uptr dylib_name_len = internal_strlen (dylib_name);
10851053 uptr env_name_len = internal_strlen (kDyldInsertLibraries );
10861054 // Allocate memory to hold the previous env var name, its value, the '='
10871055 // sign and the '\0' char.
0 commit comments