Home | History | Annotate | Download | only in asan
      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_allocator.h"
     15 #include "asan_interceptors.h"
     16 #include "asan_internal.h"
     17 #include "asan_lock.h"
     18 #include "asan_mapping.h"
     19 #include "asan_report.h"
     20 #include "asan_stack.h"
     21 #include "asan_stats.h"
     22 #include "asan_thread.h"
     23 #include "asan_thread_registry.h"
     24 #include "sanitizer/asan_interface.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 
     30 namespace __sanitizer {
     31 using namespace __asan;
     32 
     33 void Die() {
     34   static atomic_uint32_t num_calls;
     35   if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
     36     // Don't die twice - run a busy loop.
     37     while (1) { }
     38   }
     39   if (flags()->sleep_before_dying) {
     40     Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying);
     41     SleepForSeconds(flags()->sleep_before_dying);
     42   }
     43   if (flags()->unmap_shadow_on_exit)
     44     UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
     45   if (death_callback)
     46     death_callback();
     47   if (flags()->abort_on_error)
     48     Abort();
     49   Exit(flags()->exitcode);
     50 }
     51 
     52 SANITIZER_INTERFACE_ATTRIBUTE
     53 void CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2) {
     54   Report("AddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n",
     55              file, line, cond, (uptr)v1, (uptr)v2);
     56   // FIXME: check for infinite recursion without a thread-local counter here.
     57   PRINT_CURRENT_STACK();
     58   ShowStatsAndAbort();
     59 }
     60 
     61 }  // namespace __sanitizer
     62 
     63 namespace __asan {
     64 
     65 // -------------------------- Flags ------------------------- {{{1
     66 static const int kDeafultMallocContextSize = 30;
     67 
     68 static Flags asan_flags;
     69 
     70 Flags *flags() {
     71   return &asan_flags;
     72 }
     73 
     74 static void ParseFlagsFromString(Flags *f, const char *str) {
     75   ParseFlag(str, &f->quarantine_size, "quarantine_size");
     76   ParseFlag(str, &f->symbolize, "symbolize");
     77   ParseFlag(str, &f->verbosity, "verbosity");
     78   ParseFlag(str, &f->redzone, "redzone");
     79   CHECK(f->redzone >= 16);
     80   CHECK(IsPowerOfTwo(f->redzone));
     81 
     82   ParseFlag(str, &f->debug, "debug");
     83   ParseFlag(str, &f->report_globals, "report_globals");
     84   ParseFlag(str, &f->check_initialization_order, "initialization_order");
     85   ParseFlag(str, &f->malloc_context_size, "malloc_context_size");
     86   CHECK((uptr)f->malloc_context_size <= kStackTraceMax);
     87 
     88   ParseFlag(str, &f->replace_str, "replace_str");
     89   ParseFlag(str, &f->replace_intrin, "replace_intrin");
     90   ParseFlag(str, &f->replace_cfallocator, "replace_cfallocator");
     91   ParseFlag(str, &f->mac_ignore_invalid_free, "mac_ignore_invalid_free");
     92   ParseFlag(str, &f->use_fake_stack, "use_fake_stack");
     93   ParseFlag(str, &f->max_malloc_fill_size, "max_malloc_fill_size");
     94   ParseFlag(str, &f->exitcode, "exitcode");
     95   ParseFlag(str, &f->allow_user_poisoning, "allow_user_poisoning");
     96   ParseFlag(str, &f->sleep_before_dying, "sleep_before_dying");
     97   ParseFlag(str, &f->handle_segv, "handle_segv");
     98   ParseFlag(str, &f->use_sigaltstack, "use_sigaltstack");
     99   ParseFlag(str, &f->check_malloc_usable_size, "check_malloc_usable_size");
    100   ParseFlag(str, &f->unmap_shadow_on_exit, "unmap_shadow_on_exit");
    101   ParseFlag(str, &f->abort_on_error, "abort_on_error");
    102   ParseFlag(str, &f->atexit, "atexit");
    103   ParseFlag(str, &f->disable_core, "disable_core");
    104   ParseFlag(str, &f->strip_path_prefix, "strip_path_prefix");
    105   ParseFlag(str, &f->allow_reexec, "allow_reexec");
    106   ParseFlag(str, &f->print_full_thread_history, "print_full_thread_history");
    107 }
    108 
    109 extern "C" {
    110 SANITIZER_WEAK_ATTRIBUTE
    111 SANITIZER_INTERFACE_ATTRIBUTE
    112 const char* __asan_default_options() { return ""; }
    113 }  // extern "C"
    114 
    115 void InitializeFlags(Flags *f, const char *env) {
    116   internal_memset(f, 0, sizeof(*f));
    117 
    118   f->quarantine_size = (ASAN_LOW_MEMORY) ? 1UL << 26 : 1UL << 28;
    119   f->symbolize = false;
    120   f->verbosity = 0;
    121   f->redzone = (ASAN_LOW_MEMORY) ? 64 : 128;
    122   f->debug = false;
    123   f->report_globals = 1;
    124   f->check_initialization_order = true;
    125   f->malloc_context_size = kDeafultMallocContextSize;
    126   f->replace_str = true;
    127   f->replace_intrin = true;
    128   f->replace_cfallocator = true;
    129   f->mac_ignore_invalid_free = false;
    130   f->use_fake_stack = true;
    131   f->max_malloc_fill_size = 0;
    132   f->exitcode = ASAN_DEFAULT_FAILURE_EXITCODE;
    133   f->allow_user_poisoning = true;
    134   f->sleep_before_dying = 0;
    135   f->handle_segv = ASAN_NEEDS_SEGV;
    136   f->use_sigaltstack = false;
    137   f->check_malloc_usable_size = true;
    138   f->unmap_shadow_on_exit = false;
    139   f->abort_on_error = false;
    140   f->atexit = false;
    141   f->disable_core = (__WORDSIZE == 64);
    142   f->strip_path_prefix = "";
    143   f->allow_reexec = true;
    144   f->print_full_thread_history = true;
    145 
    146   // Override from user-specified string.
    147   ParseFlagsFromString(f, __asan_default_options());
    148   if (flags()->verbosity) {
    149     Report("Using the defaults from __asan_default_options: %s\n",
    150            __asan_default_options());
    151   }
    152 
    153   // Override from command line.
    154   ParseFlagsFromString(f, env);
    155 }
    156 
    157 // -------------------------- Globals --------------------- {{{1
    158 int asan_inited;
    159 bool asan_init_is_running;
    160 void (*death_callback)(void);
    161 
    162 // -------------------------- Misc ---------------- {{{1
    163 void ShowStatsAndAbort() {
    164   __asan_print_accumulated_stats();
    165   Die();
    166 }
    167 
    168 // ---------------------- mmap -------------------- {{{1
    169 // Reserve memory range [beg, end].
    170 static void ReserveShadowMemoryRange(uptr beg, uptr end) {
    171   CHECK((beg % kPageSize) == 0);
    172   CHECK(((end + 1) % kPageSize) == 0);
    173   uptr size = end - beg + 1;
    174   void *res = MmapFixedNoReserve(beg, size);
    175   if (res != (void*)beg) {
    176     Report("ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. "
    177            "Perhaps you're using ulimit -v\n", size);
    178     Abort();
    179   }
    180 }
    181 
    182 // --------------- LowLevelAllocateCallbac ---------- {{{1
    183 static void OnLowLevelAllocate(uptr ptr, uptr size) {
    184   PoisonShadow(ptr, size, kAsanInternalHeapMagic);
    185 }
    186 
    187 // -------------------------- Run-time entry ------------------- {{{1
    188 // exported functions
    189 #define ASAN_REPORT_ERROR(type, is_write, size)                     \
    190 extern "C" NOINLINE INTERFACE_ATTRIBUTE                        \
    191 void __asan_report_ ## type ## size(uptr addr);                \
    192 void __asan_report_ ## type ## size(uptr addr) {               \
    193   GET_CALLER_PC_BP_SP;                                              \
    194   __asan_report_error(pc, bp, sp, addr, is_write, size);            \
    195 }
    196 
    197 ASAN_REPORT_ERROR(load, false, 1)
    198 ASAN_REPORT_ERROR(load, false, 2)
    199 ASAN_REPORT_ERROR(load, false, 4)
    200 ASAN_REPORT_ERROR(load, false, 8)
    201 ASAN_REPORT_ERROR(load, false, 16)
    202 ASAN_REPORT_ERROR(store, true, 1)
    203 ASAN_REPORT_ERROR(store, true, 2)
    204 ASAN_REPORT_ERROR(store, true, 4)
    205 ASAN_REPORT_ERROR(store, true, 8)
    206 ASAN_REPORT_ERROR(store, true, 16)
    207 
    208 // Force the linker to keep the symbols for various ASan interface functions.
    209 // We want to keep those in the executable in order to let the instrumented
    210 // dynamic libraries access the symbol even if it is not used by the executable
    211 // itself. This should help if the build system is removing dead code at link
    212 // time.
    213 static NOINLINE void force_interface_symbols() {
    214   volatile int fake_condition = 0;  // prevent dead condition elimination.
    215   // __asan_report_* functions are noreturn, so we need a switch to prevent
    216   // the compiler from removing any of them.
    217   switch (fake_condition) {
    218     case 1: __asan_report_load1(0); break;
    219     case 2: __asan_report_load2(0); break;
    220     case 3: __asan_report_load4(0); break;
    221     case 4: __asan_report_load8(0); break;
    222     case 5: __asan_report_load16(0); break;
    223     case 6: __asan_report_store1(0); break;
    224     case 7: __asan_report_store2(0); break;
    225     case 8: __asan_report_store4(0); break;
    226     case 9: __asan_report_store8(0); break;
    227     case 10: __asan_report_store16(0); break;
    228     case 11: __asan_register_global(0, 0, 0); break;
    229     case 12: __asan_register_globals(0, 0); break;
    230     case 13: __asan_unregister_globals(0, 0); break;
    231     case 14: __asan_set_death_callback(0); break;
    232     case 15: __asan_set_error_report_callback(0); break;
    233     case 16: __asan_handle_no_return(); break;
    234     case 17: __asan_address_is_poisoned(0); break;
    235     case 18: __asan_get_allocated_size(0); break;
    236     case 19: __asan_get_current_allocated_bytes(); break;
    237     case 20: __asan_get_estimated_allocated_size(0); break;
    238     case 21: __asan_get_free_bytes(); break;
    239     case 22: __asan_get_heap_size(); break;
    240     case 23: __asan_get_ownership(0); break;
    241     case 24: __asan_get_unmapped_bytes(); break;
    242     case 25: __asan_poison_memory_region(0, 0); break;
    243     case 26: __asan_unpoison_memory_region(0, 0); break;
    244     case 27: __asan_set_error_exit_code(0); break;
    245     case 28: __asan_stack_free(0, 0, 0); break;
    246     case 29: __asan_stack_malloc(0, 0); break;
    247     case 30: __asan_set_on_error_callback(0); break;
    248     case 31: __asan_default_options(); break;
    249     case 32: __asan_before_dynamic_init(0, 0); break;
    250     case 33: __asan_after_dynamic_init(); break;
    251     case 34: __asan_malloc_hook(0, 0); break;
    252     case 35: __asan_free_hook(0); break;
    253     case 36: __asan_set_symbolize_callback(0); break;
    254   }
    255 }
    256 
    257 static void asan_atexit() {
    258   Printf("AddressSanitizer exit stats:\n");
    259   __asan_print_accumulated_stats();
    260 }
    261 
    262 }  // namespace __asan
    263 
    264 // ---------------------- Interface ---------------- {{{1
    265 using namespace __asan;  // NOLINT
    266 
    267 int NOINLINE __asan_set_error_exit_code(int exit_code) {
    268   int old = flags()->exitcode;
    269   flags()->exitcode = exit_code;
    270   return old;
    271 }
    272 
    273 void NOINLINE __asan_handle_no_return() {
    274   int local_stack;
    275   AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
    276   CHECK(curr_thread);
    277   uptr top = curr_thread->stack_top();
    278   uptr bottom = ((uptr)&local_stack - kPageSize) & ~(kPageSize-1);
    279   PoisonShadow(bottom, top - bottom, 0);
    280 }
    281 
    282 void NOINLINE __asan_set_death_callback(void (*callback)(void)) {
    283   death_callback = callback;
    284 }
    285 
    286 void __asan_init() {
    287   if (asan_inited) return;
    288   CHECK(!asan_init_is_running && "ASan init calls itself!");
    289   asan_init_is_running = true;
    290 
    291   // Make sure we are not statically linked.
    292   AsanDoesNotSupportStaticLinkage();
    293 
    294   SetPrintfAndReportCallback(AppendToErrorMessageBuffer);
    295 
    296   // Initialize flags. This must be done early, because most of the
    297   // initialization steps look at flags().
    298   const char *options = GetEnv("ASAN_OPTIONS");
    299   InitializeFlags(flags(), options);
    300 
    301   if (flags()->verbosity && options) {
    302     Report("Parsed ASAN_OPTIONS: %s\n", options);
    303   }
    304 
    305   // Re-exec ourselves if we need to set additional env or command line args.
    306   MaybeReexec();
    307 
    308   // Setup internal allocator callback.
    309   SetLowLevelAllocateCallback(OnLowLevelAllocate);
    310 
    311   if (flags()->atexit) {
    312     Atexit(asan_atexit);
    313   }
    314 
    315   // interceptors
    316   InitializeAsanInterceptors();
    317 
    318   ReplaceSystemMalloc();
    319   ReplaceOperatorsNewAndDelete();
    320 
    321   if (flags()->verbosity) {
    322     Printf("|| `[%p, %p]` || HighMem    ||\n",
    323            (void*)kHighMemBeg, (void*)kHighMemEnd);
    324     Printf("|| `[%p, %p]` || HighShadow ||\n",
    325            (void*)kHighShadowBeg, (void*)kHighShadowEnd);
    326     Printf("|| `[%p, %p]` || ShadowGap  ||\n",
    327            (void*)kShadowGapBeg, (void*)kShadowGapEnd);
    328     Printf("|| `[%p, %p]` || LowShadow  ||\n",
    329            (void*)kLowShadowBeg, (void*)kLowShadowEnd);
    330     Printf("|| `[%p, %p]` || LowMem     ||\n",
    331            (void*)kLowMemBeg, (void*)kLowMemEnd);
    332     Printf("MemToShadow(shadow): %p %p %p %p\n",
    333            (void*)MEM_TO_SHADOW(kLowShadowBeg),
    334            (void*)MEM_TO_SHADOW(kLowShadowEnd),
    335            (void*)MEM_TO_SHADOW(kHighShadowBeg),
    336            (void*)MEM_TO_SHADOW(kHighShadowEnd));
    337     Printf("red_zone=%zu\n", (uptr)flags()->redzone);
    338     Printf("malloc_context_size=%zu\n", (uptr)flags()->malloc_context_size);
    339 
    340     Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE);
    341     Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY);
    342     Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET);
    343     CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
    344   }
    345 
    346   if (flags()->disable_core) {
    347     DisableCoreDumper();
    348   }
    349 
    350   uptr shadow_start = kLowShadowBeg;
    351   if (kLowShadowBeg > 0) shadow_start -= kMmapGranularity;
    352   uptr shadow_end = kHighShadowEnd;
    353   if (MemoryRangeIsAvailable(shadow_start, shadow_end)) {
    354     if (kLowShadowBeg != kLowShadowEnd) {
    355       // mmap the low shadow plus at least one page.
    356       ReserveShadowMemoryRange(kLowShadowBeg - kMmapGranularity, kLowShadowEnd);
    357     }
    358     // mmap the high shadow.
    359     ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
    360     // protect the gap
    361     void *prot = Mprotect(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
    362     CHECK(prot == (void*)kShadowGapBeg);
    363   } else {
    364     Report("Shadow memory range interleaves with an existing memory mapping. "
    365            "ASan cannot proceed correctly. ABORTING.\n");
    366     DumpProcessMap();
    367     Die();
    368   }
    369 
    370   InstallSignalHandlers();
    371   // Start symbolizer process if necessary.
    372   if (flags()->symbolize) {
    373     const char *external_symbolizer = GetEnv("ASAN_SYMBOLIZER_PATH");
    374     if (external_symbolizer) {
    375       InitializeExternalSymbolizer(external_symbolizer);
    376     }
    377   }
    378 #ifdef _WIN32
    379   __asan_set_symbolize_callback(WinSymbolize);
    380 #endif  // _WIN32
    381 
    382   // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited
    383   // should be set to 1 prior to initializing the threads.
    384   asan_inited = 1;
    385   asan_init_is_running = false;
    386 
    387   asanThreadRegistry().Init();
    388   asanThreadRegistry().GetMain()->ThreadStart();
    389   force_interface_symbols();  // no-op.
    390 
    391   if (flags()->verbosity) {
    392     Report("AddressSanitizer Init done\n");
    393   }
    394 }
    395 
    396 #if defined(ASAN_USE_PREINIT_ARRAY)
    397   // On Linux, we force __asan_init to be called before anyone else
    398   // by placing it into .preinit_array section.
    399   // FIXME: do we have anything like this on Mac?
    400   __attribute__((section(".preinit_array")))
    401     typeof(__asan_init) *__asan_preinit =__asan_init;
    402 #elif defined(_WIN32) && defined(_DLL)
    403   // On Windows, when using dynamic CRT (/MD), we can put a pointer
    404   // to __asan_init into the global list of C initializers.
    405   // See crt0dat.c in the CRT sources for the details.
    406   #pragma section(".CRT$XIB", long, read)  // NOLINT
    407   __declspec(allocate(".CRT$XIB")) void (*__asan_preinit)() = __asan_init;
    408 #endif
    409