1 //===-- asan_rtl.cc -------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is a part of AddressSanitizer, an address sanity checker. 11 // 12 // Main file of the ASan run-time library. 13 //===----------------------------------------------------------------------===// 14 #include "asan_allocator.h" 15 #include "asan_interceptors.h" 16 #include "asan_internal.h" 17 #include "asan_lock.h" 18 #include "asan_mapping.h" 19 #include "asan_report.h" 20 #include "asan_stack.h" 21 #include "asan_stats.h" 22 #include "asan_thread.h" 23 #include "asan_thread_registry.h" 24 #include "sanitizer/asan_interface.h" 25 #include "sanitizer_common/sanitizer_atomic.h" 26 #include "sanitizer_common/sanitizer_flags.h" 27 #include "sanitizer_common/sanitizer_libc.h" 28 #include "sanitizer_common/sanitizer_symbolizer.h" 29 30 namespace __sanitizer { 31 using namespace __asan; 32 33 void Die() { 34 static atomic_uint32_t num_calls; 35 if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) { 36 // Don't die twice - run a busy loop. 37 while (1) { } 38 } 39 if (flags()->sleep_before_dying) { 40 Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying); 41 SleepForSeconds(flags()->sleep_before_dying); 42 } 43 if (flags()->unmap_shadow_on_exit) 44 UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg); 45 if (death_callback) 46 death_callback(); 47 if (flags()->abort_on_error) 48 Abort(); 49 Exit(flags()->exitcode); 50 } 51 52 SANITIZER_INTERFACE_ATTRIBUTE 53 void CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2) { 54 Report("AddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", 55 file, line, cond, (uptr)v1, (uptr)v2); 56 // FIXME: check for infinite recursion without a thread-local counter here. 57 PRINT_CURRENT_STACK(); 58 ShowStatsAndAbort(); 59 } 60 61 } // namespace __sanitizer 62 63 namespace __asan { 64 65 // -------------------------- Flags ------------------------- {{{1 66 static const int kDeafultMallocContextSize = 30; 67 68 static Flags asan_flags; 69 70 Flags *flags() { 71 return &asan_flags; 72 } 73 74 static void ParseFlagsFromString(Flags *f, const char *str) { 75 ParseFlag(str, &f->quarantine_size, "quarantine_size"); 76 ParseFlag(str, &f->symbolize, "symbolize"); 77 ParseFlag(str, &f->verbosity, "verbosity"); 78 ParseFlag(str, &f->redzone, "redzone"); 79 CHECK(f->redzone >= 16); 80 CHECK(IsPowerOfTwo(f->redzone)); 81 82 ParseFlag(str, &f->debug, "debug"); 83 ParseFlag(str, &f->report_globals, "report_globals"); 84 ParseFlag(str, &f->check_initialization_order, "initialization_order"); 85 ParseFlag(str, &f->malloc_context_size, "malloc_context_size"); 86 CHECK((uptr)f->malloc_context_size <= kStackTraceMax); 87 88 ParseFlag(str, &f->replace_str, "replace_str"); 89 ParseFlag(str, &f->replace_intrin, "replace_intrin"); 90 ParseFlag(str, &f->replace_cfallocator, "replace_cfallocator"); 91 ParseFlag(str, &f->mac_ignore_invalid_free, "mac_ignore_invalid_free"); 92 ParseFlag(str, &f->use_fake_stack, "use_fake_stack"); 93 ParseFlag(str, &f->max_malloc_fill_size, "max_malloc_fill_size"); 94 ParseFlag(str, &f->exitcode, "exitcode"); 95 ParseFlag(str, &f->allow_user_poisoning, "allow_user_poisoning"); 96 ParseFlag(str, &f->sleep_before_dying, "sleep_before_dying"); 97 ParseFlag(str, &f->handle_segv, "handle_segv"); 98 ParseFlag(str, &f->use_sigaltstack, "use_sigaltstack"); 99 ParseFlag(str, &f->check_malloc_usable_size, "check_malloc_usable_size"); 100 ParseFlag(str, &f->unmap_shadow_on_exit, "unmap_shadow_on_exit"); 101 ParseFlag(str, &f->abort_on_error, "abort_on_error"); 102 ParseFlag(str, &f->atexit, "atexit"); 103 ParseFlag(str, &f->disable_core, "disable_core"); 104 ParseFlag(str, &f->strip_path_prefix, "strip_path_prefix"); 105 ParseFlag(str, &f->allow_reexec, "allow_reexec"); 106 ParseFlag(str, &f->print_full_thread_history, "print_full_thread_history"); 107 } 108 109 extern "C" { 110 SANITIZER_WEAK_ATTRIBUTE 111 SANITIZER_INTERFACE_ATTRIBUTE 112 const char* __asan_default_options() { return ""; } 113 } // extern "C" 114 115 void InitializeFlags(Flags *f, const char *env) { 116 internal_memset(f, 0, sizeof(*f)); 117 118 f->quarantine_size = (ASAN_LOW_MEMORY) ? 1UL << 26 : 1UL << 28; 119 f->symbolize = false; 120 f->verbosity = 0; 121 f->redzone = (ASAN_LOW_MEMORY) ? 64 : 128; 122 f->debug = false; 123 f->report_globals = 1; 124 f->check_initialization_order = true; 125 f->malloc_context_size = kDeafultMallocContextSize; 126 f->replace_str = true; 127 f->replace_intrin = true; 128 f->replace_cfallocator = true; 129 f->mac_ignore_invalid_free = false; 130 f->use_fake_stack = true; 131 f->max_malloc_fill_size = 0; 132 f->exitcode = ASAN_DEFAULT_FAILURE_EXITCODE; 133 f->allow_user_poisoning = true; 134 f->sleep_before_dying = 0; 135 f->handle_segv = ASAN_NEEDS_SEGV; 136 f->use_sigaltstack = false; 137 f->check_malloc_usable_size = true; 138 f->unmap_shadow_on_exit = false; 139 f->abort_on_error = false; 140 f->atexit = false; 141 f->disable_core = (__WORDSIZE == 64); 142 f->strip_path_prefix = ""; 143 f->allow_reexec = true; 144 f->print_full_thread_history = true; 145 146 // Override from user-specified string. 147 ParseFlagsFromString(f, __asan_default_options()); 148 if (flags()->verbosity) { 149 Report("Using the defaults from __asan_default_options: %s\n", 150 __asan_default_options()); 151 } 152 153 // Override from command line. 154 ParseFlagsFromString(f, env); 155 } 156 157 // -------------------------- Globals --------------------- {{{1 158 int asan_inited; 159 bool asan_init_is_running; 160 void (*death_callback)(void); 161 162 // -------------------------- Misc ---------------- {{{1 163 void ShowStatsAndAbort() { 164 __asan_print_accumulated_stats(); 165 Die(); 166 } 167 168 // ---------------------- mmap -------------------- {{{1 169 // Reserve memory range [beg, end]. 170 static void ReserveShadowMemoryRange(uptr beg, uptr end) { 171 CHECK((beg % kPageSize) == 0); 172 CHECK(((end + 1) % kPageSize) == 0); 173 uptr size = end - beg + 1; 174 void *res = MmapFixedNoReserve(beg, size); 175 if (res != (void*)beg) { 176 Report("ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. " 177 "Perhaps you're using ulimit -v\n", size); 178 Abort(); 179 } 180 } 181 182 // --------------- LowLevelAllocateCallbac ---------- {{{1 183 static void OnLowLevelAllocate(uptr ptr, uptr size) { 184 PoisonShadow(ptr, size, kAsanInternalHeapMagic); 185 } 186 187 // -------------------------- Run-time entry ------------------- {{{1 188 // exported functions 189 #define ASAN_REPORT_ERROR(type, is_write, size) \ 190 extern "C" NOINLINE INTERFACE_ATTRIBUTE \ 191 void __asan_report_ ## type ## size(uptr addr); \ 192 void __asan_report_ ## type ## size(uptr addr) { \ 193 GET_CALLER_PC_BP_SP; \ 194 __asan_report_error(pc, bp, sp, addr, is_write, size); \ 195 } 196 197 ASAN_REPORT_ERROR(load, false, 1) 198 ASAN_REPORT_ERROR(load, false, 2) 199 ASAN_REPORT_ERROR(load, false, 4) 200 ASAN_REPORT_ERROR(load, false, 8) 201 ASAN_REPORT_ERROR(load, false, 16) 202 ASAN_REPORT_ERROR(store, true, 1) 203 ASAN_REPORT_ERROR(store, true, 2) 204 ASAN_REPORT_ERROR(store, true, 4) 205 ASAN_REPORT_ERROR(store, true, 8) 206 ASAN_REPORT_ERROR(store, true, 16) 207 208 // Force the linker to keep the symbols for various ASan interface functions. 209 // We want to keep those in the executable in order to let the instrumented 210 // dynamic libraries access the symbol even if it is not used by the executable 211 // itself. This should help if the build system is removing dead code at link 212 // time. 213 static NOINLINE void force_interface_symbols() { 214 volatile int fake_condition = 0; // prevent dead condition elimination. 215 // __asan_report_* functions are noreturn, so we need a switch to prevent 216 // the compiler from removing any of them. 217 switch (fake_condition) { 218 case 1: __asan_report_load1(0); break; 219 case 2: __asan_report_load2(0); break; 220 case 3: __asan_report_load4(0); break; 221 case 4: __asan_report_load8(0); break; 222 case 5: __asan_report_load16(0); break; 223 case 6: __asan_report_store1(0); break; 224 case 7: __asan_report_store2(0); break; 225 case 8: __asan_report_store4(0); break; 226 case 9: __asan_report_store8(0); break; 227 case 10: __asan_report_store16(0); break; 228 case 11: __asan_register_global(0, 0, 0); break; 229 case 12: __asan_register_globals(0, 0); break; 230 case 13: __asan_unregister_globals(0, 0); break; 231 case 14: __asan_set_death_callback(0); break; 232 case 15: __asan_set_error_report_callback(0); break; 233 case 16: __asan_handle_no_return(); break; 234 case 17: __asan_address_is_poisoned(0); break; 235 case 18: __asan_get_allocated_size(0); break; 236 case 19: __asan_get_current_allocated_bytes(); break; 237 case 20: __asan_get_estimated_allocated_size(0); break; 238 case 21: __asan_get_free_bytes(); break; 239 case 22: __asan_get_heap_size(); break; 240 case 23: __asan_get_ownership(0); break; 241 case 24: __asan_get_unmapped_bytes(); break; 242 case 25: __asan_poison_memory_region(0, 0); break; 243 case 26: __asan_unpoison_memory_region(0, 0); break; 244 case 27: __asan_set_error_exit_code(0); break; 245 case 28: __asan_stack_free(0, 0, 0); break; 246 case 29: __asan_stack_malloc(0, 0); break; 247 case 30: __asan_set_on_error_callback(0); break; 248 case 31: __asan_default_options(); break; 249 case 32: __asan_before_dynamic_init(0, 0); break; 250 case 33: __asan_after_dynamic_init(); break; 251 case 34: __asan_malloc_hook(0, 0); break; 252 case 35: __asan_free_hook(0); break; 253 case 36: __asan_set_symbolize_callback(0); break; 254 } 255 } 256 257 static void asan_atexit() { 258 Printf("AddressSanitizer exit stats:\n"); 259 __asan_print_accumulated_stats(); 260 } 261 262 } // namespace __asan 263 264 // ---------------------- Interface ---------------- {{{1 265 using namespace __asan; // NOLINT 266 267 int NOINLINE __asan_set_error_exit_code(int exit_code) { 268 int old = flags()->exitcode; 269 flags()->exitcode = exit_code; 270 return old; 271 } 272 273 void NOINLINE __asan_handle_no_return() { 274 int local_stack; 275 AsanThread *curr_thread = asanThreadRegistry().GetCurrent(); 276 CHECK(curr_thread); 277 uptr top = curr_thread->stack_top(); 278 uptr bottom = ((uptr)&local_stack - kPageSize) & ~(kPageSize-1); 279 PoisonShadow(bottom, top - bottom, 0); 280 } 281 282 void NOINLINE __asan_set_death_callback(void (*callback)(void)) { 283 death_callback = callback; 284 } 285 286 void __asan_init() { 287 if (asan_inited) return; 288 CHECK(!asan_init_is_running && "ASan init calls itself!"); 289 asan_init_is_running = true; 290 291 // Make sure we are not statically linked. 292 AsanDoesNotSupportStaticLinkage(); 293 294 SetPrintfAndReportCallback(AppendToErrorMessageBuffer); 295 296 // Initialize flags. This must be done early, because most of the 297 // initialization steps look at flags(). 298 const char *options = GetEnv("ASAN_OPTIONS"); 299 InitializeFlags(flags(), options); 300 301 if (flags()->verbosity && options) { 302 Report("Parsed ASAN_OPTIONS: %s\n", options); 303 } 304 305 // Re-exec ourselves if we need to set additional env or command line args. 306 MaybeReexec(); 307 308 // Setup internal allocator callback. 309 SetLowLevelAllocateCallback(OnLowLevelAllocate); 310 311 if (flags()->atexit) { 312 Atexit(asan_atexit); 313 } 314 315 // interceptors 316 InitializeAsanInterceptors(); 317 318 ReplaceSystemMalloc(); 319 ReplaceOperatorsNewAndDelete(); 320 321 if (flags()->verbosity) { 322 Printf("|| `[%p, %p]` || HighMem ||\n", 323 (void*)kHighMemBeg, (void*)kHighMemEnd); 324 Printf("|| `[%p, %p]` || HighShadow ||\n", 325 (void*)kHighShadowBeg, (void*)kHighShadowEnd); 326 Printf("|| `[%p, %p]` || ShadowGap ||\n", 327 (void*)kShadowGapBeg, (void*)kShadowGapEnd); 328 Printf("|| `[%p, %p]` || LowShadow ||\n", 329 (void*)kLowShadowBeg, (void*)kLowShadowEnd); 330 Printf("|| `[%p, %p]` || LowMem ||\n", 331 (void*)kLowMemBeg, (void*)kLowMemEnd); 332 Printf("MemToShadow(shadow): %p %p %p %p\n", 333 (void*)MEM_TO_SHADOW(kLowShadowBeg), 334 (void*)MEM_TO_SHADOW(kLowShadowEnd), 335 (void*)MEM_TO_SHADOW(kHighShadowBeg), 336 (void*)MEM_TO_SHADOW(kHighShadowEnd)); 337 Printf("red_zone=%zu\n", (uptr)flags()->redzone); 338 Printf("malloc_context_size=%zu\n", (uptr)flags()->malloc_context_size); 339 340 Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE); 341 Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY); 342 Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET); 343 CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7); 344 } 345 346 if (flags()->disable_core) { 347 DisableCoreDumper(); 348 } 349 350 uptr shadow_start = kLowShadowBeg; 351 if (kLowShadowBeg > 0) shadow_start -= kMmapGranularity; 352 uptr shadow_end = kHighShadowEnd; 353 if (MemoryRangeIsAvailable(shadow_start, shadow_end)) { 354 if (kLowShadowBeg != kLowShadowEnd) { 355 // mmap the low shadow plus at least one page. 356 ReserveShadowMemoryRange(kLowShadowBeg - kMmapGranularity, kLowShadowEnd); 357 } 358 // mmap the high shadow. 359 ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd); 360 // protect the gap 361 void *prot = Mprotect(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); 362 CHECK(prot == (void*)kShadowGapBeg); 363 } else { 364 Report("Shadow memory range interleaves with an existing memory mapping. " 365 "ASan cannot proceed correctly. ABORTING.\n"); 366 DumpProcessMap(); 367 Die(); 368 } 369 370 InstallSignalHandlers(); 371 // Start symbolizer process if necessary. 372 if (flags()->symbolize) { 373 const char *external_symbolizer = GetEnv("ASAN_SYMBOLIZER_PATH"); 374 if (external_symbolizer) { 375 InitializeExternalSymbolizer(external_symbolizer); 376 } 377 } 378 #ifdef _WIN32 379 __asan_set_symbolize_callback(WinSymbolize); 380 #endif // _WIN32 381 382 // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited 383 // should be set to 1 prior to initializing the threads. 384 asan_inited = 1; 385 asan_init_is_running = false; 386 387 asanThreadRegistry().Init(); 388 asanThreadRegistry().GetMain()->ThreadStart(); 389 force_interface_symbols(); // no-op. 390 391 if (flags()->verbosity) { 392 Report("AddressSanitizer Init done\n"); 393 } 394 } 395 396 #if defined(ASAN_USE_PREINIT_ARRAY) 397 // On Linux, we force __asan_init to be called before anyone else 398 // by placing it into .preinit_array section. 399 // FIXME: do we have anything like this on Mac? 400 __attribute__((section(".preinit_array"))) 401 typeof(__asan_init) *__asan_preinit =__asan_init; 402 #elif defined(_WIN32) && defined(_DLL) 403 // On Windows, when using dynamic CRT (/MD), we can put a pointer 404 // to __asan_init into the global list of C initializers. 405 // See crt0dat.c in the CRT sources for the details. 406 #pragma section(".CRT$XIB", long, read) // NOLINT 407 __declspec(allocate(".CRT$XIB")) void (*__asan_preinit)() = __asan_init; 408 #endif 409