#include "<DEVELOPER_DIR>/Makefiles/CoreOS/Xcode/BSD.xcconfig"
-BUILD_VARIANTS = normal debug
+// NO means only libSystem.B_asan.dylib will be ASanified.
+// YES means even the normal variant, libSystem.B.dylib, will be ASanified.
+ASAN_IN_NORMAL_VARIANT = NO
+
+ASAN_CFLAGS_ =
+ASAN_CFLAGS_YES = -DCURRENT_VARIANT_asan=1
+ASAN_LDFLAGS_ =
+SHARED_ASAN_LDFLAGS = -L $(SDKROOT)/usr/local/lib/sanitizers -Xlinker -not_for_dyld_shared_cache -rpath /usr/local/lib/sanitizers/
+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))
+
+BUILD_VARIANTS = normal debug asan
SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator
INSTALL_PATH = /usr/lib
DYLIB_CURRENT_VERSION = $(CURRENT_VERSION_STRING_$(RC_XBS))
ORDER_FILE = $(SDKROOT)/$(APPLE_INTERNAL_DIR)/OrderFiles/libSystem.order
ORDER_FILE[sdk=iphonesimulator*] =
-OTHER_CFLAGS = -include $(BUILT_PRODUCTS_DIR)/config.$(CURRENT_ARCH).$(CURRENT_VARIANT).h
-OTHER_LDFLAGS = -Wl,-search_paths_first -nodefaultlibs @$(BUILT_PRODUCTS_DIR)/linker_arguments.$(CURRENT_ARCH).$(CURRENT_VARIANT).txt
+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)
+OTHER_LDFLAGS_asan = $(ASAN_LDFLAGS_YES)
LD_GENERATE_MAP_FILE = YES
EXECUTABLE_PREFIX = lib
PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/os
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
+ 8C0BF12A1F58E51E00706493 /* enable_asan_mode in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8C0BF1291F58E51D00706493 /* enable_asan_mode */; };
BA2BD900136D282200FF78C0 /* Info.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = BA5511B6136C9D780012B9B5 /* Info.plist */; };
BA2FABC5136DBF45004383E5 /* linker_arguments_changed.c in Sources */ = {isa = PBXBuildFile; fileRef = BA2FABC4136DBF45004383E5 /* linker_arguments_changed.c */; };
BA5511C9136C9E4D0012B9B5 /* CompatibilityHacks.c in Sources */ = {isa = PBXBuildFile; fileRef = BA5511B4136C9D780012B9B5 /* CompatibilityHacks.c */; };
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
+ 8C0BF1281F58E4B400706493 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 8;
+ dstPath = "$(INSTALL_PATH_PREFIX)/usr/local/bin";
+ dstSubfolderSpec = 0;
+ files = (
+ 8C0BF12A1F58E51E00706493 /* enable_asan_mode in CopyFiles */,
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ };
BA2BD8FF136D27FE00FF78C0 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ 8C0BF1291F58E51D00706493 /* enable_asan_mode */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = enable_asan_mode; sourceTree = "<group>"; };
BA2FABC4136DBF45004383E5 /* linker_arguments_changed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = linker_arguments_changed.c; sourceTree = BUILT_PRODUCTS_DIR; };
BA5511B3136C9D780012B9B5 /* APPLE_LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = APPLE_LICENSE; sourceTree = "<group>"; };
BA5511B4136C9D780012B9B5 /* CompatibilityHacks.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = CompatibilityHacks.c; sourceTree = "<group>"; };
BA5511B7136C9D780012B9B5 /* init.c */,
BA5511B9136C9D780012B9B5 /* optionallibs */,
BA5511BA136C9D780012B9B5 /* requiredlibs */,
+ 8C0BF1291F58E51D00706493 /* enable_asan_mode */,
C64EE1D6136F644700676C52 /* xcodescripts */,
BA5511C5136C9E2E0012B9B5 /* Products */,
BA2FABC7136DBF6F004383E5 /* Generated Files */,
BA5511C0136C9E2E0012B9B5 /* Sources */,
BA5511C1136C9E2E0012B9B5 /* Frameworks */,
BA5511C2136C9E2E0012B9B5 /* Headers */,
+ 8C0BF1281F58E4B400706493 /* CopyFiles */,
);
buildRules = (
);
isa = XCBuildConfiguration;
baseConfigurationReference = C9B56C55153751A600C153A8 /* Libsystem.xcconfig */;
buildSettings = {
- BUILD_VARIANTS = (
- normal,
- debug,
- );
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
isa = XCBuildConfiguration;
baseConfigurationReference = C9B56C55153751A600C153A8 /* Libsystem.xcconfig */;
buildSettings = {
- BUILD_VARIANTS = (
- normal,
- debug,
- );
INSTALLHDRS_SCRIPT_PHASE = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
};
--- /dev/null
+#!/bin/bash -e
+
+if [ $# -ne 1 ]; then
+ echo "Usage:" 1>&2
+ echo " sudo $0 enable ... enables ASanification of system libraries on your system" 1>&2
+ echo " sudo $0 disable ... reverts the changes and restores the system back to normal" 1>&2
+ echo " $0 status ... prints current mode" 1>&2
+ exit 1
+fi
+
+if [ "$1" == "enable" ]; then
+ if [[ $(id -u) != 0 ]]; then echo "Must be run as root." 1>&2; exit 1; fi
+
+ if [ -f /usr/lib/libSystem.B.dylib-asan-mode-backup ]; then
+ if [ "`md5 -q /usr/lib/libSystem.B.dylib-asan-mode-backup`" != "`md5 -q /usr/lib/libSystem.B.dylib`" ]; then
+ echo "Looks like your system already has ASan mode enabled, or you have a custom /usr/lib/libSystem.B.dylib file. Not activating." 1>&2
+ exit 1
+ fi
+ fi
+
+ ditto /usr/lib/libSystem.B.dylib /usr/lib/libSystem.B.dylib-asan-mode-backup
+ ditto /usr/lib/libSystem.B_asan.dylib /usr/lib/libSystem.B.dylib
+ echo "ASan mode activated. You probably want to reboot now." 1>&2
+ exit 0
+elif [ "$1" == "disable" ]; then
+ if [[ $(id -u) != 0 ]]; then echo "Must be run as root." 1>&2; exit 1; fi
+ ditto /usr/lib/libSystem.B.dylib-asan-mode-backup /usr/lib/libSystem.B.dylib
+ echo "ASan mode deactivated. You probably want to reboot now." 1>&2
+ exit 0
+elif [ "$1" == "status" ]; then
+ if [ ! -f /usr/lib/libSystem.B.dylib-asan-mode-backup ]; then
+ echo "ASan mode is disabled." 1>&2
+ exit 0
+ fi
+
+ if [ "`md5 -q /usr/lib/libSystem.B.dylib-asan-mode-backup`" == "`md5 -q /usr/lib/libSystem.B.dylib`" ]; then
+ echo "ASan mode is disabled." 1>&2
+ exit 0
+ fi
+
+ if [ "`md5 -q /usr/lib/libSystem.B_asan.dylib`" == "`md5 -q /usr/lib/libSystem.B.dylib`" ]; then
+ echo "ASan mode is enabled." 1>&2
+ exit 0
+ fi
+
+ echo "Cannot tell whether ASan mode is enabled or not. You seem to have a custom /usr/lib/libSystem.B.dylib file." 1>&2
+ exit 1
+else
+ echo "Invalid argument. Run '$0' for usage instructions." 1>&2
+ exit 1
+fi
#include <pthread.h>
#include <pthread/private.h>
#include <dlfcn.h>
+#include <fcntl.h>
#include <errno.h>
#include <_libkernel_init.h> // Must be after voucher_private.h
void libSystem_atfork_parent(void);
void libSystem_atfork_child(void);
+#if CURRENT_VARIANT_asan
+const char *__asan_default_options(void);
+#endif
+
// libsyscall_initializer() initializes all of libSystem.dylib
// <rdar://problem/4892197>
__attribute__((constructor))
__keymgr_initializer();
#endif
+ // No ASan interceptors are invoked before this point. ASan is normally initialized via the malloc interceptor:
+ // _dyld_initializer() -> tlv_load_notification -> wrap_malloc -> ASanInitInternal
+
_dyld_initializer();
libdispatch_init();
_libxpc_initializer();
+#if CURRENT_VARIANT_asan
+ setenv("DT_BYPASS_LEAKS_CHECK", "1", 1);
+#endif
+
// must be initialized after dispatch
_libtrace_init();
_pthread_atfork_child_handlers();
}
+#if CURRENT_VARIANT_asan
+char dynamic_asan_opts[1024] = {0};
+const char *__asan_default_options(void) {
+ int fd = open("/System/Library/Preferences/com.apple.asan.options", O_RDONLY);
+ if (fd != -1) {
+ ssize_t remaining_size = sizeof(dynamic_asan_opts) - 1;
+ char *p = dynamic_asan_opts;
+ ssize_t read_bytes = 0;
+ do {
+ read_bytes = read(fd, p, remaining_size);
+ remaining_size -= read_bytes;
+ } while (read_bytes > 0);
+ close(fd);
+
+ if (dynamic_asan_opts[0]) {
+ return dynamic_asan_opts;
+ }
+ }
+
+ return "color=never:handle_segv=0:handle_sigbus=0:handle_sigill=0:handle_sigfpe=0";
+}
+#endif
+
/*
* Old crt1.o glue used to call through mach_init_routine which was used to initialize libSystem.
* LibSystem now auto-initializes but mach_init_routine is left for binary compatibility.