From: Apple Date: Mon, 19 Apr 2021 17:25:53 +0000 (+0000) Subject: Libsystem-1292.100.5.tar.gz X-Git-Tag: macos-113^0 X-Git-Url: https://git.saurik.com/apple/libsystem.git/commitdiff_plain/HEAD Libsystem-1292.100.5.tar.gz --- diff --git a/Libsystem.xcconfig b/Libsystem.xcconfig index 545b436..6e1b511 100644 --- a/Libsystem.xcconfig +++ b/Libsystem.xcconfig @@ -13,17 +13,29 @@ ASAN_IN_NORMAL_VARIANT = $(ASAN_IN_NORMAL_VARIANT_RC_$(RC_SUPPORT_ADDRESS_SANITI // Apple Internal Sanitizer dylib path SANITIZER_DYLIB_DIR = /usr/appleinternal/lib/sanitizers -ASAN_CFLAGS_ = -ASAN_CFLAGS_YES = -DCURRENT_VARIANT_asan=1 -ASAN_LDFLAGS_ = +ASAN_CFLAGS_NO = +ASAN_CFLAGS_YES = -DSUPPORT_ASAN=1 +ASAN_LDFLAGS_NO = SHARED_ASAN_LDFLAGS = -L $(SDKROOT)$(SANITIZER_DYLIB_DIR) -Xlinker -not_for_dyld_shared_cache -rpath $(SANITIZER_DYLIB_DIR)/ ASAN_LDFLAGS_YES[sdk=macosx*] = $(SHARED_ASAN_LDFLAGS) -Xlinker -upward-lclang_rt.asan_osx_dynamic ASAN_LDFLAGS_YES[sdk=iphoneos*] = $(SHARED_ASAN_LDFLAGS) -Xlinker -upward-lclang_rt.asan_ios_dynamic ASAN_LDFLAGS_YES[sdk=watchos*] = $(SHARED_ASAN_LDFLAGS) -Xlinker -upward-lclang_rt.asan_watchos_dynamic ASAN_LDFLAGS_YES[sdk=appletvos*] = $(SHARED_ASAN_LDFLAGS) -Xlinker -upward-lclang_rt.asan_tvos_dynamic ASAN_LDFLAGS_YES[sdk=bridgeos*] = $(SHARED_ASAN_LDFLAGS) -Xlinker -upward-lclang_rt.asan_bridgeos_dynamic -ASAN_IN_NORMAL_VARIANT_CFLAGS = $(ASAN_CFLAGS_$(ASAN_IN_NORMAL_VARIANT)) -ASAN_IN_NORMAL_VARIANT_LDFLAGS = $(ASAN_LDFLAGS_$(ASAN_IN_NORMAL_VARIANT)) + +// "no_asan" variant +// +// The "no_asan" variant is only built when ASAN_IN_NORMAL_VARIANT=YES. +// The variant exists to provide a way to opt-out processes from the +// "Whole OS ASan" mode. It should be identical to the "normal" variant +// except it does **not** upward link the ASan runtime. Despite the name, +// this does not enforce that ASan is not used. This is because an ASan +// instrumented binary could also cause the ASan runtime to be loaded. +NOASAN_CFLAGS_YES = $(ASAN_CFLAGS_YES) +NOASAN_LDFLAGS_YES = +EXTRA_BUILD_VARIANTS_ASAN_IN_NORMAL_VARIANT_NO = +EXTRA_BUILD_VARIANTS_ASAN_IN_NORMAL_VARIANT_YES = no_asan +EXTRA_BUILD_VARIANTS_ASAN_IN_NORMAL_VARIANT = $(EXTRA_BUILD_VARIANTS_ASAN_IN_NORMAL_VARIANT_$(ASAN_IN_NORMAL_VARIANT)) SDK_INSTALL_VARIANT = $(SDK_INSTALL_VARIANT_$(DRIVERKIT)) SDK_INSTALL_VARIANT_1 = driverkit @@ -35,7 +47,7 @@ SDK_INSTALL_HEADERS_ROOT_driverkit = $(SDK_INSTALL_ROOT)/$(SDK_RUNTIME_HEADERS_P SDK_RUNTIME_HEADERS_PREFIX = Runtime BUILD_VARIANTS = $(BUILD_VARIANTS_$(SDK_INSTALL_VARIANT)) -BUILD_VARIANTS_default = normal debug asan +BUILD_VARIANTS_default = normal debug asan $(EXTRA_BUILD_VARIANTS_ASAN_IN_NORMAL_VARIANT) BUILD_VARIANTS_driverkit = normal debug SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator INSTALL_PATH = $(SDK_INSTALL_ROOT)/usr/lib @@ -50,9 +62,22 @@ ORDER_FILE[sdk=iphonesimulator*] = ORDER_FILE[sdk=driverkit*] = SYSTEM_HEADER_SEARCH_PATHS = $(SDKROOT)/$(SDK_INSTALL_HEADERS_ROOT)/System/Library/Frameworks/System.framework/PrivateHeaders $(SDKROOT)/$(SDK_INSTALL_HEADERS_ROOT)/usr/local/include $(SDKROOT)/$(SDK_INSTALL_HEADERS_ROOT)/usr/include SYSTEM_FRAMEWORK_SEARCH_PATHS = $(SDKROOT)/$(SDK_INSTALL_HEADERS_ROOT)/System/Library/PrivateFrameworks $(SDKROOT)/$(SDK_INSTALL_HEADERS_ROOT)/System/Library/Frameworks -OTHER_CFLAGS = -include $(BUILT_PRODUCTS_DIR)/config.$(CURRENT_ARCH).$(CURRENT_VARIANT).h -DCURRENT_VARIANT_$(CURRENT_VARIANT)=1 $(ASAN_IN_NORMAL_VARIANT_CFLAGS) -OTHER_LDFLAGS = -Wl,-search_paths_first -nodefaultlibs @$(BUILT_PRODUCTS_DIR)/linker_arguments.$(CURRENT_ARCH).$(CURRENT_VARIANT).txt $(ASAN_IN_NORMAL_VARIANT_LDFLAGS) $(DRIVERKIT_LDFLAGS) + +OTHER_CFLAGS = -include $(BUILT_PRODUCTS_DIR)/config.$(CURRENT_ARCH).$(CURRENT_VARIANT).h -DCURRENT_VARIANT_$(CURRENT_VARIANT)=1 +OTHER_CFLAGS_normal = $(ASAN_CFLAGS_$(ASAN_IN_NORMAL_VARIANT:default=NO)) +// Preserve existing behaviour of modifying debug variant. +OTHER_CFLAGS_debug = $(ASAN_CFLAGS_$(ASAN_IN_NORMAL_VARIANT:default=NO)) +OTHER_CFLAGS_asan = $(ASAN_CFLAGS_YES) +OTHER_CFLAGS_no_asan = $(NOASAN_CFLAGS_YES) + +OTHER_LDFLAGS = -Wl,-search_paths_first -nodefaultlibs @$(BUILT_PRODUCTS_DIR)/linker_arguments.$(CURRENT_ARCH).$(CURRENT_VARIANT).txt $(DRIVERKIT_LDFLAGS) +OTHER_LDFLAGS_normal = $(ASAN_LDFLAGS_$(ASAN_IN_NORMAL_VARIANT:default=NO)) +// Preserve existing behaviour of modifying debug variant. +OTHER_LDFLAGS_debug = $(ASAN_LDFLAGS_$(ASAN_IN_NORMAL_VARIANT:default=NO)) OTHER_LDFLAGS_asan = $(ASAN_LDFLAGS_YES) +OTHER_LDFLAGS_no_asan = $(NOASAN_LDFLAGS_YES) + + // whitelist of libraries in DriverKit SDK allowed to link directly against libSystem.dylib (outside of the umbrella) DRIVERKIT_LDFLAGS[sdk=driverkit*] = -Wl,-allowable_client,c++ -Wl,-allowable_client,c++abi -Wl,-allowable_client,DriverKit LD_GENERATE_MAP_FILE = YES diff --git a/init.c b/init.c index cdc5130..8e17eb4 100644 --- a/init.c +++ b/init.c @@ -37,6 +37,7 @@ #include #if !TARGET_OS_DRIVERKIT #include +#include #endif #include #include @@ -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 /* - 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. +// 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 /*