@@ -943,6 +943,9 @@ static void DisableMmapExcGuardExceptions() {
943
943
set_behavior (mach_task_self (), task_exc_guard_none);
944
944
}
945
945
946
+ static void VerifyInterceptorsWorking ();
947
+ static void StripEnv ();
948
+
946
949
void InitializePlatformEarly () {
947
950
// Only use xnu_fast_mmap when on x86_64 and the kernel supports it.
948
951
use_xnu_fast_mmap =
@@ -953,17 +956,54 @@ void InitializePlatformEarly() {
953
956
#endif
954
957
if (GetDarwinKernelVersion () >= DarwinKernelVersion (19 , 0 ))
955
958
DisableMmapExcGuardExceptions ();
959
+
960
+ # if !SANITIZER_GO
961
+ MonotonicNanoTime (); // Call to initialize mach_timebase_info
962
+ VerifyInterceptorsWorking ();
963
+ StripEnv ();
964
+ # endif
956
965
}
957
966
958
967
#if !SANITIZER_GO
959
968
static const char kDyldInsertLibraries [] = " DYLD_INSERT_LIBRARIES" ;
960
969
LowLevelAllocator allocator_for_env;
961
970
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
+
962
1002
// Change the value of the env var |name|, leaking the original value.
963
1003
// If |name_value| is NULL, the variable is deleted from the environment,
964
1004
// otherwise the corresponding "NAME=value" string is replaced with
965
1005
// |name_value|.
966
- void LeakyResetEnv (const char *name, const char *name_value) {
1006
+ static void LeakyResetEnv (const char *name, const char *name_value) {
967
1007
char **env = GetEnviron ();
968
1008
uptr name_len = internal_strlen (name);
969
1009
while (*env != 0 ) {
@@ -988,100 +1028,28 @@ void LeakyResetEnv(const char *name, const char *name_value) {
988
1028
}
989
1029
}
990
1030
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 ;
1005
1034
1006
- if (ReexecDisabled ()) return ;
1035
+ char *dyld_insert_libraries =
1036
+ const_cast <char *>(GetEnv (kDyldInsertLibraries ));
1037
+ if (!dyld_insert_libraries)
1038
+ return ;
1007
1039
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.
1011
1040
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));
1018
1042
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);
1075
1044
if (!lib_is_in_env)
1076
1045
return ;
1077
1046
1078
- if (!common_flags ()->strip_env )
1079
- return ;
1080
-
1081
1047
// DYLD_INSERT_LIBRARIES is set and contains the runtime library. Let's remove
1082
1048
// the dylib from the environment variable, because interceptors are installed
1083
1049
// and we don't want our children to inherit the variable.
1084
1050
1051
+ uptr old_env_len = internal_strlen (dyld_insert_libraries);
1052
+ uptr dylib_name_len = internal_strlen (dylib_name);
1085
1053
uptr env_name_len = internal_strlen (kDyldInsertLibraries );
1086
1054
// Allocate memory to hold the previous env var name, its value, the '='
1087
1055
// sign and the '\0' char.
0 commit comments