1 ############################################## 2 ## Perform configuration steps for sanitizers. 3 ############################################## 4 5 my_sanitize := $(strip $(LOCAL_SANITIZE)) 6 7 # SANITIZE_HOST is only in effect if the module is already using clang (host 8 # modules that haven't set `LOCAL_CLANG := false` and device modules that 9 # have set `LOCAL_CLANG := true`. 10 my_global_sanitize := 11 ifeq ($(my_clang),true) 12 ifdef LOCAL_IS_HOST_MODULE 13 my_global_sanitize := $(strip $(SANITIZE_HOST)) 14 15 # SANITIZE_HOST=true is a deprecated way to say SANITIZE_HOST=address. 16 my_global_sanitize := $(subst true,address,$(my_global_sanitize)) 17 else 18 my_global_sanitize := $(strip $(SANITIZE_TARGET)) 19 endif 20 endif 21 22 # The sanitizer specified by the environment wins over the module. 23 ifneq ($(my_global_sanitize),) 24 my_sanitize := $(my_global_sanitize) 25 endif 26 27 # The sanitizer specified in the product configuration wins over the previous. 28 ifneq ($(SANITIZER.$(TARGET_PRODUCT).$(LOCAL_MODULE).CONFIG),) 29 my_sanitize := $(SANITIZER.$(TARGET_PRODUCT).$(LOCAL_MODULE).CONFIG) 30 ifeq ($(my_sanitize),never) 31 my_sanitize := 32 endif 33 endif 34 35 # Add a filter point for 32-bit vs 64-bit sanitization (to lighten the burden). 36 SANITIZE_ARCH ?= 32 64 37 ifeq ($(filter $(SANITIZE_ARCH),$(my_32_64_bit_suffix)),) 38 my_sanitize := 39 endif 40 41 # Add a filter point based on module owner (to lighten the burden). The format is a space- or 42 # colon-separated list of owner names. 43 ifneq (,$(SANITIZE_NEVER_BY_OWNER)) 44 ifneq (,$(LOCAL_MODULE_OWNER)) 45 ifneq (,$(filter $(LOCAL_MODULE_OWNER),$(subst :, ,$(SANITIZE_NEVER_BY_OWNER)))) 46 $(warning Not sanitizing $(LOCAL_MODULE) based on module owner.) 47 my_sanitize := 48 endif 49 endif 50 endif 51 52 # Don't apply sanitizers to NDK code. 53 ifdef LOCAL_SDK_VERSION 54 my_sanitize := 55 endif 56 57 # Never always wins. 58 ifeq ($(LOCAL_SANITIZE),never) 59 my_sanitize := 60 endif 61 62 # TSAN is not supported on 32-bit architectures. For non-multilib cases, make 63 # its use an error. For multilib cases, don't use it for the 32-bit case. 64 ifneq ($(filter thread,$(my_sanitize)),) 65 ifeq ($(my_32_64_bit_suffix),32) 66 ifeq ($(my_module_multilib),both) 67 my_sanitize := $(filter-out thread,$(my_sanitize)) 68 else 69 $(error $(LOCAL_PATH): $(LOCAL_MODULE): TSAN cannot be used for 32-bit modules.) 70 endif 71 endif 72 endif 73 74 # Undefined symbols can occur if a non-sanitized library links 75 # sanitized static libraries. That's OK, because the executable 76 # always depends on the ASan runtime library, which defines these 77 # symbols. 78 ifneq ($(strip $(SANITIZE_TARGET)),) 79 ifndef LOCAL_IS_HOST_MODULE 80 ifeq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES) 81 ifeq ($(my_sanitize),) 82 my_allow_undefined_symbols := true 83 endif 84 endif 85 # Workaround for a bug in AddressSanitizer that breaks stack unwinding. 86 # https://code.google.com/p/address-sanitizer/issues/detail?id=387 87 # Revert when external/compiler-rt is updated past r236014. 88 LOCAL_PACK_MODULE_RELOCATIONS := false 89 endif 90 endif 91 92 # Sanitizers can only be used with clang. 93 ifneq ($(my_clang),true) 94 ifneq ($(my_sanitize),) 95 $(error $(LOCAL_PATH): $(LOCAL_MODULE): Use of sanitizers requires LOCAL_CLANG := true) 96 endif 97 endif 98 99 ifneq ($(filter default-ub,$(my_sanitize)),) 100 my_sanitize := $(CLANG_DEFAULT_UB_CHECKS) 101 endif 102 103 ifneq ($(filter coverage,$(my_sanitize)),) 104 ifeq ($(filter address,$(my_sanitize)),) 105 $(error $(LOCAL_PATH): $(LOCAL_MODULE): Use of 'coverage' also requires 'address') 106 endif 107 my_cflags += -fsanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp 108 my_sanitize := $(filter-out coverage,$(my_sanitize)) 109 endif 110 111 ifneq ($(my_sanitize),) 112 fsanitize_arg := $(subst $(space),$(comma),$(my_sanitize)) 113 my_cflags += -fsanitize=$(fsanitize_arg) 114 115 ifdef LOCAL_IS_HOST_MODULE 116 my_cflags += -fno-sanitize-recover=all 117 my_ldflags += -fsanitize=$(fsanitize_arg) 118 my_ldlibs += -lrt -ldl 119 else 120 ifeq ($(filter address,$(my_sanitize)),) 121 my_cflags += -fsanitize-trap=all 122 my_cflags += -ftrap-function=abort 123 endif 124 my_shared_libraries += libdl 125 endif 126 endif 127 128 ifneq ($(filter address,$(my_sanitize)),) 129 # Frame pointer based unwinder in ASan requires ARM frame setup. 130 LOCAL_ARM_MODE := arm 131 my_cflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS) 132 my_ldflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS) 133 ifdef LOCAL_IS_HOST_MODULE 134 # -nodefaultlibs (provided with libc++) prevents the driver from linking 135 # libraries needed with -fsanitize=address. http://b/18650275 (WAI) 136 my_ldlibs += -lm -lpthread 137 my_ldflags += -Wl,--no-as-needed 138 else 139 my_cflags += -mllvm -asan-globals=0 140 # ASan runtime library must be the first in the link order. 141 my_shared_libraries := $($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_RUNTIME_LIBRARY) \ 142 $(my_shared_libraries) \ 143 $(ADDRESS_SANITIZER_CONFIG_EXTRA_SHARED_LIBRARIES) 144 my_static_libraries += $(ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES) 145 146 my_linker := $($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_LINKER) 147 # Make sure linker_asan get installed. 148 $(LOCAL_INSTALLED_MODULE) : | $(PRODUCT_OUT)$($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_LINKER) 149 endif 150 endif 151 152 ifneq ($(filter undefined,$(my_sanitize)),) 153 ifndef LOCAL_IS_HOST_MODULE 154 $(error ubsan is not yet supported on the target) 155 endif 156 endif 157 158 ifneq ($(strip $(LOCAL_SANITIZE_RECOVER)),) 159 recover_arg := $(subst $(space),$(comma),$(LOCAL_SANITIZE_RECOVER)), 160 my_cflags += -fsanitize-recover=$(recover_arg) 161 endif 162