Home | History | Annotate | Download | only in core
      1 ##############################################
      2 ## Perform configuration steps for sanitizers.
      3 ##############################################
      4 
      5 my_sanitize := $(strip $(LOCAL_SANITIZE))
      6 my_sanitize_diag := $(strip $(LOCAL_SANITIZE_DIAG))
      7 
      8 my_global_sanitize :=
      9 my_global_sanitize_diag :=
     10 ifdef LOCAL_IS_HOST_MODULE
     11   ifneq ($($(my_prefix)OS),windows)
     12     my_global_sanitize := $(strip $(SANITIZE_HOST))
     13 
     14     # SANITIZE_HOST=true is a deprecated way to say SANITIZE_HOST=address.
     15     my_global_sanitize := $(subst true,address,$(my_global_sanitize))
     16   endif
     17 else
     18   my_global_sanitize := $(strip $(SANITIZE_TARGET))
     19   my_global_sanitize_diag := $(strip $(SANITIZE_TARGET_DIAG))
     20 endif
     21 
     22 # Disable global integer_overflow in excluded paths.
     23 ifneq ($(filter integer_overflow, $(my_global_sanitize)),)
     24   combined_exclude_paths := $(INTEGER_OVERFLOW_EXCLUDE_PATHS) \
     25                             $(PRODUCT_INTEGER_OVERFLOW_EXCLUDE_PATHS)
     26 
     27   ifneq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_exclude_paths)),\
     28          $(filter $(dir)%,$(LOCAL_PATH)))),)
     29     my_global_sanitize := $(filter-out integer_overflow,$(my_global_sanitize))
     30     my_global_sanitize_diag := $(filter-out integer_overflow,$(my_global_sanitize_diag))
     31   endif
     32 endif
     33 
     34 # Global integer sanitization doesn't support static modules.
     35 ifeq ($(filter SHARED_LIBRARIES EXECUTABLES,$(LOCAL_MODULE_CLASS)),)
     36   my_global_sanitize := $(filter-out integer_overflow,$(my_global_sanitize))
     37   my_global_sanitize_diag := $(filter-out integer_overflow,$(my_global_sanitize_diag))
     38 endif
     39 ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
     40   my_global_sanitize := $(filter-out integer_overflow,$(my_global_sanitize))
     41   my_global_sanitize_diag := $(filter-out integer_overflow,$(my_global_sanitize_diag))
     42 endif
     43 
     44 # Disable global CFI in excluded paths
     45 ifneq ($(filter cfi, $(my_global_sanitize)),)
     46   combined_exclude_paths := $(CFI_EXCLUDE_PATHS) \
     47                             $(PRODUCT_CFI_EXCLUDE_PATHS)
     48 
     49   ifneq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_exclude_paths)),\
     50          $(filter $(dir)%,$(LOCAL_PATH)))),)
     51     my_global_sanitize := $(filter-out cfi,$(my_global_sanitize))
     52     my_global_sanitize_diag := $(filter-out cfi,$(my_global_sanitize_diag))
     53   endif
     54 endif
     55 
     56 ifneq ($(my_global_sanitize),)
     57   my_sanitize := $(my_global_sanitize) $(my_sanitize)
     58 endif
     59 ifneq ($(my_global_sanitize_diag),)
     60   my_sanitize_diag := $(my_global_sanitize_diag) $(my_sanitize_diag)
     61 endif
     62 
     63 # The sanitizer specified in the product configuration wins over the previous.
     64 ifneq ($(SANITIZER.$(TARGET_PRODUCT).$(LOCAL_MODULE).CONFIG),)
     65   my_sanitize := $(SANITIZER.$(TARGET_PRODUCT).$(LOCAL_MODULE).CONFIG)
     66   ifeq ($(my_sanitize),never)
     67     my_sanitize :=
     68     my_sanitize_diag :=
     69   endif
     70 endif
     71 
     72 ifndef LOCAL_IS_HOST_MODULE
     73   # Add a filter point for 32-bit vs 64-bit sanitization (to lighten the burden)
     74   SANITIZE_TARGET_ARCH ?= $(TARGET_ARCH) $(TARGET_2ND_ARCH)
     75   ifeq ($(filter $(SANITIZE_TARGET_ARCH),$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
     76     my_sanitize :=
     77     my_sanitize_diag :=
     78   endif
     79 endif
     80 
     81 # Add a filter point based on module owner (to lighten the burden). The format is a space- or
     82 # colon-separated list of owner names.
     83 ifneq (,$(SANITIZE_NEVER_BY_OWNER))
     84   ifneq (,$(LOCAL_MODULE_OWNER))
     85     ifneq (,$(filter $(LOCAL_MODULE_OWNER),$(subst :, ,$(SANITIZE_NEVER_BY_OWNER))))
     86       $(warning Not sanitizing $(LOCAL_MODULE) based on module owner.)
     87       my_sanitize :=
     88       my_sanitize_diag :=
     89     endif
     90   endif
     91 endif
     92 
     93 # Don't apply sanitizers to NDK code.
     94 ifdef LOCAL_SDK_VERSION
     95   my_sanitize :=
     96   my_global_sanitize :=
     97   my_sanitize_diag :=
     98 endif
     99 
    100 # Never always wins.
    101 ifeq ($(LOCAL_SANITIZE),never)
    102   my_sanitize :=
    103   my_sanitize_diag :=
    104 endif
    105 
    106 # Enable CFI in included paths (for Arm64 only).
    107 ifeq ($(filter cfi, $(my_sanitize)),)
    108   ifneq ($(filter arm64,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
    109     combined_include_paths := $(CFI_INCLUDE_PATHS) \
    110                               $(PRODUCT_CFI_INCLUDE_PATHS)
    111 
    112     ifneq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_include_paths)),\
    113            $(filter $(dir)%,$(LOCAL_PATH)))),)
    114       my_sanitize := cfi $(my_sanitize)
    115     endif
    116   endif
    117 endif
    118 
    119 # If CFI is disabled globally, remove it from my_sanitize.
    120 ifeq ($(strip $(ENABLE_CFI)),false)
    121   my_sanitize := $(filter-out cfi,$(my_sanitize))
    122   my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
    123 endif
    124 
    125 # Disable CFI for arm32 (b/35157333).
    126 ifneq ($(filter arm,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
    127   my_sanitize := $(filter-out cfi,$(my_sanitize))
    128   my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
    129 endif
    130 
    131 # Also disable CFI if ASAN is enabled.
    132 ifneq ($(filter address,$(my_sanitize)),)
    133   my_sanitize := $(filter-out cfi,$(my_sanitize))
    134   my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
    135 endif
    136 
    137 # CFI needs gold linker, and mips toolchain does not have one.
    138 ifneq ($(filter mips mips64,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
    139   my_sanitize := $(filter-out cfi,$(my_sanitize))
    140   my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
    141 endif
    142 
    143 # Disable sanitizers which need the UBSan runtime for host targets.
    144 ifdef LOCAL_IS_HOST_MODULE
    145   my_sanitize := $(filter-out cfi,$(my_sanitize))
    146   my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
    147   my_sanitize := $(filter-out signed-integer-overflow unsigned-integer-overflow integer_overflow,$(my_sanitize))
    148   my_sanitize_diag := $(filter-out signed-integer-overflow unsigned-integer-overflow integer_overflow,$(my_sanitize_diag))
    149 endif
    150 
    151 # Support for local sanitize blacklist paths.
    152 ifneq ($(my_sanitize)$(my_global_sanitize),)
    153   ifneq ($(LOCAL_SANITIZE_BLACKLIST),)
    154     my_cflags += -fsanitize-blacklist=$(LOCAL_PATH)/$(LOCAL_SANITIZE_BLACKLIST)
    155   endif
    156 endif
    157 
    158 # Disable integer_overflow if LOCAL_NOSANITIZE=integer.
    159 ifneq ($(filter integer_overflow, $(my_global_sanitize) $(my_sanitize)),)
    160   ifneq ($(filter integer, $(strip $(LOCAL_NOSANITIZE))),)
    161     my_sanitize := $(filter-out integer_overflow,$(my_sanitize))
    162     my_sanitize_diag := $(filter-out integer_overflow,$(my_sanitize_diag))
    163   endif
    164 endif
    165 
    166 my_nosanitize = $(strip $(LOCAL_NOSANITIZE))
    167 ifneq ($(my_nosanitize),)
    168   my_sanitize := $(filter-out $(my_nosanitize),$(my_sanitize))
    169 endif
    170 
    171 ifneq ($(filter arm x86 x86_64,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
    172   my_sanitize := $(filter-out hwaddress,$(my_sanitize))
    173 endif
    174 
    175 ifneq ($(filter hwaddress,$(my_sanitize)),)
    176   my_sanitize := $(filter-out address,$(my_sanitize))
    177   my_sanitize := $(filter-out thread,$(my_sanitize))
    178   my_sanitize := $(filter-out cfi,$(my_sanitize))
    179 endif
    180 
    181 ifneq ($(filter hwaddress,$(my_sanitize)),)
    182   my_shared_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)HWADDRESS_SANITIZER_RUNTIME_LIBRARY)
    183   ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
    184     ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
    185       my_static_libraries := $(my_static_libraries) $($(LOCAL_2ND_ARCH_VAR_PREFIX)HWADDRESS_SANITIZER_STATIC_LIBRARY)
    186     endif
    187   endif
    188 endif
    189 
    190 # TSAN is not supported on 32-bit architectures. For non-multilib cases, make
    191 # its use an error. For multilib cases, don't use it for the 32-bit case.
    192 ifneq ($(filter thread,$(my_sanitize)),)
    193   ifeq ($(my_32_64_bit_suffix),32)
    194     ifeq ($(my_module_multilib),both)
    195         my_sanitize := $(filter-out thread,$(my_sanitize))
    196     else
    197         $(error $(LOCAL_PATH): $(LOCAL_MODULE): TSAN cannot be used for 32-bit modules.)
    198     endif
    199   else
    200     my_shared_libraries += $(TSAN_RUNTIME_LIBRARY)
    201   endif
    202 endif
    203 
    204 ifneq ($(filter safe-stack,$(my_sanitize)),)
    205   ifeq ($(my_32_64_bit_suffix),32)
    206     my_sanitize := $(filter-out safe-stack,$(my_sanitize))
    207   endif
    208 endif
    209 
    210 # Disable Scudo if ASan or TSan is enabled.
    211 ifneq ($(filter address thread hwaddress,$(my_sanitize)),)
    212   my_sanitize := $(filter-out scudo,$(my_sanitize))
    213 endif
    214 
    215 # Or if disabled globally.
    216 ifeq ($(PRODUCT_DISABLE_SCUDO),true)
    217   my_sanitize := $(filter-out scudo,$(my_sanitize))
    218 endif
    219 
    220 # Undefined symbols can occur if a non-sanitized library links
    221 # sanitized static libraries. That's OK, because the executable
    222 # always depends on the ASan runtime library, which defines these
    223 # symbols.
    224 ifneq ($(filter address thread,$(strip $(SANITIZE_TARGET))),)
    225   ifndef LOCAL_IS_HOST_MODULE
    226     ifeq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES)
    227       ifeq ($(my_sanitize),)
    228         my_allow_undefined_symbols := true
    229       endif
    230     endif
    231   endif
    232 endif
    233 
    234 ifneq ($(filter default-ub,$(my_sanitize)),)
    235   my_sanitize := $(CLANG_DEFAULT_UB_CHECKS)
    236 endif
    237 
    238 ifneq ($(filter coverage,$(my_sanitize)),)
    239   ifeq ($(filter address,$(my_sanitize)),)
    240     $(error $(LOCAL_PATH): $(LOCAL_MODULE): Use of 'coverage' also requires 'address')
    241   endif
    242   my_cflags += -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp
    243   my_sanitize := $(filter-out coverage,$(my_sanitize))
    244 endif
    245 
    246 ifneq ($(filter integer_overflow,$(my_sanitize)),)
    247   # Respect LOCAL_NOSANITIZE for integer-overflow flags.
    248   ifeq ($(filter signed-integer-overflow, $(strip $(LOCAL_NOSANITIZE))),)
    249     my_sanitize += signed-integer-overflow
    250   endif
    251   ifeq ($(filter unsigned-integer-overflow, $(strip $(LOCAL_NOSANITIZE))),)
    252     my_sanitize += unsigned-integer-overflow
    253   endif
    254   my_cflags += $(INTEGER_OVERFLOW_EXTRA_CFLAGS)
    255 
    256   # Check for diagnostics mode.
    257   ifneq ($(filter integer_overflow,$(my_sanitize_diag)),)
    258     ifneq ($(filter SHARED_LIBRARIES EXECUTABLES,$(LOCAL_MODULE_CLASS)),)
    259       ifneq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
    260         my_sanitize_diag += signed-integer-overflow
    261         my_sanitize_diag += unsigned-integer-overflow
    262       else
    263         $(call pretty-error,Make cannot apply integer overflow diagnostics to static binary.)
    264       endif
    265     else
    266       $(call pretty-error,Make cannot apply integer overflow diagnostics to static library.)
    267     endif
    268   endif
    269   my_sanitize := $(filter-out integer_overflow,$(my_sanitize))
    270 endif
    271 
    272 # Makes sure integer_overflow diagnostics is removed from the diagnostics list
    273 # even if integer_overflow is not set for some reason.
    274 ifneq ($(filter integer_overflow,$(my_sanitize_diag)),)
    275   my_sanitize_diag := $(filter-out integer_overflow,$(my_sanitize_diag))
    276 endif
    277 
    278 ifneq ($(my_sanitize),)
    279   fsanitize_arg := $(subst $(space),$(comma),$(my_sanitize))
    280   my_cflags += -fsanitize=$(fsanitize_arg)
    281   my_asflags += -fsanitize=$(fsanitize_arg)
    282 
    283   ifdef LOCAL_IS_HOST_MODULE
    284     my_cflags += -fno-sanitize-recover=all
    285     my_ldflags += -fsanitize=$(fsanitize_arg)
    286   else
    287     my_cflags += -fsanitize-trap=all
    288     my_cflags += -ftrap-function=abort
    289     ifneq ($(filter address thread,$(my_sanitize)),)
    290       my_cflags += -fno-sanitize-trap=address,thread
    291       my_shared_libraries += libdl
    292     endif
    293   endif
    294 endif
    295 
    296 ifneq ($(filter cfi,$(my_sanitize)),)
    297   # __cfi_check needs to be built as Thumb (see the code in linker_cfi.cpp).
    298   # LLVM is not set up to do this on a function basis, so force Thumb on the
    299   # entire module.
    300   LOCAL_ARM_MODE := thumb
    301   my_cflags += $(CFI_EXTRA_CFLAGS)
    302   my_asflags += $(CFI_EXTRA_ASFLAGS)
    303   # Only append the default visibility flag if -fvisibility has not already been
    304   # set to hidden.
    305   ifeq ($(filter -fvisibility=hidden,$(LOCAL_CFLAGS)),)
    306     my_cflags += -fvisibility=default
    307   endif
    308   my_ldflags += $(CFI_EXTRA_LDFLAGS)
    309   my_arflags += --plugin $(LLVM_PREBUILTS_PATH)/../lib64/LLVMgold.so
    310 
    311   ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
    312         my_ldflags := $(filter-out -fsanitize-cfi-cross-dso,$(my_ldflags))
    313         my_cflags := $(filter-out -fsanitize-cfi-cross-dso,$(my_cflags))
    314   else
    315         # Apply the version script to non-static executables
    316         my_ldflags += -Wl,--version-script,build/soong/cc/config/cfi_exports.map
    317         LOCAL_ADDITIONAL_DEPENDENCIES += build/soong/cc/config/cfi_exports.map
    318   endif
    319 endif
    320 
    321 # If local or global modules need ASAN, add linker flags.
    322 ifneq ($(filter address,$(my_global_sanitize) $(my_sanitize)),)
    323   my_ldflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS)
    324   ifdef LOCAL_IS_HOST_MODULE
    325     # -nodefaultlibs (provided with libc++) prevents the driver from linking
    326     # libraries needed with -fsanitize=address. http://b/18650275 (WAI)
    327     my_ldflags += -Wl,--no-as-needed
    328   else
    329     # Add asan libraries unless LOCAL_MODULE is the asan library.
    330     # ASan runtime library must be the first in the link order.
    331     ifeq (,$(filter $(LOCAL_MODULE),$($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_RUNTIME_LIBRARY)))
    332       my_shared_libraries := $($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_RUNTIME_LIBRARY) \
    333                              $(my_shared_libraries)
    334     endif
    335     ifeq (,$(filter $(LOCAL_MODULE),$(ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES)))
    336       my_static_libraries += $(ADDRESS_SANITIZER_CONFIG_EXTRA_STATIC_LIBRARIES)
    337     endif
    338 
    339     # Do not add unnecessary dependency in shared libraries.
    340     ifeq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES)
    341       my_ldflags += -Wl,--as-needed
    342     endif
    343 
    344     ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
    345       ifneq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
    346         my_linker := $($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_LINKER)
    347         # Make sure linker_asan get installed.
    348         $(LOCAL_INSTALLED_MODULE) : | $(PRODUCT_OUT)$($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_LINKER_FILE)
    349       endif
    350     endif
    351   endif
    352 endif
    353 
    354 # If local module needs ASAN, add compiler flags.
    355 ifneq ($(filter address,$(my_sanitize)),)
    356   # Frame pointer based unwinder in ASan requires ARM frame setup.
    357   LOCAL_ARM_MODE := arm
    358   my_cflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS)
    359   ifndef LOCAL_IS_HOST_MODULE
    360     my_cflags += -mllvm -asan-globals=0
    361   endif
    362 endif
    363 
    364 # If local module needs HWASAN, add compiler flags.
    365 ifneq ($(filter hwaddress,$(my_sanitize)),)
    366   my_cflags += $(HWADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS)
    367 endif
    368 
    369 # Use minimal diagnostics when integer overflow is enabled; never do it for HOST or AUX modules
    370 ifeq ($(LOCAL_IS_HOST_MODULE)$(LOCAL_IS_AUX_MODULE),)
    371   # Pre-emptively add UBSAN minimal runtime incase a static library dependency requires it
    372   ifeq ($(filter STATIC_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
    373     ifndef LOCAL_SDK_VERSION
    374       my_static_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)UBSAN_MINIMAL_RUNTIME_LIBRARY)
    375       my_ldflags += -Wl,--exclude-libs,$($(LOCAL_2ND_ARCH_VAR_PREFIX)UBSAN_MINIMAL_RUNTIME_LIBRARY).a
    376     endif
    377   endif
    378   ifneq ($(filter unsigned-integer-overflow signed-integer-overflow integer,$(my_sanitize)),)
    379     ifeq ($(filter unsigned-integer-overflow signed-integer-overflow integer,$(my_sanitize_diag)),)
    380       ifeq ($(filter cfi,$(my_sanitize_diag)),)
    381         ifeq ($(filter address hwaddress,$(my_sanitize)),)
    382           my_cflags += -fsanitize-minimal-runtime
    383           my_cflags += -fno-sanitize-trap=integer
    384           my_cflags += -fno-sanitize-recover=integer
    385         endif
    386       endif
    387     endif
    388   endif
    389 endif
    390 
    391 # For Scudo, we opt for the minimal runtime, unless some diagnostics are enabled.
    392 ifneq ($(filter scudo,$(my_sanitize)),)
    393   ifeq ($(filter unsigned-integer-overflow signed-integer-overflow integer cfi,$(my_sanitize_diag)),)
    394     my_cflags += -fsanitize-minimal-runtime
    395   endif
    396   ifneq ($(filter -fsanitize-minimal-runtime,$(my_cflags)),)
    397     my_shared_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)SCUDO_MINIMAL_RUNTIME_LIBRARY)
    398   else
    399     my_shared_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)SCUDO_RUNTIME_LIBRARY)
    400   endif
    401 endif
    402 
    403 ifneq ($(strip $(LOCAL_SANITIZE_RECOVER)),)
    404   recover_arg := $(subst $(space),$(comma),$(LOCAL_SANITIZE_RECOVER)),
    405   my_cflags += -fsanitize-recover=$(recover_arg)
    406 endif
    407 
    408 ifneq ($(strip $(LOCAL_SANITIZE_NO_RECOVER)),)
    409   no_recover_arg := $(subst $(space),$(comma),$(LOCAL_SANITIZE_NO_RECOVER)),
    410   my_cflags += -fno-sanitize-recover=$(no_recover_arg)
    411 endif
    412 
    413 ifneq ($(my_sanitize_diag),)
    414   # TODO(vishwath): Add diagnostic support for static executables once
    415   # we switch to clang-4393122 (which adds the static ubsan runtime
    416   # that this depends on)
    417   ifneq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
    418     notrap_arg := $(subst $(space),$(comma),$(my_sanitize_diag)),
    419     my_cflags += -fno-sanitize-trap=$(notrap_arg)
    420     # Diagnostic requires a runtime library, unless ASan or TSan are also enabled.
    421     ifeq ($(filter address thread scudo hwaddress,$(my_sanitize)),)
    422       # Does not have to be the first DT_NEEDED unlike ASan.
    423       my_shared_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)UBSAN_RUNTIME_LIBRARY)
    424     endif
    425   endif
    426 endif
    427 
    428 # http://b/119329758, Android core does not boot up with this sanitizer yet.
    429 # Previously sanitized modules might not pass new implicit-integer-sign-change check.
    430 # Disable this check unless it has been explicitly specified.
    431 ifneq ($(findstring fsanitize,$(my_cflags)),)
    432   ifneq ($(findstring integer,$(my_cflags)),)
    433     ifeq ($(findstring sanitize=implicit-integer-sign-change,$(my_cflags)),)
    434       my_cflags += -fno-sanitize=implicit-integer-sign-change
    435     endif
    436   endif
    437 endif
    438