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