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