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_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_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 31 int __asan_option_detect_stack_use_after_return; // Global interface symbol. 32 uptr *__asan_test_only_reported_buggy_pointer; // Used only for testing asan. 33 34 namespace __asan { 35 36 uptr AsanMappingProfile[kAsanMappingProfileSize]; 37 38 static void AsanDie() { 39 static atomic_uint32_t num_calls; 40 if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) { 41 // Don't die twice - run a busy loop. 42 while (1) { } 43 } 44 if (flags()->sleep_before_dying) { 45 Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying); 46 SleepForSeconds(flags()->sleep_before_dying); 47 } 48 if (flags()->unmap_shadow_on_exit) { 49 if (kMidMemBeg) { 50 UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg); 51 UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd); 52 } else { 53 UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg); 54 } 55 } 56 if (common_flags()->coverage) 57 __sanitizer_cov_dump(); 58 if (death_callback) 59 death_callback(); 60 if (flags()->abort_on_error) 61 Abort(); 62 internal__exit(flags()->exitcode); 63 } 64 65 static void AsanCheckFailed(const char *file, int line, const char *cond, 66 u64 v1, u64 v2) { 67 Report("AddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", file, 68 line, cond, (uptr)v1, (uptr)v2); 69 // FIXME: check for infinite recursion without a thread-local counter here. 70 PRINT_CURRENT_STACK(); 71 Die(); 72 } 73 74 // -------------------------- Flags ------------------------- {{{1 75 static const int kDefaultMallocContextSize = 30; 76 77 Flags asan_flags_dont_use_directly; // use via flags(). 78 79 static const char *MaybeCallAsanDefaultOptions() { 80 return (&__asan_default_options) ? __asan_default_options() : ""; 81 } 82 83 static const char *MaybeUseAsanDefaultOptionsCompileDefinition() { 84 #ifdef ASAN_DEFAULT_OPTIONS 85 // Stringize the macro value. 86 # define ASAN_STRINGIZE(x) #x 87 # define ASAN_STRINGIZE_OPTIONS(options) ASAN_STRINGIZE(options) 88 return ASAN_STRINGIZE_OPTIONS(ASAN_DEFAULT_OPTIONS); 89 #else 90 return ""; 91 #endif 92 } 93 94 static void ParseFlagsFromString(Flags *f, const char *str) { 95 CommonFlags *cf = common_flags(); 96 ParseCommonFlagsFromString(cf, str); 97 CHECK((uptr)cf->malloc_context_size <= kStackTraceMax); 98 // Please write meaningful flag descriptions when adding new flags. 99 ParseFlag(str, &f->quarantine_size, "quarantine_size", 100 "Size (in bytes) of quarantine used to detect use-after-free " 101 "errors. Lower value may reduce memory usage but increase the " 102 "chance of false negatives."); 103 ParseFlag(str, &f->redzone, "redzone", 104 "Minimal size (in bytes) of redzones around heap objects. " 105 "Requirement: redzone >= 16, is a power of two."); 106 ParseFlag(str, &f->max_redzone, "max_redzone", 107 "Maximal size (in bytes) of redzones around heap objects."); 108 CHECK_GE(f->redzone, 16); 109 CHECK_GE(f->max_redzone, f->redzone); 110 CHECK_LE(f->max_redzone, 2048); 111 CHECK(IsPowerOfTwo(f->redzone)); 112 CHECK(IsPowerOfTwo(f->max_redzone)); 113 114 ParseFlag(str, &f->debug, "debug", 115 "If set, prints some debugging information and does additional checks."); 116 ParseFlag(str, &f->report_globals, "report_globals", 117 "Controls the way to handle globals (0 - don't detect buffer overflow on " 118 "globals, 1 - detect buffer overflow, 2 - print data about registered " 119 "globals)."); 120 121 ParseFlag(str, &f->check_initialization_order, 122 "check_initialization_order", 123 "If set, attempts to catch initialization order issues."); 124 125 ParseFlag(str, &f->replace_str, "replace_str", 126 "If set, uses custom wrappers and replacements for libc string functions " 127 "to find more errors."); 128 129 ParseFlag(str, &f->replace_intrin, "replace_intrin", 130 "If set, uses custom wrappers for memset/memcpy/memmove intinsics."); 131 ParseFlag(str, &f->mac_ignore_invalid_free, "mac_ignore_invalid_free", 132 "Ignore invalid free() calls to work around some bugs. Used on OS X " 133 "only."); 134 ParseFlag(str, &f->detect_stack_use_after_return, 135 "detect_stack_use_after_return", 136 "Enables stack-use-after-return checking at run-time."); 137 ParseFlag(str, &f->min_uar_stack_size_log, "min_uar_stack_size_log", 138 "Minimum fake stack size log."); 139 ParseFlag(str, &f->max_uar_stack_size_log, "max_uar_stack_size_log", 140 "Maximum fake stack size log."); 141 ParseFlag(str, &f->uar_noreserve, "uar_noreserve", 142 "Use mmap with 'norserve' flag to allocate fake stack."); 143 ParseFlag(str, &f->max_malloc_fill_size, "max_malloc_fill_size", 144 "ASan allocator flag. max_malloc_fill_size is the maximal amount of " 145 "bytes that will be filled with malloc_fill_byte on malloc."); 146 ParseFlag(str, &f->malloc_fill_byte, "malloc_fill_byte", 147 "Value used to fill the newly allocated memory."); 148 ParseFlag(str, &f->exitcode, "exitcode", 149 "Override the program exit status if the tool found an error."); 150 ParseFlag(str, &f->allow_user_poisoning, "allow_user_poisoning", 151 "If set, user may manually mark memory regions as poisoned or " 152 "unpoisoned."); 153 ParseFlag(str, &f->sleep_before_dying, "sleep_before_dying", 154 "Number of seconds to sleep between printing an error report and " 155 "terminating the program. Useful for debugging purposes (e.g. when one " 156 "needs to attach gdb)."); 157 158 ParseFlag(str, &f->check_malloc_usable_size, "check_malloc_usable_size", 159 "Allows the users to work around the bug in Nvidia drivers prior to " 160 "295.*."); 161 162 ParseFlag(str, &f->unmap_shadow_on_exit, "unmap_shadow_on_exit", 163 "If set, explicitly unmaps the (huge) shadow at exit."); 164 ParseFlag(str, &f->abort_on_error, "abort_on_error", 165 "If set, the tool calls abort() instead of _exit() after printing the " 166 "error report."); 167 ParseFlag(str, &f->print_stats, "print_stats", 168 "Print various statistics after printing an error message or if " 169 "atexit=1."); 170 ParseFlag(str, &f->print_legend, "print_legend", 171 "Print the legend for the shadow bytes."); 172 ParseFlag(str, &f->atexit, "atexit", 173 "If set, prints ASan exit stats even after program terminates " 174 "successfully."); 175 176 ParseFlag(str, &f->disable_core, "disable_core", 177 "Disable core dumping. By default, disable_core=1 on 64-bit to avoid " 178 "dumping a 16T+ core file. " 179 "Ignored on OSes that don't dump core by default."); 180 181 ParseFlag(str, &f->allow_reexec, "allow_reexec", 182 "Allow the tool to re-exec the program. This may interfere badly with " 183 "the debugger."); 184 185 ParseFlag(str, &f->print_full_thread_history, 186 "print_full_thread_history", 187 "If set, prints thread creation stacks for the threads involved in the " 188 "report and their ancestors up to the main thread."); 189 190 ParseFlag(str, &f->poison_heap, "poison_heap", 191 "Poison (or not) the heap memory on [de]allocation. Zero value is useful " 192 "for benchmarking the allocator or instrumentator."); 193 194 ParseFlag(str, &f->poison_partial, "poison_partial", 195 "If true, poison partially addressable 8-byte aligned words " 196 "(default=true). This flag affects heap and global buffers, but not " 197 "stack buffers."); 198 199 ParseFlag(str, &f->alloc_dealloc_mismatch, "alloc_dealloc_mismatch", 200 "Report errors on malloc/delete, new/free, new/delete[], etc."); 201 ParseFlag(str, &f->strict_memcmp, "strict_memcmp", 202 "If true, assume that memcmp(p1, p2, n) always reads n bytes before " 203 "comparing p1 and p2."); 204 205 ParseFlag(str, &f->strict_init_order, "strict_init_order", 206 "If true, assume that dynamic initializers can never access globals from " 207 "other modules, even if the latter are already initialized."); 208 209 ParseFlag(str, &f->start_deactivated, "start_deactivated", 210 "If true, ASan tweaks a bunch of other flags (quarantine, redzone, heap " 211 "poisoning) to reduce memory consumption as much as possible, and " 212 "restores them to original values when the first instrumented module is " 213 "loaded into the process. This is mainly intended to be used on " 214 "Android. "); 215 216 ParseFlag(str, &f->detect_invalid_pointer_pairs, 217 "detect_invalid_pointer_pairs", 218 "If non-zero, try to detect operations like <, <=, >, >= and - on " 219 "invalid pointer pairs (e.g. when pointers belong to different objects). " 220 "The bigger the value the harder we try."); 221 222 ParseFlag(str, &f->detect_container_overflow, 223 "detect_container_overflow", 224 "If true, honor the container overflow annotations. " 225 "See https://code.google.com/p/address-sanitizer/wiki/ContainerOverflow"); 226 227 ParseFlag(str, &f->detect_odr_violation, "detect_odr_violation", 228 "If >=2, detect violation of One-Definition-Rule (ODR); " 229 "If ==1, detect ODR-violation only if the two variables " 230 "have different sizes"); 231 } 232 233 void InitializeFlags(Flags *f, const char *env) { 234 CommonFlags *cf = common_flags(); 235 SetCommonFlagsDefaults(cf); 236 cf->detect_leaks = CAN_SANITIZE_LEAKS; 237 cf->external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH"); 238 cf->malloc_context_size = kDefaultMallocContextSize; 239 cf->intercept_tls_get_addr = true; 240 cf->coverage = false; 241 242 internal_memset(f, 0, sizeof(*f)); 243 f->quarantine_size = (ASAN_LOW_MEMORY) ? 1UL << 26 : 1UL << 28; 244 f->redzone = 16; 245 f->max_redzone = 2048; 246 f->debug = false; 247 f->report_globals = 1; 248 f->check_initialization_order = false; 249 f->replace_str = true; 250 f->replace_intrin = true; 251 f->mac_ignore_invalid_free = false; 252 f->detect_stack_use_after_return = false; // Also needs the compiler flag. 253 f->min_uar_stack_size_log = 16; // We can't do smaller anyway. 254 f->max_uar_stack_size_log = 20; // 1Mb per size class, i.e. ~11Mb per thread. 255 f->uar_noreserve = false; 256 f->max_malloc_fill_size = 0x1000; // By default, fill only the first 4K. 257 f->malloc_fill_byte = 0xbe; 258 f->exitcode = ASAN_DEFAULT_FAILURE_EXITCODE; 259 f->allow_user_poisoning = true; 260 f->sleep_before_dying = 0; 261 f->check_malloc_usable_size = true; 262 f->unmap_shadow_on_exit = false; 263 f->abort_on_error = false; 264 f->print_stats = false; 265 f->print_legend = true; 266 f->atexit = false; 267 f->disable_core = (SANITIZER_WORDSIZE == 64); 268 f->allow_reexec = true; 269 f->print_full_thread_history = true; 270 f->poison_heap = true; 271 f->poison_partial = true; 272 // Turn off alloc/dealloc mismatch checker on Mac and Windows for now. 273 // https://code.google.com/p/address-sanitizer/issues/detail?id=131 274 // https://code.google.com/p/address-sanitizer/issues/detail?id=309 275 // TODO(glider,timurrrr): Fix known issues and enable this back. 276 f->alloc_dealloc_mismatch = (SANITIZER_MAC == 0) && (SANITIZER_WINDOWS == 0); 277 f->strict_memcmp = true; 278 f->strict_init_order = false; 279 f->start_deactivated = false; 280 f->detect_invalid_pointer_pairs = 0; 281 f->detect_container_overflow = true; 282 f->detect_odr_violation = 2; 283 284 // Override from compile definition. 285 ParseFlagsFromString(f, MaybeUseAsanDefaultOptionsCompileDefinition()); 286 287 // Override from user-specified string. 288 ParseFlagsFromString(f, MaybeCallAsanDefaultOptions()); 289 VReport(1, "Using the defaults from __asan_default_options: %s\n", 290 MaybeCallAsanDefaultOptions()); 291 292 // Override from command line. 293 ParseFlagsFromString(f, env); 294 if (common_flags()->help) { 295 PrintFlagDescriptions(); 296 } 297 298 if (!CAN_SANITIZE_LEAKS && cf->detect_leaks) { 299 Report("%s: detect_leaks is not supported on this platform.\n", 300 SanitizerToolName); 301 cf->detect_leaks = false; 302 } 303 304 // Make "strict_init_order" imply "check_initialization_order". 305 // TODO(samsonov): Use a single runtime flag for an init-order checker. 306 if (f->strict_init_order) { 307 f->check_initialization_order = true; 308 } 309 } 310 311 // Parse flags that may change between startup and activation. 312 // On Android they come from a system property. 313 // On other platforms this is no-op. 314 void ParseExtraActivationFlags() { 315 char buf[100]; 316 GetExtraActivationFlags(buf, sizeof(buf)); 317 ParseFlagsFromString(flags(), buf); 318 if (buf[0] != '\0') 319 VReport(1, "Extra activation flags: %s\n", buf); 320 } 321 322 // -------------------------- Globals --------------------- {{{1 323 int asan_inited; 324 bool asan_init_is_running; 325 void (*death_callback)(void); 326 327 #if !ASAN_FIXED_MAPPING 328 uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; 329 #endif 330 331 // -------------------------- Misc ---------------- {{{1 332 void ShowStatsAndAbort() { 333 __asan_print_accumulated_stats(); 334 Die(); 335 } 336 337 // ---------------------- mmap -------------------- {{{1 338 // Reserve memory range [beg, end]. 339 static void ReserveShadowMemoryRange(uptr beg, uptr end) { 340 CHECK_EQ((beg % GetPageSizeCached()), 0); 341 CHECK_EQ(((end + 1) % GetPageSizeCached()), 0); 342 uptr size = end - beg + 1; 343 DecreaseTotalMmap(size); // Don't count the shadow against mmap_limit_mb. 344 void *res = MmapFixedNoReserve(beg, size); 345 if (res != (void*)beg) { 346 Report("ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. " 347 "Perhaps you're using ulimit -v\n", size); 348 Abort(); 349 } 350 } 351 352 // --------------- LowLevelAllocateCallbac ---------- {{{1 353 static void OnLowLevelAllocate(uptr ptr, uptr size) { 354 PoisonShadow(ptr, size, kAsanInternalHeapMagic); 355 } 356 357 // -------------------------- Run-time entry ------------------- {{{1 358 // exported functions 359 #define ASAN_REPORT_ERROR(type, is_write, size) \ 360 extern "C" NOINLINE INTERFACE_ATTRIBUTE \ 361 void __asan_report_ ## type ## size(uptr addr); \ 362 void __asan_report_ ## type ## size(uptr addr) { \ 363 GET_CALLER_PC_BP_SP; \ 364 __asan_report_error(pc, bp, sp, addr, is_write, size); \ 365 } 366 367 ASAN_REPORT_ERROR(load, false, 1) 368 ASAN_REPORT_ERROR(load, false, 2) 369 ASAN_REPORT_ERROR(load, false, 4) 370 ASAN_REPORT_ERROR(load, false, 8) 371 ASAN_REPORT_ERROR(load, false, 16) 372 ASAN_REPORT_ERROR(store, true, 1) 373 ASAN_REPORT_ERROR(store, true, 2) 374 ASAN_REPORT_ERROR(store, true, 4) 375 ASAN_REPORT_ERROR(store, true, 8) 376 ASAN_REPORT_ERROR(store, true, 16) 377 378 #define ASAN_REPORT_ERROR_N(type, is_write) \ 379 extern "C" NOINLINE INTERFACE_ATTRIBUTE \ 380 void __asan_report_ ## type ## _n(uptr addr, uptr size); \ 381 void __asan_report_ ## type ## _n(uptr addr, uptr size) { \ 382 GET_CALLER_PC_BP_SP; \ 383 __asan_report_error(pc, bp, sp, addr, is_write, size); \ 384 } 385 386 ASAN_REPORT_ERROR_N(load, false) 387 ASAN_REPORT_ERROR_N(store, true) 388 389 #define ASAN_MEMORY_ACCESS_CALLBACK(type, is_write, size) \ 390 extern "C" NOINLINE INTERFACE_ATTRIBUTE void __asan_##type##size(uptr addr); \ 391 void __asan_##type##size(uptr addr) { \ 392 uptr sp = MEM_TO_SHADOW(addr); \ 393 uptr s = size <= SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp) \ 394 : *reinterpret_cast<u16 *>(sp); \ 395 if (UNLIKELY(s)) { \ 396 if (UNLIKELY(size >= SHADOW_GRANULARITY || \ 397 ((s8)((addr & (SHADOW_GRANULARITY - 1)) + size - 1)) >= \ 398 (s8)s)) { \ 399 if (__asan_test_only_reported_buggy_pointer) { \ 400 *__asan_test_only_reported_buggy_pointer = addr; \ 401 } else { \ 402 GET_CALLER_PC_BP_SP; \ 403 __asan_report_error(pc, bp, sp, addr, is_write, size); \ 404 } \ 405 } \ 406 } \ 407 } 408 409 ASAN_MEMORY_ACCESS_CALLBACK(load, false, 1) 410 ASAN_MEMORY_ACCESS_CALLBACK(load, false, 2) 411 ASAN_MEMORY_ACCESS_CALLBACK(load, false, 4) 412 ASAN_MEMORY_ACCESS_CALLBACK(load, false, 8) 413 ASAN_MEMORY_ACCESS_CALLBACK(load, false, 16) 414 ASAN_MEMORY_ACCESS_CALLBACK(store, true, 1) 415 ASAN_MEMORY_ACCESS_CALLBACK(store, true, 2) 416 ASAN_MEMORY_ACCESS_CALLBACK(store, true, 4) 417 ASAN_MEMORY_ACCESS_CALLBACK(store, true, 8) 418 ASAN_MEMORY_ACCESS_CALLBACK(store, true, 16) 419 420 extern "C" 421 NOINLINE INTERFACE_ATTRIBUTE void __asan_loadN(uptr addr, uptr size) { 422 if (__asan_region_is_poisoned(addr, size)) { 423 GET_CALLER_PC_BP_SP; 424 __asan_report_error(pc, bp, sp, addr, false, size); 425 } 426 } 427 428 extern "C" 429 NOINLINE INTERFACE_ATTRIBUTE void __asan_storeN(uptr addr, uptr size) { 430 if (__asan_region_is_poisoned(addr, size)) { 431 GET_CALLER_PC_BP_SP; 432 __asan_report_error(pc, bp, sp, addr, true, size); 433 } 434 } 435 436 // Force the linker to keep the symbols for various ASan interface functions. 437 // We want to keep those in the executable in order to let the instrumented 438 // dynamic libraries access the symbol even if it is not used by the executable 439 // itself. This should help if the build system is removing dead code at link 440 // time. 441 static NOINLINE void force_interface_symbols() { 442 volatile int fake_condition = 0; // prevent dead condition elimination. 443 // __asan_report_* functions are noreturn, so we need a switch to prevent 444 // the compiler from removing any of them. 445 switch (fake_condition) { 446 case 1: __asan_report_load1(0); break; 447 case 2: __asan_report_load2(0); break; 448 case 3: __asan_report_load4(0); break; 449 case 4: __asan_report_load8(0); break; 450 case 5: __asan_report_load16(0); break; 451 case 6: __asan_report_store1(0); break; 452 case 7: __asan_report_store2(0); break; 453 case 8: __asan_report_store4(0); break; 454 case 9: __asan_report_store8(0); break; 455 case 10: __asan_report_store16(0); break; 456 case 12: __asan_register_globals(0, 0); break; 457 case 13: __asan_unregister_globals(0, 0); break; 458 case 14: __asan_set_death_callback(0); break; 459 case 15: __asan_set_error_report_callback(0); break; 460 case 16: __asan_handle_no_return(); break; 461 case 17: __asan_address_is_poisoned(0); break; 462 case 18: __asan_get_allocated_size(0); break; 463 case 19: __asan_get_current_allocated_bytes(); break; 464 case 20: __asan_get_estimated_allocated_size(0); break; 465 case 21: __asan_get_free_bytes(); break; 466 case 22: __asan_get_heap_size(); break; 467 case 23: __asan_get_ownership(0); break; 468 case 24: __asan_get_unmapped_bytes(); break; 469 case 25: __asan_poison_memory_region(0, 0); break; 470 case 26: __asan_unpoison_memory_region(0, 0); break; 471 case 27: __asan_set_error_exit_code(0); break; 472 case 30: __asan_before_dynamic_init(0); break; 473 case 31: __asan_after_dynamic_init(); break; 474 case 32: __asan_poison_stack_memory(0, 0); break; 475 case 33: __asan_unpoison_stack_memory(0, 0); break; 476 case 34: __asan_region_is_poisoned(0, 0); break; 477 case 35: __asan_describe_address(0); break; 478 } 479 } 480 481 static void asan_atexit() { 482 Printf("AddressSanitizer exit stats:\n"); 483 __asan_print_accumulated_stats(); 484 // Print AsanMappingProfile. 485 for (uptr i = 0; i < kAsanMappingProfileSize; i++) { 486 if (AsanMappingProfile[i] == 0) continue; 487 Printf("asan_mapping.h:%zd -- %zd\n", i, AsanMappingProfile[i]); 488 } 489 } 490 491 static void InitializeHighMemEnd() { 492 #if !ASAN_FIXED_MAPPING 493 kHighMemEnd = GetMaxVirtualAddress(); 494 // Increase kHighMemEnd to make sure it's properly 495 // aligned together with kHighMemBeg: 496 kHighMemEnd |= SHADOW_GRANULARITY * GetPageSizeCached() - 1; 497 #endif // !ASAN_FIXED_MAPPING 498 CHECK_EQ((kHighMemBeg % GetPageSizeCached()), 0); 499 } 500 501 static void ProtectGap(uptr a, uptr size) { 502 CHECK_EQ(a, (uptr)Mprotect(a, size)); 503 } 504 505 static void PrintAddressSpaceLayout() { 506 Printf("|| `[%p, %p]` || HighMem ||\n", 507 (void*)kHighMemBeg, (void*)kHighMemEnd); 508 Printf("|| `[%p, %p]` || HighShadow ||\n", 509 (void*)kHighShadowBeg, (void*)kHighShadowEnd); 510 if (kMidMemBeg) { 511 Printf("|| `[%p, %p]` || ShadowGap3 ||\n", 512 (void*)kShadowGap3Beg, (void*)kShadowGap3End); 513 Printf("|| `[%p, %p]` || MidMem ||\n", 514 (void*)kMidMemBeg, (void*)kMidMemEnd); 515 Printf("|| `[%p, %p]` || ShadowGap2 ||\n", 516 (void*)kShadowGap2Beg, (void*)kShadowGap2End); 517 Printf("|| `[%p, %p]` || MidShadow ||\n", 518 (void*)kMidShadowBeg, (void*)kMidShadowEnd); 519 } 520 Printf("|| `[%p, %p]` || ShadowGap ||\n", 521 (void*)kShadowGapBeg, (void*)kShadowGapEnd); 522 if (kLowShadowBeg) { 523 Printf("|| `[%p, %p]` || LowShadow ||\n", 524 (void*)kLowShadowBeg, (void*)kLowShadowEnd); 525 Printf("|| `[%p, %p]` || LowMem ||\n", 526 (void*)kLowMemBeg, (void*)kLowMemEnd); 527 } 528 Printf("MemToShadow(shadow): %p %p %p %p", 529 (void*)MEM_TO_SHADOW(kLowShadowBeg), 530 (void*)MEM_TO_SHADOW(kLowShadowEnd), 531 (void*)MEM_TO_SHADOW(kHighShadowBeg), 532 (void*)MEM_TO_SHADOW(kHighShadowEnd)); 533 if (kMidMemBeg) { 534 Printf(" %p %p", 535 (void*)MEM_TO_SHADOW(kMidShadowBeg), 536 (void*)MEM_TO_SHADOW(kMidShadowEnd)); 537 } 538 Printf("\n"); 539 Printf("redzone=%zu\n", (uptr)flags()->redzone); 540 Printf("max_redzone=%zu\n", (uptr)flags()->max_redzone); 541 Printf("quarantine_size=%zuM\n", (uptr)flags()->quarantine_size >> 20); 542 Printf("malloc_context_size=%zu\n", 543 (uptr)common_flags()->malloc_context_size); 544 545 Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE); 546 Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY); 547 Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET); 548 CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7); 549 if (kMidMemBeg) 550 CHECK(kMidShadowBeg > kLowShadowEnd && 551 kMidMemBeg > kMidShadowEnd && 552 kHighShadowBeg > kMidMemEnd); 553 } 554 555 static void AsanInitInternal() { 556 if (LIKELY(asan_inited)) return; 557 SanitizerToolName = "AddressSanitizer"; 558 CHECK(!asan_init_is_running && "ASan init calls itself!"); 559 asan_init_is_running = true; 560 561 // Initialize flags. This must be done early, because most of the 562 // initialization steps look at flags(). 563 const char *options = GetEnv("ASAN_OPTIONS"); 564 InitializeFlags(flags(), options); 565 566 InitializeHighMemEnd(); 567 568 // Make sure we are not statically linked. 569 AsanDoesNotSupportStaticLinkage(); 570 571 // Install tool-specific callbacks in sanitizer_common. 572 SetDieCallback(AsanDie); 573 SetCheckFailedCallback(AsanCheckFailed); 574 SetPrintfAndReportCallback(AppendToErrorMessageBuffer); 575 576 if (!flags()->start_deactivated) 577 ParseExtraActivationFlags(); 578 579 __sanitizer_set_report_path(common_flags()->log_path); 580 __asan_option_detect_stack_use_after_return = 581 flags()->detect_stack_use_after_return; 582 CHECK_LE(flags()->min_uar_stack_size_log, flags()->max_uar_stack_size_log); 583 584 if (options) { 585 VReport(1, "Parsed ASAN_OPTIONS: %s\n", options); 586 } 587 588 if (flags()->start_deactivated) 589 AsanStartDeactivated(); 590 591 // Re-exec ourselves if we need to set additional env or command line args. 592 MaybeReexec(); 593 594 // Setup internal allocator callback. 595 SetLowLevelAllocateCallback(OnLowLevelAllocate); 596 597 InitializeAsanInterceptors(); 598 599 ReplaceSystemMalloc(); 600 601 uptr shadow_start = kLowShadowBeg; 602 if (kLowShadowBeg) 603 shadow_start -= GetMmapGranularity(); 604 bool full_shadow_is_available = 605 MemoryRangeIsAvailable(shadow_start, kHighShadowEnd); 606 607 #if SANITIZER_LINUX && defined(__x86_64__) && !ASAN_FIXED_MAPPING 608 if (!full_shadow_is_available) { 609 kMidMemBeg = kLowMemEnd < 0x3000000000ULL ? 0x3000000000ULL : 0; 610 kMidMemEnd = kLowMemEnd < 0x3000000000ULL ? 0x4fffffffffULL : 0; 611 } 612 #endif 613 614 if (common_flags()->verbosity) 615 PrintAddressSpaceLayout(); 616 617 if (flags()->disable_core) { 618 DisableCoreDumper(); 619 } 620 621 if (full_shadow_is_available) { 622 // mmap the low shadow plus at least one page at the left. 623 if (kLowShadowBeg) 624 ReserveShadowMemoryRange(shadow_start, kLowShadowEnd); 625 // mmap the high shadow. 626 ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd); 627 // protect the gap. 628 ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); 629 CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1); 630 } else if (kMidMemBeg && 631 MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) && 632 MemoryRangeIsAvailable(kMidMemEnd + 1, kHighShadowEnd)) { 633 CHECK(kLowShadowBeg != kLowShadowEnd); 634 // mmap the low shadow plus at least one page at the left. 635 ReserveShadowMemoryRange(shadow_start, kLowShadowEnd); 636 // mmap the mid shadow. 637 ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd); 638 // mmap the high shadow. 639 ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd); 640 // protect the gaps. 641 ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); 642 ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1); 643 ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1); 644 } else { 645 Report("Shadow memory range interleaves with an existing memory mapping. " 646 "ASan cannot proceed correctly. ABORTING.\n"); 647 DumpProcessMap(); 648 Die(); 649 } 650 651 AsanTSDInit(PlatformTSDDtor); 652 InstallDeadlySignalHandlers(AsanOnSIGSEGV); 653 654 // Allocator should be initialized before starting external symbolizer, as 655 // fork() on Mac locks the allocator. 656 InitializeAllocator(); 657 658 Symbolizer::Init(common_flags()->external_symbolizer_path); 659 660 // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited 661 // should be set to 1 prior to initializing the threads. 662 asan_inited = 1; 663 asan_init_is_running = false; 664 665 if (flags()->atexit) 666 Atexit(asan_atexit); 667 668 if (common_flags()->coverage) { 669 __sanitizer_cov_init(); 670 Atexit(__sanitizer_cov_dump); 671 } 672 673 // interceptors 674 InitTlsSize(); 675 676 // Create main thread. 677 AsanThread *main_thread = AsanThread::Create(0, 0); 678 CreateThreadContextArgs create_main_args = { main_thread, 0 }; 679 u32 main_tid = asanThreadRegistry().CreateThread( 680 0, true, 0, &create_main_args); 681 CHECK_EQ(0, main_tid); 682 SetCurrentThread(main_thread); 683 main_thread->ThreadStart(internal_getpid()); 684 force_interface_symbols(); // no-op. 685 SanitizerInitializeUnwinder(); 686 687 #if CAN_SANITIZE_LEAKS 688 __lsan::InitCommonLsan(); 689 if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) { 690 Atexit(__lsan::DoLeakCheck); 691 } 692 #endif // CAN_SANITIZE_LEAKS 693 694 VReport(1, "AddressSanitizer Init done\n"); 695 } 696 697 // Initialize as requested from some part of ASan runtime library (interceptors, 698 // allocator, etc). 699 void AsanInitFromRtl() { 700 AsanInitInternal(); 701 } 702 703 #if ASAN_DYNAMIC 704 // Initialize runtime in case it's LD_PRELOAD-ed into unsanitized executable 705 // (and thus normal initializer from .preinit_array haven't run). 706 707 class AsanInitializer { 708 public: // NOLINT 709 AsanInitializer() { 710 AsanCheckIncompatibleRT(); 711 AsanCheckDynamicRTPrereqs(); 712 if (UNLIKELY(!asan_inited)) 713 __asan_init(); 714 } 715 }; 716 717 static AsanInitializer asan_initializer; 718 #endif // ASAN_DYNAMIC 719 720 } // namespace __asan 721 722 // ---------------------- Interface ---------------- {{{1 723 using namespace __asan; // NOLINT 724 725 #if !SANITIZER_SUPPORTS_WEAK_HOOKS 726 extern "C" { 727 SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE 728 const char* __asan_default_options() { return ""; } 729 } // extern "C" 730 #endif 731 732 int NOINLINE __asan_set_error_exit_code(int exit_code) { 733 int old = flags()->exitcode; 734 flags()->exitcode = exit_code; 735 return old; 736 } 737 738 void NOINLINE __asan_handle_no_return() { 739 int local_stack; 740 AsanThread *curr_thread = GetCurrentThread(); 741 CHECK(curr_thread); 742 uptr PageSize = GetPageSizeCached(); 743 uptr top = curr_thread->stack_top(); 744 uptr bottom = ((uptr)&local_stack - PageSize) & ~(PageSize-1); 745 static const uptr kMaxExpectedCleanupSize = 64 << 20; // 64M 746 if (top - bottom > kMaxExpectedCleanupSize) { 747 static bool reported_warning = false; 748 if (reported_warning) 749 return; 750 reported_warning = true; 751 Report("WARNING: ASan is ignoring requested __asan_handle_no_return: " 752 "stack top: %p; bottom %p; size: %p (%zd)\n" 753 "False positive error reports may follow\n" 754 "For details see " 755 "http://code.google.com/p/address-sanitizer/issues/detail?id=189\n", 756 top, bottom, top - bottom, top - bottom); 757 return; 758 } 759 PoisonShadow(bottom, top - bottom, 0); 760 if (curr_thread->has_fake_stack()) 761 curr_thread->fake_stack()->HandleNoReturn(); 762 } 763 764 void NOINLINE __asan_set_death_callback(void (*callback)(void)) { 765 death_callback = callback; 766 } 767 768 // Initialize as requested from instrumented application code. 769 // We use this call as a trigger to wake up ASan from deactivated state. 770 void __asan_init() { 771 AsanCheckIncompatibleRT(); 772 AsanActivate(); 773 AsanInitInternal(); 774 } 775