]> git.saurik.com Git - apple/libsystem.git/blobdiff - init.c
Libsystem-1292.100.5.tar.gz
[apple/libsystem.git] / init.c
diff --git a/init.c b/init.c
index cdc51303dcc0436fbdb0e4e2d51379457a696388..8e17eb43b5dac57927410c96ab70d50c451bb13a 100644 (file)
--- a/init.c
+++ b/init.c
@@ -37,6 +37,7 @@
 #include <pthread/private.h>
 #if !TARGET_OS_DRIVERKIT
 #include <dlfcn.h>
+#include <os/variant_private.h>
 #endif
 #include <fcntl.h>
 #include <errno.h>
@@ -107,7 +108,7 @@ void libSystem_atfork_prepare(void);
 void libSystem_atfork_parent(void);
 void libSystem_atfork_child(void);
 
-#if CURRENT_VARIANT_asan
+#if SUPPORT_ASAN
 const char *__asan_default_options(void);
 #endif
 
@@ -202,14 +203,6 @@ libSystem_initializer(int argc,
 #endif
        };
        
-       static const struct _malloc_functions malloc_funcs = {
-               .version = 1,
-#if !TARGET_OS_DRIVERKIT
-               .dlopen = dlopen,
-               .dlsym = dlsym,
-#endif
-       };
-       
        _libSystem_ktrace0(ARIADNE_LIFECYCLE_libsystem_init | DBG_FUNC_START);
 
        __libkernel_init(&libkernel_funcs, envp, apple, vars);
