13cab2bb3Spatrick //===-- asan_flags.cpp ------------------------------------------*- C++ -*-===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick //
93cab2bb3Spatrick // This file is a part of AddressSanitizer, an address sanity checker.
103cab2bb3Spatrick //
113cab2bb3Spatrick // ASan flag parsing logic.
123cab2bb3Spatrick //===----------------------------------------------------------------------===//
133cab2bb3Spatrick
143cab2bb3Spatrick #include "asan_activation.h"
153cab2bb3Spatrick #include "asan_flags.h"
163cab2bb3Spatrick #include "asan_interface_internal.h"
173cab2bb3Spatrick #include "asan_stack.h"
183cab2bb3Spatrick #include "lsan/lsan_common.h"
193cab2bb3Spatrick #include "sanitizer_common/sanitizer_common.h"
203cab2bb3Spatrick #include "sanitizer_common/sanitizer_flags.h"
213cab2bb3Spatrick #include "sanitizer_common/sanitizer_flag_parser.h"
223cab2bb3Spatrick #include "ubsan/ubsan_flags.h"
233cab2bb3Spatrick #include "ubsan/ubsan_platform.h"
243cab2bb3Spatrick
253cab2bb3Spatrick namespace __asan {
263cab2bb3Spatrick
273cab2bb3Spatrick Flags asan_flags_dont_use_directly; // use via flags().
283cab2bb3Spatrick
MaybeUseAsanDefaultOptionsCompileDefinition()293cab2bb3Spatrick static const char *MaybeUseAsanDefaultOptionsCompileDefinition() {
303cab2bb3Spatrick #ifdef ASAN_DEFAULT_OPTIONS
313cab2bb3Spatrick return SANITIZER_STRINGIFY(ASAN_DEFAULT_OPTIONS);
323cab2bb3Spatrick #else
333cab2bb3Spatrick return "";
343cab2bb3Spatrick #endif
353cab2bb3Spatrick }
363cab2bb3Spatrick
SetDefaults()373cab2bb3Spatrick void Flags::SetDefaults() {
383cab2bb3Spatrick #define ASAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
393cab2bb3Spatrick #include "asan_flags.inc"
403cab2bb3Spatrick #undef ASAN_FLAG
413cab2bb3Spatrick }
423cab2bb3Spatrick
RegisterAsanFlags(FlagParser * parser,Flags * f)433cab2bb3Spatrick static void RegisterAsanFlags(FlagParser *parser, Flags *f) {
443cab2bb3Spatrick #define ASAN_FLAG(Type, Name, DefaultValue, Description) \
453cab2bb3Spatrick RegisterFlag(parser, #Name, Description, &f->Name);
463cab2bb3Spatrick #include "asan_flags.inc"
473cab2bb3Spatrick #undef ASAN_FLAG
483cab2bb3Spatrick }
493cab2bb3Spatrick
InitializeFlags()503cab2bb3Spatrick void InitializeFlags() {
513cab2bb3Spatrick // Set the default values and prepare for parsing ASan and common flags.
523cab2bb3Spatrick SetCommonFlagsDefaults();
533cab2bb3Spatrick {
543cab2bb3Spatrick CommonFlags cf;
553cab2bb3Spatrick cf.CopyFrom(*common_flags());
563cab2bb3Spatrick cf.detect_leaks = cf.detect_leaks && CAN_SANITIZE_LEAKS;
573cab2bb3Spatrick cf.external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH");
583cab2bb3Spatrick cf.malloc_context_size = kDefaultMallocContextSize;
593cab2bb3Spatrick cf.intercept_tls_get_addr = true;
603cab2bb3Spatrick cf.exitcode = 1;
613cab2bb3Spatrick OverrideCommonFlags(cf);
623cab2bb3Spatrick }
633cab2bb3Spatrick Flags *f = flags();
643cab2bb3Spatrick f->SetDefaults();
653cab2bb3Spatrick
663cab2bb3Spatrick FlagParser asan_parser;
673cab2bb3Spatrick RegisterAsanFlags(&asan_parser, f);
683cab2bb3Spatrick RegisterCommonFlags(&asan_parser);
693cab2bb3Spatrick
703cab2bb3Spatrick // Set the default values and prepare for parsing LSan and UBSan flags
713cab2bb3Spatrick // (which can also overwrite common flags).
723cab2bb3Spatrick #if CAN_SANITIZE_LEAKS
733cab2bb3Spatrick __lsan::Flags *lf = __lsan::flags();
743cab2bb3Spatrick lf->SetDefaults();
753cab2bb3Spatrick
763cab2bb3Spatrick FlagParser lsan_parser;
773cab2bb3Spatrick __lsan::RegisterLsanFlags(&lsan_parser, lf);
783cab2bb3Spatrick RegisterCommonFlags(&lsan_parser);
793cab2bb3Spatrick #endif
803cab2bb3Spatrick
813cab2bb3Spatrick #if CAN_SANITIZE_UB
823cab2bb3Spatrick __ubsan::Flags *uf = __ubsan::flags();
833cab2bb3Spatrick uf->SetDefaults();
843cab2bb3Spatrick
853cab2bb3Spatrick FlagParser ubsan_parser;
863cab2bb3Spatrick __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);
873cab2bb3Spatrick RegisterCommonFlags(&ubsan_parser);
883cab2bb3Spatrick #endif
893cab2bb3Spatrick
90*810390e3Srobert if (SANITIZER_APPLE) {
913cab2bb3Spatrick // Support macOS MallocScribble and MallocPreScribble:
923cab2bb3Spatrick // <https://developer.apple.com/library/content/documentation/Performance/
933cab2bb3Spatrick // Conceptual/ManagingMemory/Articles/MallocDebug.html>
943cab2bb3Spatrick if (GetEnv("MallocScribble")) {
953cab2bb3Spatrick f->max_free_fill_size = 0x1000;
963cab2bb3Spatrick }
973cab2bb3Spatrick if (GetEnv("MallocPreScribble")) {
983cab2bb3Spatrick f->malloc_fill_byte = 0xaa;
993cab2bb3Spatrick }
1003cab2bb3Spatrick }
1013cab2bb3Spatrick
1023cab2bb3Spatrick // Override from ASan compile definition.
1033cab2bb3Spatrick const char *asan_compile_def = MaybeUseAsanDefaultOptionsCompileDefinition();
1043cab2bb3Spatrick asan_parser.ParseString(asan_compile_def);
1053cab2bb3Spatrick
1063cab2bb3Spatrick // Override from user-specified string.
107d89ec533Spatrick const char *asan_default_options = __asan_default_options();
1083cab2bb3Spatrick asan_parser.ParseString(asan_default_options);
1093cab2bb3Spatrick #if CAN_SANITIZE_UB
110d89ec533Spatrick const char *ubsan_default_options = __ubsan_default_options();
1113cab2bb3Spatrick ubsan_parser.ParseString(ubsan_default_options);
1123cab2bb3Spatrick #endif
1133cab2bb3Spatrick #if CAN_SANITIZE_LEAKS
114d89ec533Spatrick const char *lsan_default_options = __lsan_default_options();
1153cab2bb3Spatrick lsan_parser.ParseString(lsan_default_options);
1163cab2bb3Spatrick #endif
1173cab2bb3Spatrick
1183cab2bb3Spatrick // Override from command line.
1193cab2bb3Spatrick asan_parser.ParseStringFromEnv("ASAN_OPTIONS");
1203cab2bb3Spatrick #if CAN_SANITIZE_LEAKS
1213cab2bb3Spatrick lsan_parser.ParseStringFromEnv("LSAN_OPTIONS");
1223cab2bb3Spatrick #endif
1233cab2bb3Spatrick #if CAN_SANITIZE_UB
1243cab2bb3Spatrick ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS");
1253cab2bb3Spatrick #endif
1263cab2bb3Spatrick
1273cab2bb3Spatrick InitializeCommonFlags();
1283cab2bb3Spatrick
1293cab2bb3Spatrick // TODO(eugenis): dump all flags at verbosity>=2?
1303cab2bb3Spatrick if (Verbosity()) ReportUnrecognizedFlags();
1313cab2bb3Spatrick
1323cab2bb3Spatrick if (common_flags()->help) {
1333cab2bb3Spatrick // TODO(samsonov): print all of the flags (ASan, LSan, common).
1343cab2bb3Spatrick asan_parser.PrintFlagDescriptions();
1353cab2bb3Spatrick }
1363cab2bb3Spatrick
1373cab2bb3Spatrick // Flag validation:
1383cab2bb3Spatrick if (!CAN_SANITIZE_LEAKS && common_flags()->detect_leaks) {
1393cab2bb3Spatrick Report("%s: detect_leaks is not supported on this platform.\n",
1403cab2bb3Spatrick SanitizerToolName);
1413cab2bb3Spatrick Die();
1423cab2bb3Spatrick }
143*810390e3Srobert // Ensure that redzone is at least ASAN_SHADOW_GRANULARITY.
144*810390e3Srobert if (f->redzone < (int)ASAN_SHADOW_GRANULARITY)
145*810390e3Srobert f->redzone = ASAN_SHADOW_GRANULARITY;
1463cab2bb3Spatrick // Make "strict_init_order" imply "check_initialization_order".
1473cab2bb3Spatrick // TODO(samsonov): Use a single runtime flag for an init-order checker.
1483cab2bb3Spatrick if (f->strict_init_order) {
1493cab2bb3Spatrick f->check_initialization_order = true;
1503cab2bb3Spatrick }
1513cab2bb3Spatrick CHECK_LE((uptr)common_flags()->malloc_context_size, kStackTraceMax);
1523cab2bb3Spatrick CHECK_LE(f->min_uar_stack_size_log, f->max_uar_stack_size_log);
1533cab2bb3Spatrick CHECK_GE(f->redzone, 16);
1543cab2bb3Spatrick CHECK_GE(f->max_redzone, f->redzone);
1553cab2bb3Spatrick CHECK_LE(f->max_redzone, 2048);
1563cab2bb3Spatrick CHECK(IsPowerOfTwo(f->redzone));
1573cab2bb3Spatrick CHECK(IsPowerOfTwo(f->max_redzone));
1583cab2bb3Spatrick
1593cab2bb3Spatrick // quarantine_size is deprecated but we still honor it.
1603cab2bb3Spatrick // quarantine_size can not be used together with quarantine_size_mb.
1613cab2bb3Spatrick if (f->quarantine_size >= 0 && f->quarantine_size_mb >= 0) {
1623cab2bb3Spatrick Report("%s: please use either 'quarantine_size' (deprecated) or "
1633cab2bb3Spatrick "quarantine_size_mb, but not both\n", SanitizerToolName);
1643cab2bb3Spatrick Die();
1653cab2bb3Spatrick }
1663cab2bb3Spatrick if (f->quarantine_size >= 0)
1673cab2bb3Spatrick f->quarantine_size_mb = f->quarantine_size >> 20;
1683cab2bb3Spatrick if (f->quarantine_size_mb < 0) {
1693cab2bb3Spatrick const int kDefaultQuarantineSizeMb =
1703cab2bb3Spatrick (ASAN_LOW_MEMORY) ? 1UL << 4 : 1UL << 8;
1713cab2bb3Spatrick f->quarantine_size_mb = kDefaultQuarantineSizeMb;
1723cab2bb3Spatrick }
1733cab2bb3Spatrick if (f->thread_local_quarantine_size_kb < 0) {
1743cab2bb3Spatrick const u32 kDefaultThreadLocalQuarantineSizeKb =
1753cab2bb3Spatrick // It is not advised to go lower than 64Kb, otherwise quarantine batches
1763cab2bb3Spatrick // pushed from thread local quarantine to global one will create too
1773cab2bb3Spatrick // much overhead. One quarantine batch size is 8Kb and it holds up to
1783cab2bb3Spatrick // 1021 chunk, which amounts to 1/8 memory overhead per batch when
1793cab2bb3Spatrick // thread local quarantine is set to 64Kb.
1803cab2bb3Spatrick (ASAN_LOW_MEMORY) ? 1 << 6 : FIRST_32_SECOND_64(1 << 8, 1 << 10);
1813cab2bb3Spatrick f->thread_local_quarantine_size_kb = kDefaultThreadLocalQuarantineSizeKb;
1823cab2bb3Spatrick }
1833cab2bb3Spatrick if (f->thread_local_quarantine_size_kb == 0 && f->quarantine_size_mb > 0) {
1843cab2bb3Spatrick Report("%s: thread_local_quarantine_size_kb can be set to 0 only when "
1853cab2bb3Spatrick "quarantine_size_mb is set to 0\n", SanitizerToolName);
1863cab2bb3Spatrick Die();
1873cab2bb3Spatrick }
1883cab2bb3Spatrick if (!f->replace_str && common_flags()->intercept_strlen) {
1893cab2bb3Spatrick Report("WARNING: strlen interceptor is enabled even though replace_str=0. "
1903cab2bb3Spatrick "Use intercept_strlen=0 to disable it.");
1913cab2bb3Spatrick }
1923cab2bb3Spatrick if (!f->replace_str && common_flags()->intercept_strchr) {
1933cab2bb3Spatrick Report("WARNING: strchr* interceptors are enabled even though "
1943cab2bb3Spatrick "replace_str=0. Use intercept_strchr=0 to disable them.");
1953cab2bb3Spatrick }
1963cab2bb3Spatrick if (!f->replace_str && common_flags()->intercept_strndup) {
1973cab2bb3Spatrick Report("WARNING: strndup* interceptors are enabled even though "
1983cab2bb3Spatrick "replace_str=0. Use intercept_strndup=0 to disable them.");
1993cab2bb3Spatrick }
2003cab2bb3Spatrick }
2013cab2bb3Spatrick
2023cab2bb3Spatrick } // namespace __asan
2033cab2bb3Spatrick
SANITIZER_INTERFACE_WEAK_DEF(const char *,__asan_default_options,void)2043cab2bb3Spatrick SANITIZER_INTERFACE_WEAK_DEF(const char*, __asan_default_options, void) {
2053cab2bb3Spatrick return "";
2063cab2bb3Spatrick }
207