asan_rtl.cc revision 4558168b361d59be9cc5510b72bb0de9ca795c3a
1//===-- asan_rtl.cc ---------------------------------------------*- C++ -*-===// 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_allocator.h" 15#include "asan_interceptors.h" 16#include "asan_interface.h" 17#include "asan_internal.h" 18#include "asan_lock.h" 19#include "asan_mac.h" 20#include "asan_mapping.h" 21#include "asan_stack.h" 22#include "asan_stats.h" 23#include "asan_thread.h" 24#include "asan_thread_registry.h" 25 26#include <new> 27#include <dlfcn.h> 28#include <execinfo.h> 29#include <fcntl.h> 30#include <pthread.h> 31#include <signal.h> 32#include <stdarg.h> 33#include <stdint.h> 34#include <stdio.h> 35#include <stdlib.h> 36#include <string.h> 37#include <sys/stat.h> 38#include <sys/types.h> 39#ifndef ANDROID 40#include <sys/ucontext.h> 41#endif 42#include <sys/time.h> 43#include <sys/resource.h> 44#include <unistd.h> 45// must not include <setjmp.h> on Linux 46 47namespace __asan { 48 49// -------------------------- Flags ------------------------- {{{1 50static const size_t kMallocContextSize = 30; 51static int FLAG_atexit; 52bool FLAG_fast_unwind = true; 53 54size_t FLAG_redzone; // power of two, >= 32 55size_t FLAG_quarantine_size; 56int FLAG_demangle; 57bool FLAG_symbolize; 58int FLAG_v; 59int FLAG_debug; 60bool FLAG_poison_shadow; 61int FLAG_report_globals; 62size_t FLAG_malloc_context_size = kMallocContextSize; 63uintptr_t FLAG_large_malloc; 64bool FLAG_lazy_shadow; 65bool FLAG_handle_segv; 66bool FLAG_handle_sigill; 67bool FLAG_replace_str; 68bool FLAG_replace_intrin; 69bool FLAG_replace_cfallocator; // Used on Mac only. 70size_t FLAG_max_malloc_fill_size = 0; 71bool FLAG_use_fake_stack; 72int FLAG_exitcode = EXIT_FAILURE; 73bool FLAG_allow_user_poisoning; 74 75// -------------------------- Globals --------------------- {{{1 76int asan_inited; 77bool asan_init_is_running; 78 79// -------------------------- Interceptors ---------------- {{{1 80typedef int (*sigaction_f)(int signum, const struct sigaction *act, 81 struct sigaction *oldact); 82typedef sig_t (*signal_f)(int signum, sig_t handler); 83typedef void (*longjmp_f)(void *env, int val); 84typedef longjmp_f _longjmp_f; 85typedef longjmp_f siglongjmp_f; 86typedef void (*__cxa_throw_f)(void *, void *, void *); 87typedef int (*pthread_create_f)(pthread_t *thread, const pthread_attr_t *attr, 88 void *(*start_routine) (void *), void *arg); 89#ifdef __APPLE__ 90dispatch_async_f_f real_dispatch_async_f; 91dispatch_sync_f_f real_dispatch_sync_f; 92dispatch_after_f_f real_dispatch_after_f; 93dispatch_barrier_async_f_f real_dispatch_barrier_async_f; 94dispatch_group_async_f_f real_dispatch_group_async_f; 95pthread_workqueue_additem_np_f real_pthread_workqueue_additem_np; 96#endif 97 98sigaction_f real_sigaction; 99signal_f real_signal; 100longjmp_f real_longjmp; 101_longjmp_f real__longjmp; 102siglongjmp_f real_siglongjmp; 103__cxa_throw_f real___cxa_throw; 104pthread_create_f real_pthread_create; 105 106// -------------------------- Misc ---------------- {{{1 107void ShowStatsAndAbort() { 108 __asan_print_accumulated_stats(); 109 ASAN_DIE; 110} 111 112static void PrintBytes(const char *before, uintptr_t *a) { 113 uint8_t *bytes = (uint8_t*)a; 114 size_t byte_num = (__WORDSIZE) / 8; 115 Printf("%s%p:", before, (uintptr_t)a); 116 for (size_t i = 0; i < byte_num; i++) { 117 Printf(" %lx%lx", bytes[i] >> 4, bytes[i] & 15); 118 } 119 Printf("\n"); 120} 121 122// Opens the file 'file_name" and reads up to 'max_len' bytes. 123// The resulting buffer is mmaped and stored in '*buff'. 124// Returns the number of read bytes or -1 if file can not be opened. 125static ssize_t ReadFileToBuffer(const char *file_name, char **buff, 126 size_t max_len) { 127 const size_t kMinFileLen = kPageSize; 128 ssize_t read_len = -1; 129 *buff = 0; 130 size_t maped_size = 0; 131 // The files we usually open are not seekable, so try different buffer sizes. 132 for (size_t size = kMinFileLen; size <= max_len; size *= 2) { 133 int fd = AsanOpenReadonly(file_name); 134 if (fd < 0) return -1; 135 AsanUnmapOrDie(*buff, maped_size); 136 maped_size = size; 137 *buff = (char*)AsanMmapSomewhereOrDie(size, __FUNCTION__); 138 read_len = AsanRead(fd, *buff, size); 139 AsanClose(fd); 140 if (read_len < size) // We've read the whole file. 141 break; 142 } 143 return read_len; 144} 145 146// Like getenv, but reads env directly from /proc and does not use libc. 147// This function should be called first inside __asan_init. 148static const char* GetEnvFromProcSelfEnviron(const char* name) { 149 static char *environ; 150 static ssize_t len; 151 static bool inited; 152 if (!inited) { 153 inited = true; 154 len = ReadFileToBuffer("/proc/self/environ", &environ, 1 << 20); 155 } 156 if (!environ || len <= 0) return NULL; 157 size_t namelen = internal_strlen(name); 158 const char *p = environ; 159 while (*p != '\0') { // will happen at the \0\0 that terminates the buffer 160 // proc file has the format NAME=value\0NAME=value\0NAME=value\0... 161 const char* endp = 162 (char*)internal_memchr(p, '\0', len - (p - environ)); 163 if (endp == NULL) // this entry isn't NUL terminated 164 return NULL; 165 else if (!internal_memcmp(p, name, namelen) && p[namelen] == '=') // Match. 166 return p + namelen + 1; // point after = 167 p = endp + 1; 168 } 169 return NULL; // Not found. 170} 171 172// ---------------------- Thread ------------------------- {{{1 173static void *asan_thread_start(void *arg) { 174 AsanThread *t= (AsanThread*)arg; 175 asanThreadRegistry().SetCurrent(t); 176 return t->ThreadStart(); 177} 178 179// ---------------------- mmap -------------------- {{{1 180void OutOfMemoryMessageAndDie(const char *mem_type, size_t size) { 181 Report("ERROR: AddressSanitizer failed to allocate " 182 "0x%lx (%ld) bytes of %s\n", 183 size, size, mem_type); 184 PRINT_CURRENT_STACK(); 185 ShowStatsAndAbort(); 186} 187 188// Reserve memory range [beg, end]. 189static void ReserveShadowMemoryRange(uintptr_t beg, uintptr_t end) { 190 CHECK((beg % kPageSize) == 0); 191 CHECK(((end + 1) % kPageSize) == 0); 192 size_t size = end - beg + 1; 193 void *res = AsanMmapFixedNoReserve(beg, size); 194 CHECK(res == (void*)beg && "ReserveShadowMemoryRange failed"); 195} 196 197// ---------------------- LowLevelAllocator ------------- {{{1 198void *LowLevelAllocator::Allocate(size_t size) { 199 CHECK((size & (size - 1)) == 0 && "size must be a power of two"); 200 if (allocated_end_ - allocated_current_ < size) { 201 size_t size_to_allocate = Max(size, kPageSize); 202 allocated_current_ = 203 (char*)AsanMmapSomewhereOrDie(size_to_allocate, __FUNCTION__); 204 allocated_end_ = allocated_current_ + size_to_allocate; 205 PoisonShadow((uintptr_t)allocated_current_, size_to_allocate, 206 kAsanInternalHeapMagic); 207 } 208 CHECK(allocated_end_ - allocated_current_ >= size); 209 void *res = allocated_current_; 210 allocated_current_ += size; 211 return res; 212} 213 214// ---------------------- DescribeAddress -------------------- {{{1 215static bool DescribeStackAddress(uintptr_t addr, uintptr_t access_size) { 216 AsanThread *t = asanThreadRegistry().FindThreadByStackAddress(addr); 217 if (!t) return false; 218 const intptr_t kBufSize = 4095; 219 char buf[kBufSize]; 220 uintptr_t offset = 0; 221 const char *frame_descr = t->GetFrameNameByAddr(addr, &offset); 222 // This string is created by the compiler and has the following form: 223 // "FunctioName n alloc_1 alloc_2 ... alloc_n" 224 // where alloc_i looks like "offset size len ObjectName ". 225 CHECK(frame_descr); 226 // Report the function name and the offset. 227 const char *name_end = real_strchr(frame_descr, ' '); 228 CHECK(name_end); 229 buf[0] = 0; 230 strncat(buf, frame_descr, 231 Min(kBufSize, static_cast<intptr_t>(name_end - frame_descr))); 232 Printf("Address %p is located at offset %ld " 233 "in frame <%s> of T%d's stack:\n", 234 addr, offset, buf, t->tid()); 235 // Report the number of stack objects. 236 char *p; 237 size_t n_objects = strtol(name_end, &p, 10); 238 CHECK(n_objects > 0); 239 Printf(" This frame has %ld object(s):\n", n_objects); 240 // Report all objects in this frame. 241 for (size_t i = 0; i < n_objects; i++) { 242 size_t beg, size; 243 intptr_t len; 244 beg = strtol(p, &p, 10); 245 size = strtol(p, &p, 10); 246 len = strtol(p, &p, 10); 247 if (beg <= 0 || size <= 0 || len < 0 || *p != ' ') { 248 Printf("AddressSanitizer can't parse the stack frame descriptor: |%s|\n", 249 frame_descr); 250 break; 251 } 252 p++; 253 buf[0] = 0; 254 strncat(buf, p, Min(kBufSize, len)); 255 p += len; 256 Printf(" [%ld, %ld) '%s'\n", beg, beg + size, buf); 257 } 258 Printf("HINT: this may be a false positive if your program uses " 259 "some custom stack unwind mechanism\n" 260 " (longjmp and C++ exceptions *are* supported)\n"); 261 t->summary()->Announce(); 262 return true; 263} 264 265__attribute__((noinline)) 266static void DescribeAddress(uintptr_t addr, uintptr_t access_size) { 267 // Check if this is a global. 268 if (DescribeAddrIfGlobal(addr)) 269 return; 270 271 if (DescribeStackAddress(addr, access_size)) 272 return; 273 274 // finally, check if this is a heap. 275 DescribeHeapAddress(addr, access_size); 276} 277 278// -------------------------- Run-time entry ------------------- {{{1 279void GetPcSpBpAx(void *context, 280 uintptr_t *pc, uintptr_t *sp, uintptr_t *bp, uintptr_t *ax) { 281#ifndef ANDROID 282 ucontext_t *ucontext = (ucontext_t*)context; 283#endif 284#ifdef __APPLE__ 285# if __WORDSIZE == 64 286 *pc = ucontext->uc_mcontext->__ss.__rip; 287 *bp = ucontext->uc_mcontext->__ss.__rbp; 288 *sp = ucontext->uc_mcontext->__ss.__rsp; 289 *ax = ucontext->uc_mcontext->__ss.__rax; 290# else 291 *pc = ucontext->uc_mcontext->__ss.__eip; 292 *bp = ucontext->uc_mcontext->__ss.__ebp; 293 *sp = ucontext->uc_mcontext->__ss.__esp; 294 *ax = ucontext->uc_mcontext->__ss.__eax; 295# endif // __WORDSIZE 296#else // assume linux 297# if defined (ANDROID) 298 *pc = *sp = *bp = *ax = 0; 299# elif defined(__arm__) 300 *pc = ucontext->uc_mcontext.arm_pc; 301 *bp = ucontext->uc_mcontext.arm_fp; 302 *sp = ucontext->uc_mcontext.arm_sp; 303 *ax = ucontext->uc_mcontext.arm_r0; 304# elif __WORDSIZE == 64 305 *pc = ucontext->uc_mcontext.gregs[REG_RIP]; 306 *bp = ucontext->uc_mcontext.gregs[REG_RBP]; 307 *sp = ucontext->uc_mcontext.gregs[REG_RSP]; 308 *ax = ucontext->uc_mcontext.gregs[REG_RAX]; 309# else 310 *pc = ucontext->uc_mcontext.gregs[REG_EIP]; 311 *bp = ucontext->uc_mcontext.gregs[REG_EBP]; 312 *sp = ucontext->uc_mcontext.gregs[REG_ESP]; 313 *ax = ucontext->uc_mcontext.gregs[REG_EAX]; 314# endif // __WORDSIZE 315#endif 316} 317 318static void ASAN_OnSIGSEGV(int, siginfo_t *siginfo, void *context) { 319 uintptr_t addr = (uintptr_t)siginfo->si_addr; 320 if (AddrIsInShadow(addr) && FLAG_lazy_shadow) { 321 // We traped on access to a shadow address. Just map a large chunk around 322 // this address. 323 const uintptr_t chunk_size = kPageSize << 10; // 4M 324 uintptr_t chunk = addr & ~(chunk_size - 1); 325 AsanMmapFixedReserve(chunk, chunk_size); 326 return; 327 } 328 // Write the first message using the bullet-proof write. 329 if (13 != AsanWrite(2, "ASAN:SIGSEGV\n", 13)) ASAN_DIE; 330 uintptr_t pc, sp, bp, ax; 331 GetPcSpBpAx(context, &pc, &sp, &bp, &ax); 332 Report("ERROR: AddressSanitizer crashed on unknown address %p" 333 " (pc %p sp %p bp %p ax %p T%d)\n", 334 addr, pc, sp, bp, ax, 335 asanThreadRegistry().GetCurrentTidOrMinusOne()); 336 Printf("AddressSanitizer can not provide additional info. ABORTING\n"); 337 GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, false, pc, bp); 338 stack.PrintStack(); 339 ShowStatsAndAbort(); 340} 341 342static void ASAN_OnSIGILL(int, siginfo_t *siginfo, void *context) { 343 // Write the first message using the bullet-proof write. 344 if (12 != AsanWrite(2, "ASAN:SIGILL\n", 12)) ASAN_DIE; 345 uintptr_t pc, sp, bp, ax; 346 GetPcSpBpAx(context, &pc, &sp, &bp, &ax); 347 348 uintptr_t addr = ax; 349 350 uint8_t *insn = (uint8_t*)pc; 351 CHECK(insn[0] == 0x0f && insn[1] == 0x0b); // ud2 352 unsigned access_size_and_type = insn[2] - 0x50; 353 CHECK(access_size_and_type < 16); 354 bool is_write = access_size_and_type & 8; 355 int access_size = 1 << (access_size_and_type & 7); 356 __asan_report_error(pc, bp, sp, addr, is_write, access_size); 357} 358 359// exported functions 360#define ASAN_REPORT_ERROR(type, is_write, size) \ 361extern "C" void __asan_report_ ## type ## size(uintptr_t addr) \ 362 __attribute__((visibility("default"))) __attribute__((noinline)); \ 363extern "C" void __asan_report_ ## type ## size(uintptr_t addr) { \ 364 GET_BP_PC_SP; \ 365 __asan_report_error(pc, bp, sp, addr, is_write, size); \ 366} 367 368ASAN_REPORT_ERROR(load, false, 1) 369ASAN_REPORT_ERROR(load, false, 2) 370ASAN_REPORT_ERROR(load, false, 4) 371ASAN_REPORT_ERROR(load, false, 8) 372ASAN_REPORT_ERROR(load, false, 16) 373ASAN_REPORT_ERROR(store, true, 1) 374ASAN_REPORT_ERROR(store, true, 2) 375ASAN_REPORT_ERROR(store, true, 4) 376ASAN_REPORT_ERROR(store, true, 8) 377ASAN_REPORT_ERROR(store, true, 16) 378 379// Force the linker to keep the symbols for various ASan interface functions. 380// We want to keep those in the executable in order to let the instrumented 381// dynamic libraries access the symbol even if it is not used by the executable 382// itself. This should help if the build system is removing dead code at link 383// time. 384static void force_interface_symbols() { 385 volatile int fake_condition = 0; // prevent dead condition elimination. 386 if (fake_condition) { 387 __asan_report_load1(NULL); 388 __asan_report_load2(NULL); 389 __asan_report_load4(NULL); 390 __asan_report_load8(NULL); 391 __asan_report_load16(NULL); 392 __asan_report_store1(NULL); 393 __asan_report_store2(NULL); 394 __asan_report_store4(NULL); 395 __asan_report_store8(NULL); 396 __asan_report_store16(NULL); 397 __asan_register_global(0, 0, NULL); 398 __asan_register_globals(NULL, 0); 399 __asan_unregister_globals(NULL, 0); 400 } 401} 402 403// -------------------------- Init ------------------- {{{1 404static int64_t IntFlagValue(const char *flags, const char *flag, 405 int64_t default_val) { 406 if (!flags) return default_val; 407 const char *str = strstr(flags, flag); 408 if (!str) return default_val; 409 return atoll(str + internal_strlen(flag)); 410} 411 412static void asan_atexit() { 413 Printf("AddressSanitizer exit stats:\n"); 414 __asan_print_accumulated_stats(); 415} 416 417void CheckFailed(const char *cond, const char *file, int line) { 418 Report("CHECK failed: %s at %s:%d, pthread_self=%p\n", 419 cond, file, line, pthread_self()); 420 PRINT_CURRENT_STACK(); 421 ShowStatsAndAbort(); 422} 423 424} // namespace __asan 425 426// -------------------------- Interceptors ------------------- {{{1 427using namespace __asan; // NOLINT 428 429#define OPERATOR_NEW_BODY \ 430 GET_STACK_TRACE_HERE_FOR_MALLOC;\ 431 return asan_memalign(0, size, &stack); 432 433#ifdef ANDROID 434void *operator new(size_t size) { OPERATOR_NEW_BODY; } 435void *operator new[](size_t size) { OPERATOR_NEW_BODY; } 436#else 437void *operator new(size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; } 438void *operator new[](size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; } 439void *operator new(size_t size, std::nothrow_t const&) throw() 440{ OPERATOR_NEW_BODY; } 441void *operator new[](size_t size, std::nothrow_t const&) throw() 442{ OPERATOR_NEW_BODY; } 443#endif 444 445#define OPERATOR_DELETE_BODY \ 446 GET_STACK_TRACE_HERE_FOR_FREE(ptr);\ 447 asan_free(ptr, &stack); 448 449void operator delete(void *ptr) throw() { OPERATOR_DELETE_BODY; } 450void operator delete[](void *ptr) throw() { OPERATOR_DELETE_BODY; } 451void operator delete(void *ptr, std::nothrow_t const&) throw() 452{ OPERATOR_DELETE_BODY; } 453void operator delete[](void *ptr, std::nothrow_t const&) throw() 454{ OPERATOR_DELETE_BODY;} 455 456extern "C" 457#ifndef __APPLE__ 458__attribute__((visibility("default"))) 459#endif 460int WRAP(pthread_create)(pthread_t *thread, const pthread_attr_t *attr, 461 void *(*start_routine) (void *), void *arg) { 462 GET_STACK_TRACE_HERE(kStackTraceMax, /*fast_unwind*/false); 463 AsanThread *t = (AsanThread*)asan_malloc(sizeof(AsanThread), &stack); 464 AsanThread *curr_thread = asanThreadRegistry().GetCurrent(); 465 CHECK(curr_thread || asanThreadRegistry().IsCurrentThreadDying()); 466 new(t) AsanThread(asanThreadRegistry().GetCurrentTidOrMinusOne(), 467 start_routine, arg, &stack); 468 return real_pthread_create(thread, attr, asan_thread_start, t); 469} 470 471static bool MySignal(int signum) { 472 if (FLAG_handle_sigill && signum == SIGILL) return true; 473 if (FLAG_handle_segv && signum == SIGSEGV) return true; 474#ifdef __APPLE__ 475 if (FLAG_handle_segv && signum == SIGBUS) return true; 476#endif 477 return false; 478} 479 480static void MaybeInstallSigaction(int signum, 481 void (*handler)(int, siginfo_t *, void *)) { 482 if (!MySignal(signum)) 483 return; 484 struct sigaction sigact; 485 real_memset(&sigact, 0, sizeof(sigact)); 486 sigact.sa_sigaction = handler; 487 sigact.sa_flags = SA_SIGINFO; 488 CHECK(0 == real_sigaction(signum, &sigact, 0)); 489} 490 491extern "C" 492sig_t WRAP(signal)(int signum, sig_t handler) { 493 if (!MySignal(signum)) { 494 return real_signal(signum, handler); 495 } 496 return NULL; 497} 498 499extern "C" 500int WRAP(sigaction)(int signum, const struct sigaction *act, 501 struct sigaction *oldact) { 502 if (!MySignal(signum)) { 503 return real_sigaction(signum, act, oldact); 504 } 505 return 0; 506} 507 508 509static void UnpoisonStackFromHereToTop() { 510 int local_stack; 511 AsanThread *curr_thread = asanThreadRegistry().GetCurrent(); 512 CHECK(curr_thread); 513 uintptr_t top = curr_thread->stack_top(); 514 uintptr_t bottom = ((uintptr_t)&local_stack - kPageSize) & ~(kPageSize-1); 515 PoisonShadow(bottom, top - bottom, 0); 516} 517 518extern "C" void WRAP(longjmp)(void *env, int val) { 519 UnpoisonStackFromHereToTop(); 520 real_longjmp(env, val); 521} 522 523extern "C" void WRAP(_longjmp)(void *env, int val) { 524 UnpoisonStackFromHereToTop(); 525 real__longjmp(env, val); 526} 527 528extern "C" void WRAP(siglongjmp)(void *env, int val) { 529 UnpoisonStackFromHereToTop(); 530 real_siglongjmp(env, val); 531} 532 533extern "C" void __cxa_throw(void *a, void *b, void *c); 534 535#if ASAN_HAS_EXCEPTIONS == 1 536extern "C" void WRAP(__cxa_throw)(void *a, void *b, void *c) { 537 CHECK(&real___cxa_throw); 538 UnpoisonStackFromHereToTop(); 539 real___cxa_throw(a, b, c); 540} 541#endif 542 543extern "C" { 544// intercept mlock and friends. 545// Since asan maps 16T of RAM, mlock is completely unfriendly to asan. 546// All functions return 0 (success). 547static void MlockIsUnsupported() { 548 static bool printed = 0; 549 if (printed) return; 550 printed = true; 551 Printf("INFO: AddressSanitizer ignores mlock/mlockall/munlock/munlockall\n"); 552} 553int mlock(const void *addr, size_t len) { 554 MlockIsUnsupported(); 555 return 0; 556} 557int munlock(const void *addr, size_t len) { 558 MlockIsUnsupported(); 559 return 0; 560} 561int mlockall(int flags) { 562 MlockIsUnsupported(); 563 return 0; 564} 565int munlockall(void) { 566 MlockIsUnsupported(); 567 return 0; 568} 569} // extern "C" 570 571// ---------------------- Interface ---------------- {{{1 572int __asan_set_error_exit_code(int exit_code) { 573 int old = FLAG_exitcode; 574 FLAG_exitcode = exit_code; 575 return old; 576} 577 578void __asan_report_error(uintptr_t pc, uintptr_t bp, uintptr_t sp, 579 uintptr_t addr, bool is_write, size_t access_size) { 580 // Do not print more than one report, otherwise they will mix up. 581 static int num_calls = 0; 582 if (AtomicInc(&num_calls) > 1) return; 583 584 Printf("=================================================================\n"); 585 const char *bug_descr = "unknown-crash"; 586 if (AddrIsInMem(addr)) { 587 uint8_t *shadow_addr = (uint8_t*)MemToShadow(addr); 588 // If we are accessing 16 bytes, look at the second shadow byte. 589 if (*shadow_addr == 0 && access_size > SHADOW_GRANULARITY) 590 shadow_addr++; 591 // If we are in the partial right redzone, look at the next shadow byte. 592 if (*shadow_addr > 0 && *shadow_addr < 128) 593 shadow_addr++; 594 switch (*shadow_addr) { 595 case kAsanHeapLeftRedzoneMagic: 596 case kAsanHeapRightRedzoneMagic: 597 bug_descr = "heap-buffer-overflow"; 598 break; 599 case kAsanHeapFreeMagic: 600 bug_descr = "heap-use-after-free"; 601 break; 602 case kAsanStackLeftRedzoneMagic: 603 bug_descr = "stack-buffer-underflow"; 604 break; 605 case kAsanStackMidRedzoneMagic: 606 case kAsanStackRightRedzoneMagic: 607 case kAsanStackPartialRedzoneMagic: 608 bug_descr = "stack-buffer-overflow"; 609 break; 610 case kAsanStackAfterReturnMagic: 611 bug_descr = "stack-use-after-return"; 612 break; 613 case kAsanUserPoisonedMemoryMagic: 614 bug_descr = "use-after-poison"; 615 break; 616 case kAsanGlobalRedzoneMagic: 617 bug_descr = "global-buffer-overflow"; 618 break; 619 } 620 } 621 622 AsanThread *curr_thread = asanThreadRegistry().GetCurrent(); 623 int curr_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); 624 625 if (curr_thread) { 626 // We started reporting an error message. Stop using the fake stack 627 // in case we will call an instrumented function from a symbolizer. 628 curr_thread->fake_stack().StopUsingFakeStack(); 629 } 630 631 Report("ERROR: AddressSanitizer %s on address " 632 "%p at pc 0x%lx bp 0x%lx sp 0x%lx\n", 633 bug_descr, addr, pc, bp, sp); 634 635 Printf("%s of size %d at %p thread T%d\n", 636 access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", 637 access_size, addr, curr_tid); 638 639 if (FLAG_debug) { 640 PrintBytes("PC: ", (uintptr_t*)pc); 641 } 642 643 GET_STACK_TRACE_WITH_PC_AND_BP(kStackTraceMax, 644 false, // FLAG_fast_unwind, 645 pc, bp); 646 stack.PrintStack(); 647 648 CHECK(AddrIsInMem(addr)); 649 650 DescribeAddress(addr, access_size); 651 652 uintptr_t shadow_addr = MemToShadow(addr); 653 Report("ABORTING\n"); 654 __asan_print_accumulated_stats(); 655 Printf("Shadow byte and word:\n"); 656 Printf(" %p: %x\n", shadow_addr, *(unsigned char*)shadow_addr); 657 uintptr_t aligned_shadow = shadow_addr & ~(kWordSize - 1); 658 PrintBytes(" ", (uintptr_t*)(aligned_shadow)); 659 Printf("More shadow bytes:\n"); 660 PrintBytes(" ", (uintptr_t*)(aligned_shadow-4*kWordSize)); 661 PrintBytes(" ", (uintptr_t*)(aligned_shadow-3*kWordSize)); 662 PrintBytes(" ", (uintptr_t*)(aligned_shadow-2*kWordSize)); 663 PrintBytes(" ", (uintptr_t*)(aligned_shadow-1*kWordSize)); 664 PrintBytes("=>", (uintptr_t*)(aligned_shadow+0*kWordSize)); 665 PrintBytes(" ", (uintptr_t*)(aligned_shadow+1*kWordSize)); 666 PrintBytes(" ", (uintptr_t*)(aligned_shadow+2*kWordSize)); 667 PrintBytes(" ", (uintptr_t*)(aligned_shadow+3*kWordSize)); 668 PrintBytes(" ", (uintptr_t*)(aligned_shadow+4*kWordSize)); 669 ASAN_DIE; 670} 671 672void __asan_init() { 673 if (asan_inited) return; 674 asan_init_is_running = true; 675 676 // Make sure we are not statically linked. 677 AsanDoesNotSupportStaticLinkage(); 678 679 // flags 680 const char *options = GetEnvFromProcSelfEnviron("ASAN_OPTIONS"); 681 FLAG_malloc_context_size = 682 IntFlagValue(options, "malloc_context_size=", kMallocContextSize); 683 CHECK(FLAG_malloc_context_size <= kMallocContextSize); 684 685 FLAG_max_malloc_fill_size = 686 IntFlagValue(options, "max_malloc_fill_size=", 0); 687 688 FLAG_v = IntFlagValue(options, "verbosity=", 0); 689 690 FLAG_redzone = IntFlagValue(options, "redzone=", 128); 691 CHECK(FLAG_redzone >= 32); 692 CHECK((FLAG_redzone & (FLAG_redzone - 1)) == 0); 693 694 FLAG_atexit = IntFlagValue(options, "atexit=", 0); 695 FLAG_poison_shadow = IntFlagValue(options, "poison_shadow=", 1); 696 FLAG_report_globals = IntFlagValue(options, "report_globals=", 1); 697 FLAG_lazy_shadow = IntFlagValue(options, "lazy_shadow=", 0); 698 FLAG_handle_segv = IntFlagValue(options, "handle_segv=", ASAN_NEEDS_SEGV); 699 FLAG_handle_sigill = IntFlagValue(options, "handle_sigill=", 0); 700 FLAG_symbolize = IntFlagValue(options, "symbolize=", 1); 701 FLAG_demangle = IntFlagValue(options, "demangle=", 1); 702 FLAG_debug = IntFlagValue(options, "debug=", 0); 703 FLAG_replace_cfallocator = IntFlagValue(options, "replace_cfallocator=", 1); 704 FLAG_fast_unwind = IntFlagValue(options, "fast_unwind=", 1); 705 FLAG_replace_str = IntFlagValue(options, "replace_str=", 1); 706 FLAG_replace_intrin = IntFlagValue(options, "replace_intrin=", 1); 707 FLAG_use_fake_stack = IntFlagValue(options, "use_fake_stack=", 1); 708 FLAG_exitcode = IntFlagValue(options, "exitcode=", EXIT_FAILURE); 709 FLAG_allow_user_poisoning = IntFlagValue(options, 710 "allow_user_poisoning=", 1); 711 712 if (FLAG_atexit) { 713 atexit(asan_atexit); 714 } 715 716 FLAG_quarantine_size = 717 IntFlagValue(options, "quarantine_size=", 1UL << 28); 718 719 // interceptors 720 InitializeAsanInterceptors(); 721 722 ReplaceSystemMalloc(); 723 724 INTERCEPT_FUNCTION(sigaction); 725 INTERCEPT_FUNCTION(signal); 726 INTERCEPT_FUNCTION(longjmp); 727 INTERCEPT_FUNCTION(_longjmp); 728 INTERCEPT_FUNCTION_IF_EXISTS(__cxa_throw); 729 INTERCEPT_FUNCTION(pthread_create); 730#ifdef __APPLE__ 731 INTERCEPT_FUNCTION(dispatch_async_f); 732 INTERCEPT_FUNCTION(dispatch_sync_f); 733 INTERCEPT_FUNCTION(dispatch_after_f); 734 INTERCEPT_FUNCTION(dispatch_barrier_async_f); 735 INTERCEPT_FUNCTION(dispatch_group_async_f); 736 // We don't need to intercept pthread_workqueue_additem_np() to support the 737 // libdispatch API, but it helps us to debug the unsupported functions. Let's 738 // intercept it only during verbose runs. 739 if (FLAG_v >= 2) { 740 INTERCEPT_FUNCTION(pthread_workqueue_additem_np); 741 } 742#else 743 // On Darwin siglongjmp tailcalls longjmp, so we don't want to intercept it 744 // there. 745 INTERCEPT_FUNCTION(siglongjmp); 746#endif 747 748 MaybeInstallSigaction(SIGSEGV, ASAN_OnSIGSEGV); 749 MaybeInstallSigaction(SIGBUS, ASAN_OnSIGSEGV); 750 MaybeInstallSigaction(SIGILL, ASAN_OnSIGILL); 751 752 if (FLAG_v) { 753 Printf("|| `[%p, %p]` || HighMem ||\n", kHighMemBeg, kHighMemEnd); 754 Printf("|| `[%p, %p]` || HighShadow ||\n", 755 kHighShadowBeg, kHighShadowEnd); 756 Printf("|| `[%p, %p]` || ShadowGap ||\n", 757 kShadowGapBeg, kShadowGapEnd); 758 Printf("|| `[%p, %p]` || LowShadow ||\n", 759 kLowShadowBeg, kLowShadowEnd); 760 Printf("|| `[%p, %p]` || LowMem ||\n", kLowMemBeg, kLowMemEnd); 761 Printf("MemToShadow(shadow): %p %p %p %p\n", 762 MEM_TO_SHADOW(kLowShadowBeg), 763 MEM_TO_SHADOW(kLowShadowEnd), 764 MEM_TO_SHADOW(kHighShadowBeg), 765 MEM_TO_SHADOW(kHighShadowEnd)); 766 Printf("red_zone=%ld\n", FLAG_redzone); 767 Printf("malloc_context_size=%ld\n", (int)FLAG_malloc_context_size); 768 Printf("fast_unwind=%d\n", (int)FLAG_fast_unwind); 769 770 Printf("SHADOW_SCALE: %lx\n", SHADOW_SCALE); 771 Printf("SHADOW_GRANULARITY: %lx\n", SHADOW_GRANULARITY); 772 Printf("SHADOW_OFFSET: %lx\n", SHADOW_OFFSET); 773 CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7); 774 } 775 776 if (__WORDSIZE == 64) { 777 // Disable core dumper -- it makes little sense to dump 16T+ core. 778 struct rlimit nocore; 779 nocore.rlim_cur = 0; 780 nocore.rlim_max = 0; 781 setrlimit(RLIMIT_CORE, &nocore); 782 } 783 784 { 785 if (!FLAG_lazy_shadow) { 786 if (kLowShadowBeg != kLowShadowEnd) { 787 // mmap the low shadow plus one page. 788 ReserveShadowMemoryRange(kLowShadowBeg - kPageSize, kLowShadowEnd); 789 } 790 // mmap the high shadow. 791 ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd); 792 } 793 // protect the gap 794 void *prot = AsanMprotect(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); 795 CHECK(prot == (void*)kShadowGapBeg); 796 } 797 798 // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited 799 // should be set to 1 prior to initializing the threads. 800 asan_inited = 1; 801 asan_init_is_running = false; 802 803 asanThreadRegistry().Init(); 804 asanThreadRegistry().GetMain()->ThreadStart(); 805 force_interface_symbols(); // no-op. 806 807 if (FLAG_v) { 808 Report("AddressSanitizer Init done\n"); 809 } 810} 811