@@ -245,7 +238,7 @@ libSystem_initializer(int argc,
        _libxpc_initializer();
        _libSystem_ktrace_init_func(LIBXPC);
 
-#if CURRENT_VARIANT_asan
+#if SUPPORT_ASAN
        setenv("DT_BYPASS_LEAKS_CHECK", "1", 1);
 #endif
 #endif // !TARGET_OS_DRIVERKIT
@@ -269,7 +262,17 @@ libSystem_initializer(int argc,
        _libSystem_ktrace_init_func(DARWIN);
 #endif // !TARGET_OS_DRIVERKIT
 
-       __stack_logging_early_finished(&malloc_funcs);
+       const struct _malloc_late_init mli = {
+               .version = 1,
+#if !TARGET_OS_DRIVERKIT
+               .dlopen = dlopen,
+               .dlsym = dlsym,
+               // this must come after _libxpc_initializer()
+               .internal_diagnostics = os_variant_has_internal_diagnostics("com.apple.libsystem"),
+#endif
+       };
+
+       __malloc_late_init(&mli);
 
 #if !TARGET_OS_IPHONE
        /* <rdar://problem/22139800> - Preserve the old behavior of apple[] for
@@ -394,24 +397,105 @@ libSystem_atfork_child(void)
        _pthread_atfork_child_handlers();
 }
 
-#if CURRENT_VARIANT_asan
-#define DEFAULT_ASAN_OPTIONS "color=never" \
-       ":handle_segv=0:handle_sigbus=0:handle_sigill=0:handle_sigfpe=0" \
-       ":external_symbolizer_path=" \
-       ":log_path=stderr:log_exe_name=0" \
-       ":halt_on_error=0" \
-       ":print_module_map=2" \
-       ":start_deactivated=1" \
-       ":detect_odr_violation=0"
+#if SUPPORT_ASAN
+
+// Prevents use of coloring terminal signals in report. These
+// hinder readability when writing to files or the system log.
+#define ASAN_OPT_NO_COLOR "color=never"
+
+// Disables ASan's signal handlers. It's better to let the system catch
+// these kinds of crashes.
+#define ASAN_OPT_NO_SIGNAL_HANDLERS ":handle_segv=0:handle_sigbus=0:handle_sigill=0:handle_sigfpe=0"
+
+// Disables using the out-of-process symbolizer (atos) but still allows
+// in-process symbolization via `dladdr()`. This gives useful function names
+// (unless they are redacted) which can be helpful in the event we can't
+// symbolize offline. Out-of-process symbolization isn't useful because
+// the dSYMs are usually not present on the device.
+#define ASAN_OPT_NO_OOP_SYMBOLIZER ":external_symbolizer_path="
+
+// Don't try to log to a file. It's difficult to find a location for the file
+// that is writable so just write to stderr.
+#define ASAN_OPT_FILE_LOG ":log_path=stderr:log_exe_name=0"
+
+// Print the module map when finding an issue. This is necessary for offline
+// symbolication.
+#define ASAN_OPT_MODULE_MAP ":print_module_map=2"
+
+// Disable ODR violation checking.
+// <rdar://problem/71021707> Investigate enabling ODR checking for ASan in BATS and in the `_asan` variant
+#define ASAN_OPT_NO_ODR_VIOLATION ":detect_odr_violation=0"
+
+// Start ASan in deactivated mode. This reduces memory overhead until
+// instrumented code is loaded. This prevents catching bugs if no instrumented
+// code is loaded.
+#define ASAN_OPT_START_DEACTIVATED ":start_deactivated=1"
+
+// Do not crash when an error is found. This always works for errors caught via
+// ASan's interceptors. This won't work for errors caught in ASan
+// instrumentation unless the code is compiled with
+// `-fsanitize-recover=address`.  If this option is being used then the ASan
+// reports can only be found by looking at the system log.
+#define ASAN_OPT_NO_HALT_ON_ERROR ":halt_on_error=0"
+
+// Crash when an error is found.
+#define ASAN_OPT_HALT_ON_ERROR ":halt_on_error=1"
+
+// ASan options common to all supported variants
+#define COMMON_ASAN_OPTIONS \
+  ASAN_OPT_NO_COLOR \
+  ASAN_OPT_NO_SIGNAL_HANDLERS \
+  ASAN_OPT_NO_OOP_SYMBOLIZER \
+  ASAN_OPT_FILE_LOG \
+  ASAN_OPT_MODULE_MAP \
+  ASAN_OPT_NO_ODR_VIOLATION
+
+#if defined(CURRENT_VARIANT_normal) || defined(CURRENT_VARIANT_debug) || defined (CURRENT_VARIANT_no_asan)
+
+// In the normal variant ASan will be running in all userspace processes ("whole userspace ASan").
+// This mode exists to support "ASan in BATS".
+//
+// Supporting ASan in the debug variant preserves existing behavior.
+//
+// The no_asan variant does not load the ASan runtime. However, the runtime
+// might still be loaded if a program or its dependencies are instrumented.
+// There is nothing we can do to prevent this so we should set the appropriate
+// ASan options (same as normal variant) if it does happen. We try to do this
+// here but this currently doesn't work due to rdar://problem/72212914.
+//
+// These variants use the following extra options:
+//
+// ASAN_OPT_NO_HALT_ON_ERROR - Try to avoid crash loops and increase the
+//                             chances of booting successfully.
+// ASAN_OPT_START_DEACTIVATED - Try to reduce memory overhead.
+
+# define DEFAULT_ASAN_OPTIONS \
+  COMMON_ASAN_OPTIONS \
+  ASAN_OPT_START_DEACTIVATED \
+  ASAN_OPT_NO_HALT_ON_ERROR
+
+#elif defined(CURRENT_VARIANT_asan)
+
+// The `_asan` variant is used to support running proceses with
+// `DYLD_IMAGE_SUFFIX=_asan`. This mode is typically used to target select parts of the OS.
+//
+// It uses the following extra options:
+//
+// ASAN_OPT_HALT_ON_ERROR - Crashing is better than just writing the error to the system log
+//                          if the system can handle this. This workflow is
+//                          more tolerant (e.g. `launchctl debug`) to crashing
+//                          than the "whole userspace ASan" workflow.
+
+# define DEFAULT_ASAN_OPTIONS \
+  COMMON_ASAN_OPTIONS \
+  ASAN_OPT_HALT_ON_ERROR
+
+#else
+# error Supporting ASan is not supported in the current variant
+#endif
+
 char dynamic_asan_opts[1024] = {0};
 const char *__asan_default_options(void) {
-       char executable_path[4096] = {0};
-       uint32_t size = sizeof(executable_path);
-       const char *process_name = "";
-       if (_NSGetExecutablePath(executable_path, &size) == 0) {
-               process_name = strrchr(executable_path, '/') + 1;
-       }
-
        int fd = open("/System/Library/Preferences/com.apple.asan.options", O_RDONLY);
        if (fd != -1) {
                ssize_t remaining_size = sizeof(dynamic_asan_opts) - 1;
@@ -430,6 +514,20 @@ const char *__asan_default_options(void) {
 
        return DEFAULT_ASAN_OPTIONS;
 }
+
+#undef ASAN_OPT_NO_COLOR
+#undef ASAN_OPT_NO_SIGNAL_HANDLERS
+#undef ASAN_OPT_NO_OOP_SYMBOLIZER
+#undef ASAN_OPT_FILE_LOG
+#undef ASAN_OPT_MODULE_MAP
+#undef ASAN_OPT_NO_ODR_VIOLATION
+#undef ASAN_OPT_START_DEACTIVATED
+#undef ASAN_OPT_NO_HALT_ON_ERROR
+#undef ASAN_OPT_HALT_ON_ERROR
+
+#undef COMMON_ASAN_OPTIONS
+#undef DEFAULT_ASAN_OPTIONS
+
 #endif
 
 /*