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