Home | History | Annotate | Line # | Download | only in asan
      1  1.1  kamil //===-- asan_flags.cc -------------------------------------------*- C++ -*-===//
      2  1.1  kamil //
      3  1.1  kamil //                     The LLVM Compiler Infrastructure
      4  1.1  kamil //
      5  1.1  kamil // This file is distributed under the University of Illinois Open Source
      6  1.1  kamil // License. See LICENSE.TXT for details.
      7  1.1  kamil //
      8  1.1  kamil //===----------------------------------------------------------------------===//
      9  1.1  kamil //
     10  1.1  kamil // This file is a part of AddressSanitizer, an address sanity checker.
     11  1.1  kamil //
     12  1.1  kamil // ASan flag parsing logic.
     13  1.1  kamil //===----------------------------------------------------------------------===//
     14  1.1  kamil 
     15  1.1  kamil #include "asan_activation.h"
     16  1.1  kamil #include "asan_flags.h"
     17  1.1  kamil #include "asan_interface_internal.h"
     18  1.1  kamil #include "asan_stack.h"
     19  1.1  kamil #include "lsan/lsan_common.h"
     20  1.1  kamil #include "sanitizer_common/sanitizer_common.h"
     21  1.1  kamil #include "sanitizer_common/sanitizer_flags.h"
     22  1.1  kamil #include "sanitizer_common/sanitizer_flag_parser.h"
     23  1.1  kamil #include "ubsan/ubsan_flags.h"
     24  1.1  kamil #include "ubsan/ubsan_platform.h"
     25  1.1  kamil 
     26  1.1  kamil namespace __asan {
     27  1.1  kamil 
     28  1.1  kamil Flags asan_flags_dont_use_directly;  // use via flags().
     29  1.1  kamil 
     30  1.1  kamil static const char *MaybeCallAsanDefaultOptions() {
     31  1.1  kamil   return (&__asan_default_options) ? __asan_default_options() : "";
     32  1.1  kamil }
     33  1.1  kamil 
     34  1.1  kamil static const char *MaybeUseAsanDefaultOptionsCompileDefinition() {
     35  1.1  kamil #ifdef ASAN_DEFAULT_OPTIONS
     36  1.1  kamil   return SANITIZER_STRINGIFY(ASAN_DEFAULT_OPTIONS);
     37  1.1  kamil #else
     38  1.1  kamil   return "";
     39  1.1  kamil #endif
     40  1.1  kamil }
     41  1.1  kamil 
     42  1.1  kamil void Flags::SetDefaults() {
     43  1.1  kamil #define ASAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
     44  1.1  kamil #include "asan_flags.inc"
     45  1.1  kamil #undef ASAN_FLAG
     46  1.1  kamil }
     47  1.1  kamil 
     48  1.1  kamil static void RegisterAsanFlags(FlagParser *parser, Flags *f) {
     49  1.1  kamil #define ASAN_FLAG(Type, Name, DefaultValue, Description) \
     50  1.1  kamil   RegisterFlag(parser, #Name, Description, &f->Name);
     51  1.1  kamil #include "asan_flags.inc"
     52  1.1  kamil #undef ASAN_FLAG
     53  1.1  kamil }
     54  1.1  kamil 
     55  1.1  kamil void InitializeFlags() {
     56  1.1  kamil   // Set the default values and prepare for parsing ASan and common flags.
     57  1.1  kamil   SetCommonFlagsDefaults();
     58  1.1  kamil   {
     59  1.1  kamil     CommonFlags cf;
     60  1.1  kamil     cf.CopyFrom(*common_flags());
     61  1.1  kamil     cf.detect_leaks = cf.detect_leaks && CAN_SANITIZE_LEAKS;
     62  1.1  kamil     cf.external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH");
     63  1.1  kamil     cf.malloc_context_size = kDefaultMallocContextSize;
     64  1.1  kamil     cf.intercept_tls_get_addr = true;
     65  1.1  kamil     cf.exitcode = 1;
     66  1.1  kamil     OverrideCommonFlags(cf);
     67  1.1  kamil   }
     68  1.1  kamil   Flags *f = flags();
     69  1.1  kamil   f->SetDefaults();
     70  1.1  kamil 
     71  1.1  kamil   FlagParser asan_parser;
     72  1.1  kamil   RegisterAsanFlags(&asan_parser, f);
     73  1.1  kamil   RegisterCommonFlags(&asan_parser);
     74  1.1  kamil 
     75  1.1  kamil   // Set the default values and prepare for parsing LSan and UBSan flags
     76  1.1  kamil   // (which can also overwrite common flags).
     77  1.1  kamil #if CAN_SANITIZE_LEAKS
     78  1.1  kamil   __lsan::Flags *lf = __lsan::flags();
     79  1.1  kamil   lf->SetDefaults();
     80  1.1  kamil 
     81  1.1  kamil   FlagParser lsan_parser;
     82  1.1  kamil   __lsan::RegisterLsanFlags(&lsan_parser, lf);
     83  1.1  kamil   RegisterCommonFlags(&lsan_parser);
     84  1.1  kamil #endif
     85  1.1  kamil 
     86  1.1  kamil #if CAN_SANITIZE_UB
     87  1.1  kamil   __ubsan::Flags *uf = __ubsan::flags();
     88  1.1  kamil   uf->SetDefaults();
     89  1.1  kamil 
     90  1.1  kamil   FlagParser ubsan_parser;
     91  1.1  kamil   __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);
     92  1.1  kamil   RegisterCommonFlags(&ubsan_parser);
     93  1.1  kamil #endif
     94  1.1  kamil 
     95  1.1  kamil   if (SANITIZER_MAC) {
     96  1.1  kamil     // Support macOS MallocScribble and MallocPreScribble:
     97  1.1  kamil     // <https://developer.apple.com/library/content/documentation/Performance/
     98  1.1  kamil     // Conceptual/ManagingMemory/Articles/MallocDebug.html>
     99  1.1  kamil     if (GetEnv("MallocScribble")) {
    100  1.1  kamil       f->max_free_fill_size = 0x1000;
    101  1.1  kamil     }
    102  1.1  kamil     if (GetEnv("MallocPreScribble")) {
    103  1.1  kamil       f->malloc_fill_byte = 0xaa;
    104  1.1  kamil     }
    105  1.1  kamil   }
    106  1.1  kamil 
    107  1.1  kamil   // Override from ASan compile definition.
    108  1.1  kamil   const char *asan_compile_def = MaybeUseAsanDefaultOptionsCompileDefinition();
    109  1.1  kamil   asan_parser.ParseString(asan_compile_def);
    110  1.1  kamil 
    111  1.1  kamil   // Override from user-specified string.
    112  1.1  kamil   const char *asan_default_options = MaybeCallAsanDefaultOptions();
    113  1.1  kamil   asan_parser.ParseString(asan_default_options);
    114  1.1  kamil #if CAN_SANITIZE_UB
    115  1.1  kamil   const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions();
    116  1.1  kamil   ubsan_parser.ParseString(ubsan_default_options);
    117  1.1  kamil #endif
    118  1.1  kamil #if CAN_SANITIZE_LEAKS
    119  1.1  kamil   const char *lsan_default_options = __lsan::MaybeCallLsanDefaultOptions();
    120  1.1  kamil   lsan_parser.ParseString(lsan_default_options);
    121  1.1  kamil #endif
    122  1.1  kamil 
    123  1.1  kamil   // Override from command line.
    124  1.1  kamil   asan_parser.ParseString(GetEnv("ASAN_OPTIONS"));
    125  1.1  kamil #if CAN_SANITIZE_LEAKS
    126  1.1  kamil   lsan_parser.ParseString(GetEnv("LSAN_OPTIONS"));
    127  1.1  kamil #endif
    128  1.1  kamil #if CAN_SANITIZE_UB
    129  1.1  kamil   ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
    130  1.1  kamil #endif
    131  1.1  kamil 
    132  1.1  kamil   InitializeCommonFlags();
    133  1.1  kamil 
    134  1.1  kamil   // TODO(eugenis): dump all flags at verbosity>=2?
    135  1.1  kamil   if (Verbosity()) ReportUnrecognizedFlags();
    136  1.1  kamil 
    137  1.1  kamil   if (common_flags()->help) {
    138  1.1  kamil     // TODO(samsonov): print all of the flags (ASan, LSan, common).
    139  1.1  kamil     asan_parser.PrintFlagDescriptions();
    140  1.1  kamil   }
    141  1.1  kamil 
    142  1.1  kamil   // Flag validation:
    143  1.1  kamil   if (!CAN_SANITIZE_LEAKS && common_flags()->detect_leaks) {
    144  1.1  kamil     Report("%s: detect_leaks is not supported on this platform.\n",
    145  1.1  kamil            SanitizerToolName);
    146  1.1  kamil     Die();
    147  1.1  kamil   }
    148  1.1  kamil   // Ensure that redzone is at least SHADOW_GRANULARITY.
    149  1.1  kamil   if (f->redzone < (int)SHADOW_GRANULARITY)
    150  1.1  kamil     f->redzone = SHADOW_GRANULARITY;
    151  1.1  kamil   // Make "strict_init_order" imply "check_initialization_order".
    152  1.1  kamil   // TODO(samsonov): Use a single runtime flag for an init-order checker.
    153  1.1  kamil   if (f->strict_init_order) {
    154  1.1  kamil     f->check_initialization_order = true;
    155  1.1  kamil   }
    156  1.1  kamil   CHECK_LE((uptr)common_flags()->malloc_context_size, kStackTraceMax);
    157  1.1  kamil   CHECK_LE(f->min_uar_stack_size_log, f->max_uar_stack_size_log);
    158  1.1  kamil   CHECK_GE(f->redzone, 16);
    159  1.1  kamil   CHECK_GE(f->max_redzone, f->redzone);
    160  1.1  kamil   CHECK_LE(f->max_redzone, 2048);
    161  1.1  kamil   CHECK(IsPowerOfTwo(f->redzone));
    162  1.1  kamil   CHECK(IsPowerOfTwo(f->max_redzone));
    163  1.1  kamil   if (SANITIZER_RTEMS) {
    164  1.1  kamil     CHECK(!f->unmap_shadow_on_exit);
    165  1.1  kamil     CHECK(!f->protect_shadow_gap);
    166  1.1  kamil   }
    167  1.1  kamil 
    168  1.1  kamil   // quarantine_size is deprecated but we still honor it.
    169  1.1  kamil   // quarantine_size can not be used together with quarantine_size_mb.
    170  1.1  kamil   if (f->quarantine_size >= 0 && f->quarantine_size_mb >= 0) {
    171  1.1  kamil     Report("%s: please use either 'quarantine_size' (deprecated) or "
    172  1.1  kamil            "quarantine_size_mb, but not both\n", SanitizerToolName);
    173  1.1  kamil     Die();
    174  1.1  kamil   }
    175  1.1  kamil   if (f->quarantine_size >= 0)
    176  1.1  kamil     f->quarantine_size_mb = f->quarantine_size >> 20;
    177  1.1  kamil   if (f->quarantine_size_mb < 0) {
    178  1.1  kamil     const int kDefaultQuarantineSizeMb =
    179  1.1  kamil         (ASAN_LOW_MEMORY) ? 1UL << 4 : 1UL << 8;
    180  1.1  kamil     f->quarantine_size_mb = kDefaultQuarantineSizeMb;
    181  1.1  kamil   }
    182  1.1  kamil   if (f->thread_local_quarantine_size_kb < 0) {
    183  1.1  kamil     const u32 kDefaultThreadLocalQuarantineSizeKb =
    184  1.1  kamil         // It is not advised to go lower than 64Kb, otherwise quarantine batches
    185  1.1  kamil         // pushed from thread local quarantine to global one will create too
    186  1.1  kamil         // much overhead. One quarantine batch size is 8Kb and it  holds up to
    187  1.1  kamil         // 1021 chunk, which amounts to 1/8 memory overhead per batch when
    188  1.1  kamil         // thread local quarantine is set to 64Kb.
    189  1.1  kamil         (ASAN_LOW_MEMORY) ? 1 << 6 : FIRST_32_SECOND_64(1 << 8, 1 << 10);
    190  1.1  kamil     f->thread_local_quarantine_size_kb = kDefaultThreadLocalQuarantineSizeKb;
    191  1.1  kamil   }
    192  1.1  kamil   if (f->thread_local_quarantine_size_kb == 0 && f->quarantine_size_mb > 0) {
    193  1.1  kamil     Report("%s: thread_local_quarantine_size_kb can be set to 0 only when "
    194  1.1  kamil            "quarantine_size_mb is set to 0\n", SanitizerToolName);
    195  1.1  kamil     Die();
    196  1.1  kamil   }
    197  1.1  kamil   if (!f->replace_str && common_flags()->intercept_strlen) {
    198  1.1  kamil     Report("WARNING: strlen interceptor is enabled even though replace_str=0. "
    199  1.1  kamil            "Use intercept_strlen=0 to disable it.");
    200  1.1  kamil   }
    201  1.1  kamil   if (!f->replace_str && common_flags()->intercept_strchr) {
    202  1.1  kamil     Report("WARNING: strchr* interceptors are enabled even though "
    203  1.1  kamil            "replace_str=0. Use intercept_strchr=0 to disable them.");
    204  1.1  kamil   }
    205  1.1  kamil   if (!f->replace_str && common_flags()->intercept_strndup) {
    206  1.1  kamil     Report("WARNING: strndup* interceptors are enabled even though "
    207  1.1  kamil            "replace_str=0. Use intercept_strndup=0 to disable them.");
    208  1.1  kamil   }
    209  1.1  kamil }
    210  1.1  kamil 
    211  1.1  kamil }  // namespace __asan
    212  1.1  kamil 
    213  1.1  kamil SANITIZER_INTERFACE_WEAK_DEF(const char*, __asan_default_options, void) {
    214  1.1  kamil   return "";
    215  1.1  kamil }
    216