asan_rtl.cc revision 1.4
1//===-- asan_rtl.cc -------------------------------------------------------===// 2// 3// This file is distributed under the University of Illinois Open Source 4// License. See LICENSE.TXT for details. 5// 6//===----------------------------------------------------------------------===// 7// 8// This file is a part of AddressSanitizer, an address sanity checker. 9// 10// Main file of the ASan run-time library. 11//===----------------------------------------------------------------------===// 12 13#include "asan_activation.h" 14#include "asan_allocator.h" 15#include "asan_interceptors.h" 16#include "asan_interface_internal.h" 17#include "asan_internal.h" 18#include "asan_mapping.h" 19#include "asan_poisoning.h" 20#include "asan_report.h" 21#include "asan_stack.h" 22#include "asan_stats.h" 23#include "asan_suppressions.h" 24#include "asan_thread.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#include "lsan/lsan_common.h" 30#include "ubsan/ubsan_init.h" 31#include "ubsan/ubsan_platform.h" 32 33int __asan_option_detect_stack_use_after_return; // Global interface symbol. 34uptr *__asan_test_only_reported_buggy_pointer; // Used only for testing asan. 35 36namespace __asan { 37 38uptr AsanMappingProfile[kAsanMappingProfileSize]; 39 40static void AsanDie() { 41 static atomic_uint32_t num_calls; 42 if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) { 43 // Don't die twice - run a busy loop. 44 while (1) { } 45 } 46 if (flags()->sleep_before_dying) { 47 Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying); 48 SleepForSeconds(flags()->sleep_before_dying); 49 } 50 if (flags()->unmap_shadow_on_exit) { 51 if (kMidMemBeg) { 52 UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg); 53 UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd); 54 } else { 55 UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg); 56 } 57 } 58} 59 60static void AsanCheckFailed(const char *file, int line, const char *cond, 61 u64 v1, u64 v2) { 62 Report("AddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", file, 63 line, cond, (uptr)v1, (uptr)v2); 64 // FIXME: check for infinite recursion without a thread-local counter here. 65 PRINT_CURRENT_STACK_CHECK(); 66 Die(); 67} 68 69// -------------------------- Globals --------------------- {{{1 70int asan_inited; 71bool asan_init_is_running; 72 73#if !ASAN_FIXED_MAPPING 74uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; 75#endif 76 77// -------------------------- Misc ---------------- {{{1 78void ShowStatsAndAbort() { 79 __asan_print_accumulated_stats(); 80 Die(); 81} 82 83// ---------------------- mmap -------------------- {{{1 84// Reserve memory range [beg, end]. 85// We need to use inclusive range because end+1 may not be representable. 86void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name) { 87 CHECK_EQ((beg % GetPageSizeCached()), 0); 88 CHECK_EQ(((end + 1) % GetPageSizeCached()), 0); 89 uptr size = end - beg + 1; 90 DecreaseTotalMmap(size); // Don't count the shadow against mmap_limit_mb. 91 void *res = MmapFixedNoReserve(beg, size, name); 92 if (res != (void*)beg) { 93 Report("ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. " 94 "Perhaps you're using ulimit -v\n", size); 95 Abort(); 96 } 97 if (common_flags()->no_huge_pages_for_shadow) 98 NoHugePagesInRegion(beg, size); 99 if (common_flags()->use_madv_dontdump) 100 DontDumpShadowMemory(beg, size); 101} 102 103// --------------- LowLevelAllocateCallbac ---------- {{{1 104static void OnLowLevelAllocate(uptr ptr, uptr size) { 105 PoisonShadow(ptr, size, kAsanInternalHeapMagic); 106} 107 108// -------------------------- Run-time entry ------------------- {{{1 109// exported functions 110#define ASAN_REPORT_ERROR(type, is_write, size) \ 111extern "C" NOINLINE INTERFACE_ATTRIBUTE \ 112void __asan_report_ ## type ## size(uptr addr) { \ 113 GET_CALLER_PC_BP_SP; \ 114 ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \ 115} \ 116extern "C" NOINLINE INTERFACE_ATTRIBUTE \ 117void __asan_report_exp_ ## type ## size(uptr addr, u32 exp) { \ 118 GET_CALLER_PC_BP_SP; \ 119 ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \ 120} \ 121extern "C" NOINLINE INTERFACE_ATTRIBUTE \ 122void __asan_report_ ## type ## size ## _noabort(uptr addr) { \ 123 GET_CALLER_PC_BP_SP; \ 124 ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \ 125} \ 126 127ASAN_REPORT_ERROR(load, false, 1) 128ASAN_REPORT_ERROR(load, false, 2) 129ASAN_REPORT_ERROR(load, false, 4) 130ASAN_REPORT_ERROR(load, false, 8) 131ASAN_REPORT_ERROR(load, false, 16) 132ASAN_REPORT_ERROR(store, true, 1) 133ASAN_REPORT_ERROR(store, true, 2) 134ASAN_REPORT_ERROR(store, true, 4) 135ASAN_REPORT_ERROR(store, true, 8) 136ASAN_REPORT_ERROR(store, true, 16) 137 138#define ASAN_REPORT_ERROR_N(type, is_write) \ 139extern "C" NOINLINE INTERFACE_ATTRIBUTE \ 140void __asan_report_ ## type ## _n(uptr addr, uptr size) { \ 141 GET_CALLER_PC_BP_SP; \ 142 ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \ 143} \ 144extern "C" NOINLINE INTERFACE_ATTRIBUTE \ 145void __asan_report_exp_ ## type ## _n(uptr addr, uptr size, u32 exp) { \ 146 GET_CALLER_PC_BP_SP; \ 147 ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \ 148} \ 149extern "C" NOINLINE INTERFACE_ATTRIBUTE \ 150void __asan_report_ ## type ## _n_noabort(uptr addr, uptr size) { \ 151 GET_CALLER_PC_BP_SP; \ 152 ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \ 153} \ 154 155ASAN_REPORT_ERROR_N(load, false) 156ASAN_REPORT_ERROR_N(store, true) 157 158#define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg, fatal) \ 159 uptr sp = MEM_TO_SHADOW(addr); \ 160 uptr s = size <= SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp) \ 161 : *reinterpret_cast<u16 *>(sp); \ 162 if (UNLIKELY(s)) { \ 163 if (UNLIKELY(size >= SHADOW_GRANULARITY || \ 164 ((s8)((addr & (SHADOW_GRANULARITY - 1)) + size - 1)) >= \ 165 (s8)s)) { \ 166 if (__asan_test_only_reported_buggy_pointer) { \ 167 *__asan_test_only_reported_buggy_pointer = addr; \ 168 } else { \ 169 GET_CALLER_PC_BP_SP; \ 170 ReportGenericError(pc, bp, sp, addr, is_write, size, exp_arg, \ 171 fatal); \ 172 } \ 173 } \ 174 } 175 176#define ASAN_MEMORY_ACCESS_CALLBACK(type, is_write, size) \ 177 extern "C" NOINLINE INTERFACE_ATTRIBUTE \ 178 void __asan_##type##size(uptr addr) { \ 179 ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, true) \ 180 } \ 181 extern "C" NOINLINE INTERFACE_ATTRIBUTE \ 182 void __asan_exp_##type##size(uptr addr, u32 exp) { \ 183 ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp, true) \ 184 } \ 185 extern "C" NOINLINE INTERFACE_ATTRIBUTE \ 186 void __asan_##type##size ## _noabort(uptr addr) { \ 187 ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, false) \ 188 } \ 189 190ASAN_MEMORY_ACCESS_CALLBACK(load, false, 1) 191ASAN_MEMORY_ACCESS_CALLBACK(load, false, 2) 192ASAN_MEMORY_ACCESS_CALLBACK(load, false, 4) 193ASAN_MEMORY_ACCESS_CALLBACK(load, false, 8) 194ASAN_MEMORY_ACCESS_CALLBACK(load, false, 16) 195ASAN_MEMORY_ACCESS_CALLBACK(store, true, 1) 196ASAN_MEMORY_ACCESS_CALLBACK(store, true, 2) 197ASAN_MEMORY_ACCESS_CALLBACK(store, true, 4) 198ASAN_MEMORY_ACCESS_CALLBACK(store, true, 8) 199ASAN_MEMORY_ACCESS_CALLBACK(store, true, 16) 200 201extern "C" 202NOINLINE INTERFACE_ATTRIBUTE 203void __asan_loadN(uptr addr, uptr size) { 204 if (__asan_region_is_poisoned(addr, size)) { 205 GET_CALLER_PC_BP_SP; 206 ReportGenericError(pc, bp, sp, addr, false, size, 0, true); 207 } 208} 209 210extern "C" 211NOINLINE INTERFACE_ATTRIBUTE 212void __asan_exp_loadN(uptr addr, uptr size, u32 exp) { 213 if (__asan_region_is_poisoned(addr, size)) { 214 GET_CALLER_PC_BP_SP; 215 ReportGenericError(pc, bp, sp, addr, false, size, exp, true); 216 } 217} 218 219extern "C" 220NOINLINE INTERFACE_ATTRIBUTE 221void __asan_loadN_noabort(uptr addr, uptr size) { 222 if (__asan_region_is_poisoned(addr, size)) { 223 GET_CALLER_PC_BP_SP; 224 ReportGenericError(pc, bp, sp, addr, false, size, 0, false); 225 } 226} 227 228extern "C" 229NOINLINE INTERFACE_ATTRIBUTE 230void __asan_storeN(uptr addr, uptr size) { 231 if (__asan_region_is_poisoned(addr, size)) { 232 GET_CALLER_PC_BP_SP; 233 ReportGenericError(pc, bp, sp, addr, true, size, 0, true); 234 } 235} 236 237extern "C" 238NOINLINE INTERFACE_ATTRIBUTE 239void __asan_exp_storeN(uptr addr, uptr size, u32 exp) { 240 if (__asan_region_is_poisoned(addr, size)) { 241 GET_CALLER_PC_BP_SP; 242 ReportGenericError(pc, bp, sp, addr, true, size, exp, true); 243 } 244} 245 246extern "C" 247NOINLINE INTERFACE_ATTRIBUTE 248void __asan_storeN_noabort(uptr addr, uptr size) { 249 if (__asan_region_is_poisoned(addr, size)) { 250 GET_CALLER_PC_BP_SP; 251 ReportGenericError(pc, bp, sp, addr, true, size, 0, false); 252 } 253} 254 255// Force the linker to keep the symbols for various ASan interface functions. 256// We want to keep those in the executable in order to let the instrumented 257// dynamic libraries access the symbol even if it is not used by the executable 258// itself. This should help if the build system is removing dead code at link 259// time. 260static NOINLINE void force_interface_symbols() { 261 volatile int fake_condition = 0; // prevent dead condition elimination. 262 // __asan_report_* functions are noreturn, so we need a switch to prevent 263 // the compiler from removing any of them. 264 switch (fake_condition) { 265 case 1: __asan_report_load1(0); break; 266 case 2: __asan_report_load2(0); break; 267 case 3: __asan_report_load4(0); break; 268 case 4: __asan_report_load8(0); break; 269 case 5: __asan_report_load16(0); break; 270 case 6: __asan_report_load_n(0, 0); break; 271 case 7: __asan_report_store1(0); break; 272 case 8: __asan_report_store2(0); break; 273 case 9: __asan_report_store4(0); break; 274 case 10: __asan_report_store8(0); break; 275 case 11: __asan_report_store16(0); break; 276 case 12: __asan_report_store_n(0, 0); break; 277 case 13: __asan_report_exp_load1(0, 0); break; 278 case 14: __asan_report_exp_load2(0, 0); break; 279 case 15: __asan_report_exp_load4(0, 0); break; 280 case 16: __asan_report_exp_load8(0, 0); break; 281 case 17: __asan_report_exp_load16(0, 0); break; 282 case 18: __asan_report_exp_load_n(0, 0, 0); break; 283 case 19: __asan_report_exp_store1(0, 0); break; 284 case 20: __asan_report_exp_store2(0, 0); break; 285 case 21: __asan_report_exp_store4(0, 0); break; 286 case 22: __asan_report_exp_store8(0, 0); break; 287 case 23: __asan_report_exp_store16(0, 0); break; 288 case 24: __asan_report_exp_store_n(0, 0, 0); break; 289 case 25: __asan_register_globals(nullptr, 0); break; 290 case 26: __asan_unregister_globals(nullptr, 0); break; 291 case 27: __asan_set_death_callback(nullptr); break; 292 case 28: __asan_set_error_report_callback(nullptr); break; 293 case 29: __asan_handle_no_return(); break; 294 case 30: __asan_address_is_poisoned(nullptr); break; 295 case 31: __asan_poison_memory_region(nullptr, 0); break; 296 case 32: __asan_unpoison_memory_region(nullptr, 0); break; 297 case 34: __asan_before_dynamic_init(nullptr); break; 298 case 35: __asan_after_dynamic_init(); break; 299 case 36: __asan_poison_stack_memory(0, 0); break; 300 case 37: __asan_unpoison_stack_memory(0, 0); break; 301 case 38: __asan_region_is_poisoned(0, 0); break; 302 case 39: __asan_describe_address(0); break; 303 } 304} 305 306static void asan_atexit() { 307 Printf("AddressSanitizer exit stats:\n"); 308 __asan_print_accumulated_stats(); 309 // Print AsanMappingProfile. 310 for (uptr i = 0; i < kAsanMappingProfileSize; i++) { 311 if (AsanMappingProfile[i] == 0) continue; 312 Printf("asan_mapping.h:%zd -- %zd\n", i, AsanMappingProfile[i]); 313 } 314} 315 316static void InitializeHighMemEnd() { 317#if !ASAN_FIXED_MAPPING 318 kHighMemEnd = GetMaxVirtualAddress(); 319 // Increase kHighMemEnd to make sure it's properly 320 // aligned together with kHighMemBeg: 321 kHighMemEnd |= SHADOW_GRANULARITY * GetPageSizeCached() - 1; 322#endif // !ASAN_FIXED_MAPPING 323 CHECK_EQ((kHighMemBeg % GetPageSizeCached()), 0); 324} 325 326static void ProtectGap(uptr addr, uptr size) { 327 if (!flags()->protect_shadow_gap) 328 return; 329 void *res = MmapNoAccess(addr, size, "shadow gap"); 330 if (addr == (uptr)res) 331 return; 332 // A few pages at the start of the address space can not be protected. 333 // But we really want to protect as much as possible, to prevent this memory 334 // being returned as a result of a non-FIXED mmap(). 335 if (addr == kZeroBaseShadowStart) { 336 uptr step = GetPageSizeCached(); 337 while (size > step && addr < kZeroBaseMaxShadowStart) { 338 addr += step; 339 size -= step; 340 void *res = MmapNoAccess(addr, size, "shadow gap"); 341 if (addr == (uptr)res) 342 return; 343 } 344 } 345 346 Report("ERROR: Failed to protect the shadow gap. " 347 "ASan cannot proceed correctly. ABORTING.\n"); 348 DumpProcessMap(); 349 Die(); 350} 351 352static void PrintAddressSpaceLayout() { 353 Printf("|| `[%p, %p]` || HighMem ||\n", 354 (void*)kHighMemBeg, (void*)kHighMemEnd); 355 Printf("|| `[%p, %p]` || HighShadow ||\n", 356 (void*)kHighShadowBeg, (void*)kHighShadowEnd); 357 if (kMidMemBeg) { 358 Printf("|| `[%p, %p]` || ShadowGap3 ||\n", 359 (void*)kShadowGap3Beg, (void*)kShadowGap3End); 360 Printf("|| `[%p, %p]` || MidMem ||\n", 361 (void*)kMidMemBeg, (void*)kMidMemEnd); 362 Printf("|| `[%p, %p]` || ShadowGap2 ||\n", 363 (void*)kShadowGap2Beg, (void*)kShadowGap2End); 364 Printf("|| `[%p, %p]` || MidShadow ||\n", 365 (void*)kMidShadowBeg, (void*)kMidShadowEnd); 366 } 367 Printf("|| `[%p, %p]` || ShadowGap ||\n", 368 (void*)kShadowGapBeg, (void*)kShadowGapEnd); 369 if (kLowShadowBeg) { 370 Printf("|| `[%p, %p]` || LowShadow ||\n", 371 (void*)kLowShadowBeg, (void*)kLowShadowEnd); 372 Printf("|| `[%p, %p]` || LowMem ||\n", 373 (void*)kLowMemBeg, (void*)kLowMemEnd); 374 } 375 Printf("MemToShadow(shadow): %p %p %p %p", 376 (void*)MEM_TO_SHADOW(kLowShadowBeg), 377 (void*)MEM_TO_SHADOW(kLowShadowEnd), 378 (void*)MEM_TO_SHADOW(kHighShadowBeg), 379 (void*)MEM_TO_SHADOW(kHighShadowEnd)); 380 if (kMidMemBeg) { 381 Printf(" %p %p", 382 (void*)MEM_TO_SHADOW(kMidShadowBeg), 383 (void*)MEM_TO_SHADOW(kMidShadowEnd)); 384 } 385 Printf("\n"); 386 Printf("redzone=%zu\n", (uptr)flags()->redzone); 387 Printf("max_redzone=%zu\n", (uptr)flags()->max_redzone); 388 Printf("quarantine_size_mb=%zuM\n", (uptr)flags()->quarantine_size_mb); 389 Printf("malloc_context_size=%zu\n", 390 (uptr)common_flags()->malloc_context_size); 391 392 Printf("SHADOW_SCALE: %d\n", (int)SHADOW_SCALE); 393 Printf("SHADOW_GRANULARITY: %d\n", (int)SHADOW_GRANULARITY); 394 Printf("SHADOW_OFFSET: 0x%zx\n", (uptr)SHADOW_OFFSET); 395 CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7); 396 if (kMidMemBeg) 397 CHECK(kMidShadowBeg > kLowShadowEnd && 398 kMidMemBeg > kMidShadowEnd && 399 kHighShadowBeg > kMidMemEnd); 400} 401 402static void AsanInitInternal() { 403 if (LIKELY(asan_inited)) return; 404 SanitizerToolName = "AddressSanitizer"; 405 CHECK(!asan_init_is_running && "ASan init calls itself!"); 406 asan_init_is_running = true; 407 408 CacheBinaryName(); 409 410 // Initialize flags. This must be done early, because most of the 411 // initialization steps look at flags(). 412 InitializeFlags(); 413 414 AsanCheckIncompatibleRT(); 415 AsanCheckDynamicRTPrereqs(); 416 417 SetCanPoisonMemory(flags()->poison_heap); 418 SetMallocContextSize(common_flags()->malloc_context_size); 419 420 InitializeHighMemEnd(); 421 422 // Make sure we are not statically linked. 423 AsanDoesNotSupportStaticLinkage(); 424 425 // Install tool-specific callbacks in sanitizer_common. 426 AddDieCallback(AsanDie); 427 SetCheckFailedCallback(AsanCheckFailed); 428 SetPrintfAndReportCallback(AppendToErrorMessageBuffer); 429 430 __sanitizer_set_report_path(common_flags()->log_path); 431 432 // Enable UAR detection, if required. 433 __asan_option_detect_stack_use_after_return = 434 flags()->detect_stack_use_after_return; 435 436 // Re-exec ourselves if we need to set additional env or command line args. 437 MaybeReexec(); 438 439 // Setup internal allocator callback. 440 SetLowLevelAllocateCallback(OnLowLevelAllocate); 441 442 InitializeAsanInterceptors(); 443 444 // Enable system log ("adb logcat") on Android. 445 // Doing this before interceptors are initialized crashes in: 446 // AsanInitInternal -> android_log_write -> __interceptor_strcmp 447 AndroidLogInit(); 448 449 ReplaceSystemMalloc(); 450 451 uptr shadow_start = kLowShadowBeg; 452 if (kLowShadowBeg) 453 shadow_start -= GetMmapGranularity(); 454 bool full_shadow_is_available = 455 MemoryRangeIsAvailable(shadow_start, kHighShadowEnd); 456 457#if SANITIZER_LINUX && defined(__x86_64__) && defined(_LP64) && \ 458 !ASAN_FIXED_MAPPING 459 if (!full_shadow_is_available) { 460 kMidMemBeg = kLowMemEnd < 0x3000000000ULL ? 0x3000000000ULL : 0; 461 kMidMemEnd = kLowMemEnd < 0x3000000000ULL ? 0x4fffffffffULL : 0; 462 } 463#endif 464 465 if (Verbosity()) PrintAddressSpaceLayout(); 466 467 DisableCoreDumperIfNecessary(); 468 469 if (full_shadow_is_available) { 470 // mmap the low shadow plus at least one page at the left. 471 if (kLowShadowBeg) 472 ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, "low shadow"); 473 // mmap the high shadow. 474 ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, "high shadow"); 475 // protect the gap. 476 ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); 477 CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1); 478 } else if (kMidMemBeg && 479 MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) && 480 MemoryRangeIsAvailable(kMidMemEnd + 1, kHighShadowEnd)) { 481 CHECK(kLowShadowBeg != kLowShadowEnd); 482 // mmap the low shadow plus at least one page at the left. 483 ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, "low shadow"); 484 // mmap the mid shadow. 485 ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd, "mid shadow"); 486 // mmap the high shadow. 487 ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, "high shadow"); 488 // protect the gaps. 489 ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); 490 ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1); 491 ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1); 492 } else { 493 Report("Shadow memory range interleaves with an existing memory mapping. " 494 "ASan cannot proceed correctly. ABORTING.\n"); 495 Report("ASan shadow was supposed to be located in the [%p-%p] range.\n", 496 shadow_start, kHighShadowEnd); 497 DumpProcessMap(); 498 Die(); 499 } 500 501 AsanTSDInit(PlatformTSDDtor); 502 InstallDeadlySignalHandlers(AsanOnDeadlySignal); 503 504 AllocatorOptions allocator_options; 505 allocator_options.SetFrom(flags(), common_flags()); 506 InitializeAllocator(allocator_options); 507 508 MaybeStartBackgroudThread(); 509 SetSoftRssLimitExceededCallback(AsanSoftRssLimitExceededCallback); 510 511 // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited 512 // should be set to 1 prior to initializing the threads. 513 asan_inited = 1; 514 asan_init_is_running = false; 515 516 if (flags()->atexit) 517 Atexit(asan_atexit); 518 519 InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); 520 521 // Now that ASan runtime is (mostly) initialized, deactivate it if 522 // necessary, so that it can be re-activated when requested. 523 if (flags()->start_deactivated) 524 AsanDeactivate(); 525 526 // interceptors 527 InitTlsSize(); 528 529 // Create main thread. 530 AsanThread *main_thread = AsanThread::Create( 531 /* start_routine */ nullptr, /* arg */ nullptr, /* parent_tid */ 0, 532 /* stack */ nullptr, /* detached */ true); 533 CHECK_EQ(0, main_thread->tid()); 534 SetCurrentThread(main_thread); 535 main_thread->ThreadStart(internal_getpid(), 536 /* signal_thread_is_registered */ nullptr); 537 force_interface_symbols(); // no-op. 538 SanitizerInitializeUnwinder(); 539 540#if CAN_SANITIZE_LEAKS 541 __lsan::InitCommonLsan(); 542 if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) { 543 Atexit(__lsan::DoLeakCheck); 544 } 545#endif // CAN_SANITIZE_LEAKS 546 547#if CAN_SANITIZE_UB 548 __ubsan::InitAsPlugin(); 549#endif 550 551 InitializeSuppressions(); 552 553 VReport(1, "AddressSanitizer Init done\n"); 554} 555 556// Initialize as requested from some part of ASan runtime library (interceptors, 557// allocator, etc). 558void AsanInitFromRtl() { 559 AsanInitInternal(); 560} 561 562#if ASAN_DYNAMIC 563// Initialize runtime in case it's LD_PRELOAD-ed into unsanitized executable 564// (and thus normal initializers from .preinit_array or modules haven't run). 565 566class AsanInitializer { 567public: // NOLINT 568 AsanInitializer() { 569 AsanInitFromRtl(); 570 } 571}; 572 573static AsanInitializer asan_initializer; 574#endif // ASAN_DYNAMIC 575 576} // namespace __asan 577 578// ---------------------- Interface ---------------- {{{1 579using namespace __asan; // NOLINT 580 581void NOINLINE __asan_handle_no_return() { 582 int local_stack; 583 AsanThread *curr_thread = GetCurrentThread(); 584 uptr PageSize = GetPageSizeCached(); 585 uptr top, bottom; 586 if (curr_thread) { 587 top = curr_thread->stack_top(); 588 bottom = ((uptr)&local_stack - PageSize) & ~(PageSize - 1); 589 } else { 590 // If we haven't seen this thread, try asking the OS for stack bounds. 591 uptr tls_addr, tls_size, stack_size; 592 GetThreadStackAndTls(/*main=*/false, &bottom, &stack_size, &tls_addr, 593 &tls_size); 594 top = bottom + stack_size; 595 } 596 static const uptr kMaxExpectedCleanupSize = 64 << 20; // 64M 597 if (top - bottom > kMaxExpectedCleanupSize) { 598 static bool reported_warning = false; 599 if (reported_warning) 600 return; 601 reported_warning = true; 602 Report("WARNING: ASan is ignoring requested __asan_handle_no_return: " 603 "stack top: %p; bottom %p; size: %p (%zd)\n" 604 "False positive error reports may follow\n" 605 "For details see " 606 "http://code.google.com/p/address-sanitizer/issues/detail?id=189\n", 607 top, bottom, top - bottom, top - bottom); 608 return; 609 } 610 PoisonShadow(bottom, top - bottom, 0); 611 if (curr_thread && curr_thread->has_fake_stack()) 612 curr_thread->fake_stack()->HandleNoReturn(); 613} 614 615void NOINLINE __asan_set_death_callback(void (*callback)(void)) { 616 SetUserDieCallback(callback); 617} 618 619// Initialize as requested from instrumented application code. 620// We use this call as a trigger to wake up ASan from deactivated state. 621void __asan_init() { 622 AsanActivate(); 623 AsanInitInternal(); 624} 625 626void __asan_version_mismatch_check() { 627 // Do nothing. 628} 629