1##############################################
2## Perform configuration steps for sanitizers.
3##############################################
4
5my_sanitize := $(strip $(LOCAL_SANITIZE))
6my_sanitize_diag := $(strip $(LOCAL_SANITIZE_DIAG))
7
8my_global_sanitize :=
9my_global_sanitize_diag :=
10ifdef 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
17else
18  my_global_sanitize := $(strip $(SANITIZE_TARGET))
19  my_global_sanitize_diag := $(strip $(SANITIZE_TARGET_DIAG))
20endif
21
22# Disable global integer_overflow in excluded paths.
23ifneq ($(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
32endif
33
34# Global integer sanitization doesn't support static modules.
35ifeq ($(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))
38endif
39ifeq ($(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))
42endif
43
44# Disable global CFI in excluded paths
45ifneq ($(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
54endif
55
56# Disable global memtag_heap in excluded paths
57ifneq ($(filter memtag_heap, $(my_global_sanitize)),)
58  combined_exclude_paths := $(MEMTAG_HEAP_EXCLUDE_PATHS) \
59                            $(PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS)
60
61  ifneq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_exclude_paths)),\
62         $(filter $(dir)%,$(LOCAL_PATH)))),)
63    my_global_sanitize := $(filter-out memtag_heap,$(my_global_sanitize))
64    my_global_sanitize_diag := $(filter-out memtag_heap,$(my_global_sanitize_diag))
65  endif
66endif
67
68# Disable global HWASan in excluded paths
69ifneq ($(filter hwaddress, $(my_global_sanitize)),)
70  combined_exclude_paths := $(HWASAN_EXCLUDE_PATHS) \
71                            $(PRODUCT_HWASAN_EXCLUDE_PATHS)
72
73  ifneq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_exclude_paths)),\
74         $(filter $(dir)%,$(LOCAL_PATH)))),)
75    my_global_sanitize := $(filter-out hwaddress,$(my_global_sanitize))
76    my_global_sanitize_diag := $(filter-out hwaddress,$(my_global_sanitize_diag))
77  endif
78endif
79
80ifneq ($(my_global_sanitize),)
81  my_sanitize := $(my_global_sanitize) $(my_sanitize)
82endif
83ifneq ($(my_global_sanitize_diag),)
84  my_sanitize_diag := $(my_global_sanitize_diag) $(my_sanitize_diag)
85endif
86
87# The sanitizer specified in the product configuration wins over the previous.
88ifneq ($(SANITIZER.$(TARGET_PRODUCT).$(LOCAL_MODULE).CONFIG),)
89  my_sanitize := $(SANITIZER.$(TARGET_PRODUCT).$(LOCAL_MODULE).CONFIG)
90  ifeq ($(my_sanitize),never)
91    my_sanitize :=
92    my_sanitize_diag :=
93  endif
94endif
95
96ifndef LOCAL_IS_HOST_MODULE
97  # Add a filter point for 32-bit vs 64-bit sanitization (to lighten the burden)
98  SANITIZE_TARGET_ARCH ?= $(TARGET_ARCH) $(TARGET_2ND_ARCH)
99  ifeq ($(filter $(SANITIZE_TARGET_ARCH),$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
100    my_sanitize :=
101    my_sanitize_diag :=
102  endif
103endif
104
105# Add a filter point based on module owner (to lighten the burden). The format is a space- or
106# colon-separated list of owner names.
107ifneq (,$(SANITIZE_NEVER_BY_OWNER))
108  ifneq (,$(LOCAL_MODULE_OWNER))
109    ifneq (,$(filter $(LOCAL_MODULE_OWNER),$(subst :, ,$(SANITIZE_NEVER_BY_OWNER))))
110      $(warning Not sanitizing $(LOCAL_MODULE) based on module owner.)
111      my_sanitize :=
112      my_sanitize_diag :=
113    endif
114  endif
115endif
116
117# Don't apply sanitizers to NDK code.
118ifdef LOCAL_SDK_VERSION
119  my_sanitize :=
120  my_global_sanitize :=
121  my_sanitize_diag :=
122endif
123
124# Never always wins.
125ifeq ($(LOCAL_SANITIZE),never)
126  my_sanitize :=
127  my_sanitize_diag :=
128endif
129
130# Enable CFI in included paths.
131ifeq ($(filter cfi, $(my_sanitize)),)
132  combined_include_paths := $(CFI_INCLUDE_PATHS) \
133                            $(PRODUCT_CFI_INCLUDE_PATHS)
134  combined_exclude_paths := $(CFI_EXCLUDE_PATHS) \
135                            $(PRODUCT_CFI_EXCLUDE_PATHS)
136
137  ifneq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_include_paths)),\
138         $(filter $(dir)%,$(LOCAL_PATH)))),)
139    ifeq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_exclude_paths)),\
140         $(filter $(dir)%,$(LOCAL_PATH)))),)
141      my_sanitize := cfi $(my_sanitize)
142    endif
143  endif
144endif
145
146# Enable memtag_heap in included paths (for Arm64 only).
147ifeq ($(filter memtag_heap, $(my_sanitize)),)
148  ifneq ($(filter arm64,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
149    combined_sync_include_paths := $(MEMTAG_HEAP_SYNC_INCLUDE_PATHS) \
150                                   $(PRODUCT_MEMTAG_HEAP_SYNC_INCLUDE_PATHS)
151    combined_async_include_paths := $(MEMTAG_HEAP_ASYNC_INCLUDE_PATHS) \
152                                    $(PRODUCT_MEMTAG_HEAP_ASYNC_INCLUDE_PATHS)
153    combined_exclude_paths := $(MEMTAG_HEAP_EXCLUDE_PATHS) \
154                              $(PRODUCT_MEMTAG_HEAP_EXCLUDE_PATHS)
155    ifneq ($(PRODUCT_MEMTAG_HEAP_SKIP_DEFAULT_PATHS),true)
156      combined_sync_include_paths += $(PRODUCT_MEMTAG_HEAP_SYNC_DEFAULT_INCLUDE_PATHS)
157      combined_async_include_paths += $(PRODUCT_MEMTAG_HEAP_ASYNC_DEFAULT_INCLUDE_PATHS)
158    endif
159
160    ifeq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_exclude_paths)),\
161          $(filter $(dir)%,$(LOCAL_PATH)))),)
162      ifneq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_sync_include_paths)),\
163             $(filter $(dir)%,$(LOCAL_PATH)))),)
164        my_sanitize := memtag_heap $(my_sanitize)
165        my_sanitize_diag := memtag_heap $(my_sanitize_diag)
166      else ifneq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_async_include_paths)),\
167             $(filter $(dir)%,$(LOCAL_PATH)))),)
168        my_sanitize := memtag_heap $(my_sanitize)
169      endif
170    endif
171  endif
172endif
173
174# Enable HWASan in included paths.
175ifeq ($(filter hwaddress, $(my_sanitize)),)
176  combined_include_paths := $(HWASAN_INCLUDE_PATHS) \
177                            $(PRODUCT_HWASAN_INCLUDE_PATHS)
178
179  ifneq ($(strip $(foreach dir,$(subst $(comma),$(space),$(combined_include_paths)),\
180         $(filter $(dir)%,$(LOCAL_PATH)))),)
181    my_sanitize := hwaddress $(my_sanitize)
182  endif
183endif
184
185# If CFI is disabled globally, remove it from my_sanitize.
186ifeq ($(strip $(ENABLE_CFI)),false)
187  my_sanitize := $(filter-out cfi,$(my_sanitize))
188  my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
189endif
190
191# Also disable CFI and MTE if ASAN is enabled.
192ifneq ($(filter address,$(my_sanitize)),)
193  my_sanitize := $(filter-out cfi,$(my_sanitize))
194  my_sanitize := $(filter-out memtag_stack,$(my_sanitize))
195  my_sanitize := $(filter-out memtag_globals,$(my_sanitize))
196  my_sanitize := $(filter-out memtag_heap,$(my_sanitize))
197  my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
198endif
199
200# Disable memtag for host targets. Host executables in AndroidMk files are
201# deprecated, but some partners still have them floating around.
202ifdef LOCAL_IS_HOST_MODULE
203  my_sanitize := $(filter-out memtag_heap memtag_stack memtag_globals,$(my_sanitize))
204  my_sanitize_diag := $(filter-out memtag_heap memtag_stack memtag_globals,$(my_sanitize_diag))
205endif
206
207# Disable sanitizers which need the UBSan runtime for host targets.
208ifdef LOCAL_IS_HOST_MODULE
209  my_sanitize := $(filter-out cfi,$(my_sanitize))
210  my_sanitize_diag := $(filter-out cfi,$(my_sanitize_diag))
211  my_sanitize := $(filter-out signed-integer-overflow unsigned-integer-overflow integer_overflow,$(my_sanitize))
212  my_sanitize_diag := $(filter-out signed-integer-overflow unsigned-integer-overflow integer_overflow,$(my_sanitize_diag))
213endif
214
215# Support for local sanitize blacklist paths.
216ifneq ($(my_sanitize)$(my_global_sanitize),)
217  ifneq ($(LOCAL_SANITIZE_BLOCKLIST),)
218    my_cflags += -fsanitize-blacklist=$(LOCAL_PATH)/$(LOCAL_SANITIZE_BLOCKLIST)
219  endif
220endif
221
222# Disable integer_overflow if LOCAL_NOSANITIZE=integer.
223ifneq ($(filter integer_overflow, $(my_global_sanitize) $(my_sanitize)),)
224  ifneq ($(filter integer, $(strip $(LOCAL_NOSANITIZE))),)
225    my_sanitize := $(filter-out integer_overflow,$(my_sanitize))
226    my_sanitize_diag := $(filter-out integer_overflow,$(my_sanitize_diag))
227  endif
228endif
229
230my_nosanitize = $(strip $(LOCAL_NOSANITIZE))
231ifneq ($(my_nosanitize),)
232  my_sanitize := $(filter-out $(my_nosanitize),$(my_sanitize))
233endif
234
235ifneq ($(filter arm x86 x86_64,$(TARGET_$(LOCAL_2ND_ARCH_VAR_PREFIX)ARCH)),)
236  my_sanitize := $(filter-out hwaddress,$(my_sanitize))
237  my_sanitize := $(filter-out memtag_heap,$(my_sanitize))
238  my_sanitize := $(filter-out memtag_stack,$(my_sanitize))
239  my_sanitize := $(filter-out memtag_globals,$(my_sanitize))
240endif
241
242ifneq ($(filter hwaddress,$(my_sanitize)),)
243  my_sanitize := $(filter-out address,$(my_sanitize))
244  my_sanitize := $(filter-out memtag_stack,$(my_sanitize))
245  my_sanitize := $(filter-out memtag_globals,$(my_sanitize))
246  my_sanitize := $(filter-out memtag_heap,$(my_sanitize))
247  my_sanitize := $(filter-out thread,$(my_sanitize))
248  my_sanitize := $(filter-out cfi,$(my_sanitize))
249endif
250
251ifneq ($(filter hwaddress,$(my_sanitize)),)
252  my_shared_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)HWADDRESS_SANITIZER_RUNTIME_LIBRARY)
253  ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
254    ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
255      my_static_libraries := $(my_static_libraries) \
256                             $($(LOCAL_2ND_ARCH_VAR_PREFIX)HWADDRESS_SANITIZER_STATIC_LIBRARY) \
257                             libdl
258    endif
259  endif
260endif
261
262ifneq ($(filter memtag_heap memtag_stack memtag_globals,$(my_sanitize)),)
263  ifneq ($(filter memtag_heap,$(my_sanitize_diag)),)
264    my_ldflags += -fsanitize-memtag-mode=sync
265    my_sanitize_diag := $(filter-out memtag_heap,$(my_sanitize_diag))
266  else
267    my_ldflags += -fsanitize-memtag-mode=async
268  endif
269endif
270
271# Ignore SANITIZE_TARGET_DIAG=memtag_heap without SANITIZE_TARGET=memtag_heap
272# This can happen if a condition above filters out memtag_heap from
273# my_sanitize. It is easier to handle all of these cases here centrally.
274ifneq ($(filter memtag_heap,$(my_sanitize_diag)),)
275  my_sanitize_diag := $(filter-out memtag_heap,$(my_sanitize_diag))
276endif
277
278ifneq ($(filter memtag_heap,$(my_sanitize)),)
279  my_cflags += -fsanitize=memtag-heap
280  my_ldflags += -fsanitize=memtag-heap
281  my_sanitize := $(filter-out memtag_heap,$(my_sanitize))
282endif
283
284ifneq ($(filter memtag_stack,$(my_sanitize)),)
285  my_cflags += -fsanitize=memtag-stack
286  my_ldflags += -fsanitize=memtag-stack
287  my_cflags += -march=armv8a+memtag
288  my_ldflags += -march=armv8a+memtag
289  my_asflags += -march=armv8a+memtag
290  my_sanitize := $(filter-out memtag_stack,$(my_sanitize))
291endif
292
293ifneq ($(filter memtag_globals,$(my_sanitize)),)
294  my_cflags += -fsanitize=memtag-globals
295  my_ldflags += -fsanitize=memtag-globals
296  # TODO(mitchp): For now, enable memtag-heap with memtag-globals because the
297  # linker isn't new enough
298  # (https://reviews.llvm.org/differential/changeset/?ref=4243566).
299  my_sanitize := $(filter-out memtag_globals,$(my_sanitize))
300endif
301
302# TSAN is not supported on 32-bit architectures. For non-multilib cases, make
303# its use an error. For multilib cases, don't use it for the 32-bit case.
304ifneq ($(filter thread,$(my_sanitize)),)
305  ifeq ($(my_32_64_bit_suffix),32)
306    ifeq ($(my_module_multilib),both)
307        my_sanitize := $(filter-out thread,$(my_sanitize))
308    else
309        $(error $(LOCAL_PATH): $(LOCAL_MODULE): TSAN cannot be used for 32-bit modules.)
310    endif
311  else
312    my_shared_libraries += $(TSAN_RUNTIME_LIBRARY)
313  endif
314endif
315
316ifneq ($(filter safe-stack,$(my_sanitize)),)
317  ifeq ($(my_32_64_bit_suffix),32)
318    my_sanitize := $(filter-out safe-stack,$(my_sanitize))
319  endif
320endif
321
322# Disable Scudo if ASan or TSan is enabled.
323ifneq ($(filter address thread hwaddress,$(my_sanitize)),)
324  my_sanitize := $(filter-out scudo,$(my_sanitize))
325endif
326
327# Or if disabled globally.
328ifeq ($(PRODUCT_DISABLE_SCUDO),true)
329  my_sanitize := $(filter-out scudo,$(my_sanitize))
330endif
331
332# Undefined symbols can occur if a non-sanitized library links
333# sanitized static libraries. That's OK, because the executable
334# always depends on the ASan runtime library, which defines these
335# symbols.
336ifneq ($(filter address thread,$(strip $(SANITIZE_TARGET))),)
337  ifndef LOCAL_IS_HOST_MODULE
338    ifeq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES)
339      ifeq ($(my_sanitize),)
340        my_allow_undefined_symbols := true
341      endif
342    endif
343  endif
344endif
345
346ifneq ($(filter default-ub,$(my_sanitize)),)
347  my_sanitize := $(CLANG_DEFAULT_UB_CHECKS)
348endif
349
350ifneq ($(filter fuzzer,$(my_sanitize)),)
351  # SANITIZE_TARGET='fuzzer' actually means to create the fuzzer coverage
352  # information, not to link against the fuzzer main().
353  my_sanitize := $(filter-out fuzzer,$(my_sanitize))
354  my_sanitize += fuzzer-no-link
355
356  # TODO(b/131771163): Disable LTO for fuzzer builds. Note that Cfi causes
357  # dependency on LTO.
358  my_sanitize := $(filter-out cfi,$(my_sanitize))
359  my_cflags += -fno-lto
360  my_ldflags += -fno-lto
361
362  # TODO(b/142430592): Upstream linker scripts for sanitizer runtime libraries
363  # discard the sancov_lowest_stack symbol, because it's emulated TLS (and thus
364  # doesn't match the linker script due to the "__emutls_v." prefix).
365  my_cflags += -fno-sanitize-coverage=stack-depth
366  my_ldflags += -fno-sanitize-coverage=stack-depth
367endif
368
369ifneq ($(filter integer_overflow,$(my_sanitize)),)
370  # Respect LOCAL_NOSANITIZE for integer-overflow flags.
371  ifeq ($(filter signed-integer-overflow, $(strip $(LOCAL_NOSANITIZE))),)
372    my_sanitize += signed-integer-overflow
373  endif
374  ifeq ($(filter unsigned-integer-overflow, $(strip $(LOCAL_NOSANITIZE))),)
375    my_sanitize += unsigned-integer-overflow
376  endif
377  my_cflags += $(INTEGER_OVERFLOW_EXTRA_CFLAGS)
378
379  # Check for diagnostics mode.
380  ifneq ($(filter integer_overflow,$(my_sanitize_diag)),)
381    ifneq ($(filter SHARED_LIBRARIES EXECUTABLES,$(LOCAL_MODULE_CLASS)),)
382      ifneq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
383        my_sanitize_diag += signed-integer-overflow
384        my_sanitize_diag += unsigned-integer-overflow
385      else
386        $(call pretty-error,Make cannot apply integer overflow diagnostics to static binary.)
387      endif
388    else
389      $(call pretty-error,Make cannot apply integer overflow diagnostics to static library.)
390    endif
391  endif
392  my_sanitize := $(filter-out integer_overflow,$(my_sanitize))
393endif
394
395# Makes sure integer_overflow diagnostics is removed from the diagnostics list
396# even if integer_overflow is not set for some reason.
397ifneq ($(filter integer_overflow,$(my_sanitize_diag)),)
398  my_sanitize_diag := $(filter-out integer_overflow,$(my_sanitize_diag))
399endif
400
401ifneq ($(my_sanitize),)
402  fsanitize_arg := $(subst $(space),$(comma),$(my_sanitize))
403  my_cflags += -fsanitize=$(fsanitize_arg)
404  my_asflags += -fsanitize=$(fsanitize_arg)
405
406  # When fuzzing, we wish to crash with diagnostics on any bug.
407  ifneq ($(filter fuzzer-no-link,$(my_sanitize)),)
408    my_cflags += -fno-sanitize-trap=all
409    my_cflags += -fno-sanitize-recover=all
410    my_ldflags += -fsanitize=fuzzer-no-link
411  else ifdef LOCAL_IS_HOST_MODULE
412    my_cflags += -fno-sanitize-recover=all
413    my_ldflags += -fsanitize=$(fsanitize_arg)
414  else
415    my_cflags += -fsanitize-trap=all
416    ifneq ($(filter address thread,$(my_sanitize)),)
417      my_cflags += -fno-sanitize-trap=address,thread
418      my_shared_libraries += libdl
419    endif
420  endif
421endif
422
423ifneq ($(filter cfi,$(my_sanitize)),)
424  # __cfi_check needs to be built as Thumb (see the code in linker_cfi.cpp).
425  # LLVM is not set up to do this on a function basis, so force Thumb on the
426  # entire module.
427  LOCAL_ARM_MODE := thumb
428  my_cflags += $(CFI_EXTRA_CFLAGS)
429  my_asflags += $(CFI_EXTRA_ASFLAGS)
430  # Only append the default visibility flag if -fvisibility has not already been
431  # set to hidden.
432  ifeq ($(filter -fvisibility=hidden,$(LOCAL_CFLAGS)),)
433    my_cflags += -fvisibility=default
434  endif
435  my_ldflags += $(CFI_EXTRA_LDFLAGS)
436
437  ifeq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
438        my_ldflags := $(filter-out -fsanitize-cfi-cross-dso,$(my_ldflags))
439        my_cflags := $(filter-out -fsanitize-cfi-cross-dso,$(my_cflags))
440  else
441        # Apply the version script to non-static executables
442        my_ldflags += -Wl,--version-script,build/soong/cc/config/cfi_exports.map
443        LOCAL_ADDITIONAL_DEPENDENCIES += build/soong/cc/config/cfi_exports.map
444  endif
445endif
446
447# If local or global modules need ASAN, add linker flags.
448ifneq ($(filter address,$(my_global_sanitize) $(my_sanitize)),)
449  my_ldflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS)
450  ifdef LOCAL_IS_HOST_MODULE
451    # -nodefaultlibs (provided with libc++) prevents the driver from linking
452    # libraries needed with -fsanitize=address. http://b/18650275 (WAI)
453    my_ldflags += -Wl,--no-as-needed
454  else
455    # Add asan libraries unless LOCAL_MODULE is the asan library.
456    # ASan runtime library must be the first in the link order.
457    ifeq (,$(filter $(LOCAL_MODULE),$($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_RUNTIME_LIBRARY)))
458      my_shared_libraries := $($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_RUNTIME_LIBRARY) \
459                             $(my_shared_libraries)
460    endif
461
462    # Do not add unnecessary dependency in shared libraries.
463    ifeq ($(LOCAL_MODULE_CLASS),SHARED_LIBRARIES)
464      my_ldflags += -Wl,--as-needed
465    endif
466
467    ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
468      ifneq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
469        my_linker := $($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_LINKER)
470        # Make sure linker_asan get installed.
471        $(LOCAL_INSTALLED_MODULE) : | $(PRODUCT_OUT)$($(LOCAL_2ND_ARCH_VAR_PREFIX)ADDRESS_SANITIZER_LINKER_FILE)
472      endif
473    endif
474  endif
475endif
476
477# If local module needs ASAN, add compiler flags.
478ifneq ($(filter address,$(my_sanitize)),)
479  # Frame pointer based unwinder in ASan requires ARM frame setup.
480  LOCAL_ARM_MODE := arm
481  my_cflags += $(ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS)
482  ifndef LOCAL_IS_HOST_MODULE
483    my_cflags += -mllvm -asan-globals=0
484  endif
485endif
486
487# If local module needs HWASAN, add compiler flags.
488ifneq ($(filter hwaddress,$(my_sanitize)),)
489  my_cflags += $(HWADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS)
490
491  ifneq ($(filter EXECUTABLES NATIVE_TESTS,$(LOCAL_MODULE_CLASS)),)
492    ifneq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
493      my_linker := /system/bin/linker_hwasan64
494    endif
495  endif
496
497endif
498
499# Use minimal diagnostics when integer overflow is enabled; never do it for HOST modules
500ifeq ($(LOCAL_IS_HOST_MODULE),)
501  # Pre-emptively add UBSAN minimal runtime incase a static library dependency requires it
502  ifeq ($(filter STATIC_LIBRARIES,$(LOCAL_MODULE_CLASS)),)
503    ifndef LOCAL_SDK_VERSION
504      my_static_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)UBSAN_MINIMAL_RUNTIME_LIBRARY)
505      my_ldflags += -Wl,--exclude-libs,$($(LOCAL_2ND_ARCH_VAR_PREFIX)UBSAN_MINIMAL_RUNTIME_LIBRARY).a
506    endif
507  endif
508  ifneq ($(filter unsigned-integer-overflow signed-integer-overflow integer,$(my_sanitize)),)
509    ifeq ($(filter unsigned-integer-overflow signed-integer-overflow integer,$(my_sanitize_diag)),)
510      ifeq ($(filter cfi,$(my_sanitize_diag)),)
511        ifeq ($(filter address hwaddress fuzzer-no-link,$(my_sanitize)),)
512          my_cflags += -fsanitize-minimal-runtime
513          my_cflags += -fno-sanitize-trap=integer
514          my_cflags += -fno-sanitize-recover=integer
515        endif
516      endif
517    endif
518  endif
519endif
520
521# For Scudo, we opt for the minimal runtime, unless some diagnostics are enabled.
522ifneq ($(filter scudo,$(my_sanitize)),)
523  ifeq ($(filter unsigned-integer-overflow signed-integer-overflow integer cfi,$(my_sanitize_diag)),)
524    my_cflags += -fsanitize-minimal-runtime
525  endif
526  ifneq ($(filter -fsanitize-minimal-runtime,$(my_cflags)),)
527    my_shared_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)SCUDO_MINIMAL_RUNTIME_LIBRARY)
528  else
529    my_shared_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)SCUDO_RUNTIME_LIBRARY)
530  endif
531endif
532
533ifneq ($(strip $(LOCAL_SANITIZE_RECOVER)),)
534  recover_arg := $(subst $(space),$(comma),$(LOCAL_SANITIZE_RECOVER)),
535  my_cflags += -fsanitize-recover=$(recover_arg)
536endif
537
538ifneq ($(strip $(LOCAL_SANITIZE_NO_RECOVER)),)
539  no_recover_arg := $(subst $(space),$(comma),$(LOCAL_SANITIZE_NO_RECOVER)),
540  my_cflags += -fno-sanitize-recover=$(no_recover_arg)
541endif
542
543ifneq ($(my_sanitize_diag),)
544  # TODO(vishwath): Add diagnostic support for static executables once
545  # we switch to clang-4393122 (which adds the static ubsan runtime
546  # that this depends on)
547  ifneq ($(LOCAL_FORCE_STATIC_EXECUTABLE),true)
548    notrap_arg := $(subst $(space),$(comma),$(my_sanitize_diag)),
549    my_cflags += -fno-sanitize-trap=$(notrap_arg)
550    # Diagnostic requires a runtime library, unless ASan or TSan are also enabled.
551    ifeq ($(filter address thread scudo hwaddress,$(my_sanitize)),)
552      # Does not have to be the first DT_NEEDED unlike ASan.
553      my_shared_libraries += $($(LOCAL_2ND_ARCH_VAR_PREFIX)UBSAN_RUNTIME_LIBRARY)
554    endif
555  endif
556endif
557
558# http://b/119329758, Android core does not boot up with this sanitizer yet.
559# Previously sanitized modules might not pass new implicit-integer-sign-change check.
560# Disable this check unless it has been explicitly specified.
561ifneq ($(findstring fsanitize,$(my_cflags)),)
562  ifneq ($(findstring integer,$(my_cflags)),)
563    ifeq ($(findstring sanitize=implicit-integer-sign-change,$(my_cflags)),)
564      my_cflags += -fno-sanitize=implicit-integer-sign-change
565    endif
566  endif
567endif
568
569# http://b/177566116, libc++ may crash with this sanitizer.
570# Disable this check unless it has been explicitly specified.
571ifneq ($(findstring fsanitize,$(my_cflags)),)
572  ifneq ($(findstring integer,$(my_cflags)),)
573    ifeq ($(findstring sanitize=unsigned-shift-base,$(my_cflags)),)
574      my_cflags += -fno-sanitize=unsigned-shift-base
575    endif
576  endif
577endif
578