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