asan_rtl.cc revision 89c1384464848c1ad041becf8b97936fa10de21b
1474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org//===-- asan_rtl.cc -------------------------------------------------------===// 2474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// 3474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// The LLVM Compiler Infrastructure 4474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// 5474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// This file is distributed under the University of Illinois Open Source 6474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// License. See LICENSE.TXT for details. 7474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// 8474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org//===----------------------------------------------------------------------===// 9474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// 10474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// This file is a part of AddressSanitizer, an address sanity checker. 11474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// 12474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// Main file of the ASan run-time library. 13474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org//===----------------------------------------------------------------------===// 14474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "asan_allocator.h" 15474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "asan_interceptors.h" 16474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "asan_internal.h" 17474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "asan_mapping.h" 18474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "asan_report.h" 19474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "asan_stack.h" 20474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "asan_stats.h" 21474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "asan_thread.h" 22474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "asan_thread_registry.h" 23474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "sanitizer_common/sanitizer_atomic.h" 24474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "sanitizer_common/sanitizer_flags.h" 25474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "sanitizer_common/sanitizer_libc.h" 26474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "sanitizer_common/sanitizer_symbolizer.h" 27474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 28474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgnamespace __asan { 29474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 30474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orguptr AsanMappingProfile[kAsanMappingProfileSize]; 31474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 32474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void AsanDie() { 33474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org static atomic_uint32_t num_calls; 34474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) { 35474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org // Don't die twice - run a busy loop. 36474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org while (1) { } 37474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org } 38474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org if (flags()->sleep_before_dying) { 39474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying); 40474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org SleepForSeconds(flags()->sleep_before_dying); 41474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org } 42474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org if (flags()->unmap_shadow_on_exit) { 43474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org if (kMidMemBeg) { 448b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg); 458b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd); 46474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org } else { 47474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg); 48474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org } 49474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org } 50dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org if (death_callback) 51dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org death_callback(); 52dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org if (flags()->abort_on_error) 53474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org Abort(); 54474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org internal__exit(flags()->exitcode); 55474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 56474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 57474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void AsanCheckFailed(const char *file, int line, const char *cond, 58474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org u64 v1, u64 v2) { 59474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org Report("AddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", 60474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org file, line, cond, (uptr)v1, (uptr)v2); 61474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org // FIXME: check for infinite recursion without a thread-local counter here. 6276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org PRINT_CURRENT_STACK(); 63474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org Die(); 64474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 65167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org 66474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// -------------------------- Flags ------------------------- {{{1 67474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const int kDeafultMallocContextSize = 30; 68474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 69474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic Flags asan_flags; 70474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 71474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgFlags *flags() { 72474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org return &asan_flags; 73474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 74474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 75474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const char *MaybeCallAsanDefaultOptions() { 76474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org return (&__asan_default_options) ? __asan_default_options() : ""; 77474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 78474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 79474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic const char *MaybeUseAsanDefaultOptionsCompileDefiniton() { 80167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org#ifdef ASAN_DEFAULT_OPTIONS 816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org// Stringize the macro value. 82474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org# define ASAN_STRINGIZE(x) #x 83474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org# define ASAN_STRINGIZE_OPTIONS(options) ASAN_STRINGIZE(options) 84474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org return ASAN_STRINGIZE_OPTIONS(ASAN_DEFAULT_OPTIONS); 85474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#else 86474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org return ""; 87474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif 88474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 89474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 90474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void ParseFlagsFromString(Flags *f, const char *str) { 91474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->quarantine_size, "quarantine_size"); 92474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->symbolize, "symbolize"); 93474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->verbosity, "verbosity"); 94474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->redzone, "redzone"); 95474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org CHECK(f->redzone >= 16); 96474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org CHECK(IsPowerOfTwo(f->redzone)); 97474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 98474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->debug, "debug"); 99474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->report_globals, "report_globals"); 10047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org ParseFlag(str, &f->check_initialization_order, "initialization_order"); 10147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org ParseFlag(str, &f->malloc_context_size, "malloc_context_size"); 10247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org CHECK((uptr)f->malloc_context_size <= kStackTraceMax); 10347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org 104474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->replace_str, "replace_str"); 105474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->replace_intrin, "replace_intrin"); 106474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->mac_ignore_invalid_free, "mac_ignore_invalid_free"); 107474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->use_fake_stack, "use_fake_stack"); 108474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->max_malloc_fill_size, "max_malloc_fill_size"); 109474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->exitcode, "exitcode"); 110474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->allow_user_poisoning, "allow_user_poisoning"); 111474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->sleep_before_dying, "sleep_before_dying"); 112474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->handle_segv, "handle_segv"); 113474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->use_sigaltstack, "use_sigaltstack"); 114474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->check_malloc_usable_size, "check_malloc_usable_size"); 115474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->unmap_shadow_on_exit, "unmap_shadow_on_exit"); 1166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ParseFlag(str, &f->abort_on_error, "abort_on_error"); 1176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org ParseFlag(str, &f->print_stats, "print_stats"); 118474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->print_legend, "print_legend"); 119474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->atexit, "atexit"); 120474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->disable_core, "disable_core"); 121474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->strip_path_prefix, "strip_path_prefix"); 122474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->allow_reexec, "allow_reexec"); 123474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->print_full_thread_history, "print_full_thread_history"); 124474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->log_path, "log_path"); 125474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->fast_unwind_on_fatal, "fast_unwind_on_fatal"); 126474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->fast_unwind_on_malloc, "fast_unwind_on_malloc"); 127474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->poison_heap, "poison_heap"); 128474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->alloc_dealloc_mismatch, "alloc_dealloc_mismatch"); 129474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->use_stack_depot, "use_stack_depot"); 130474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlag(str, &f->strict_memcmp, "strict_memcmp"); 131474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 132474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 1336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgstatic const char *asan_external_symbolizer; 134474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 135474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvoid InitializeFlags(Flags *f, const char *env) { 136474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org internal_memset(f, 0, sizeof(*f)); 137474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 138474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->quarantine_size = (ASAN_LOW_MEMORY) ? 1UL << 26 : 1UL << 28; 139474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->symbolize = (asan_external_symbolizer != 0); 140474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->verbosity = 0; 141474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->redzone = ASAN_ALLOCATOR_VERSION == 2 ? 16 : (ASAN_LOW_MEMORY) ? 64 : 128; 142474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->debug = false; 143474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->report_globals = 1; 144474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->check_initialization_order = false; 145474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->malloc_context_size = kDeafultMallocContextSize; 146474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->replace_str = true; 147474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->replace_intrin = true; 148474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->mac_ignore_invalid_free = false; 149474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->use_fake_stack = true; 150474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->max_malloc_fill_size = 0; 151474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->exitcode = ASAN_DEFAULT_FAILURE_EXITCODE; 152474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->allow_user_poisoning = true; 153474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->sleep_before_dying = 0; 154474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->handle_segv = ASAN_NEEDS_SEGV; 155474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->use_sigaltstack = false; 156474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->check_malloc_usable_size = true; 15788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org f->unmap_shadow_on_exit = false; 15888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org f->abort_on_error = false; 159474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->print_stats = false; 160474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->print_legend = true; 161474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->atexit = false; 162474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->disable_core = (SANITIZER_WORDSIZE == 64); 163474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->strip_path_prefix = ""; 164474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->allow_reexec = true; 165474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->print_full_thread_history = true; 166474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->log_path = 0; 167474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->fast_unwind_on_fatal = false; 168474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->fast_unwind_on_malloc = true; 169474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->poison_heap = true; 170474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org // Turn off alloc/dealloc mismatch checker on Mac for now. 1716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // TODO(glider): Fix known issues and enable this back. 17288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org f->alloc_dealloc_mismatch = (SANITIZER_MAC == 0);; 17388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org f->use_stack_depot = true; // Only affects allocator2. 174474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org f->strict_memcmp = true; 175474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 176474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org // Override from compile definition. 177474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlagsFromString(f, MaybeUseAsanDefaultOptionsCompileDefiniton()); 178474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 179474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org // Override from user-specified string. 180474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlagsFromString(f, MaybeCallAsanDefaultOptions()); 181474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org if (flags()->verbosity) { 182474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org Report("Using the defaults from __asan_default_options: %s\n", 183474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org MaybeCallAsanDefaultOptions()); 184474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org } 185474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 186474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org // Override from command line. 187474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org ParseFlagsFromString(f, env); 188474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 189474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 190474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// -------------------------- Globals --------------------- {{{1 191474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgint asan_inited; 192474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgbool asan_init_is_running; 193474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvoid (*death_callback)(void); 194474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 195474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if !ASAN_FIXED_MAPPING 196474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orguptr kHighMemEnd, kMidMemBeg, kMidMemEnd; 1976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#endif 1986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 1996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org// -------------------------- Misc ---------------- {{{1 2006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgvoid ShowStatsAndAbort() { 201474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org __asan_print_accumulated_stats(); 202474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org Die(); 203474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 204474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 205474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// ---------------------- mmap -------------------- {{{1 206474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// Reserve memory range [beg, end]. 207474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void ReserveShadowMemoryRange(uptr beg, uptr end) { 208474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org CHECK((beg % GetPageSizeCached()) == 0); 209474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org CHECK(((end + 1) % GetPageSizeCached()) == 0); 210474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org uptr size = end - beg + 1; 211474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org void *res = MmapFixedNoReserve(beg, size); 212474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org if (res != (void*)beg) { 213474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org Report("ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. " 214474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org "Perhaps you're using ulimit -v\n", size); 215474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org Abort(); 216474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org } 2176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org} 2186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 219474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// --------------- LowLevelAllocateCallbac ---------- {{{1 22076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgstatic void OnLowLevelAllocate(uptr ptr, uptr size) { 22176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org PoisonShadow(ptr, size, kAsanInternalHeapMagic); 22276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org} 22376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org 22476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// -------------------------- Run-time entry ------------------- {{{1 22576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org// exported functions 22676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#define ASAN_REPORT_ERROR(type, is_write, size) \ 22776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgextern "C" NOINLINE INTERFACE_ATTRIBUTE \ 22876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgvoid __asan_report_ ## type ## size(uptr addr); \ 22976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgvoid __asan_report_ ## type ## size(uptr addr) { \ 23076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org GET_CALLER_PC_BP_SP; \ 23176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org __asan_report_error(pc, bp, sp, addr, is_write, size); \ 23276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org} 23376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org 23476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgASAN_REPORT_ERROR(load, false, 1) 23576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgASAN_REPORT_ERROR(load, false, 2) 23676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgASAN_REPORT_ERROR(load, false, 4) 23776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgASAN_REPORT_ERROR(load, false, 8) 23876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgASAN_REPORT_ERROR(load, false, 16) 23976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgASAN_REPORT_ERROR(store, true, 1) 24076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgASAN_REPORT_ERROR(store, true, 2) 24176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgASAN_REPORT_ERROR(store, true, 4) 24276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgASAN_REPORT_ERROR(store, true, 8) 24376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgASAN_REPORT_ERROR(store, true, 16) 24476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org 24576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org#define ASAN_REPORT_ERROR_N(type, is_write) \ 24676e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgextern "C" NOINLINE INTERFACE_ATTRIBUTE \ 24776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgvoid __asan_report_ ## type ## _n(uptr addr, uptr size); \ 24876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.orgvoid __asan_report_ ## type ## _n(uptr addr, uptr size) { \ 24976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org GET_CALLER_PC_BP_SP; \ 250474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org __asan_report_error(pc, bp, sp, addr, is_write, size); \ 251474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 252474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 2536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgASAN_REPORT_ERROR_N(load, false) 2546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgASAN_REPORT_ERROR_N(store, true) 2556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 2566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org// Force the linker to keep the symbols for various ASan interface functions. 2576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org// We want to keep those in the executable in order to let the instrumented 2586fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org// dynamic libraries access the symbol even if it is not used by the executable 2596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org// itself. This should help if the build system is removing dead code at link 260474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// time. 261474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic NOINLINE void force_interface_symbols() { 262474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org volatile int fake_condition = 0; // prevent dead condition elimination. 263474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org // __asan_report_* functions are noreturn, so we need a switch to prevent 264474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org // the compiler from removing any of them. 265474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org switch (fake_condition) { 266474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 1: __asan_report_load1(0); break; 267474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 2: __asan_report_load2(0); break; 268474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 3: __asan_report_load4(0); break; 269474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 4: __asan_report_load8(0); break; 270167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org case 5: __asan_report_load16(0); break; 271167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org case 6: __asan_report_store1(0); break; 2726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org case 7: __asan_report_store2(0); break; 273167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org case 8: __asan_report_store4(0); break; 274474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 9: __asan_report_store8(0); break; 275474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 10: __asan_report_store16(0); break; 276474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 12: __asan_register_globals(0, 0); break; 277474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 13: __asan_unregister_globals(0, 0); break; 278474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 14: __asan_set_death_callback(0); break; 279474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 15: __asan_set_error_report_callback(0); break; 280474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 16: __asan_handle_no_return(); break; 281474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 17: __asan_address_is_poisoned(0); break; 282474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 18: __asan_get_allocated_size(0); break; 283474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 19: __asan_get_current_allocated_bytes(); break; 2846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org case 20: __asan_get_estimated_allocated_size(0); break; 2856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org case 21: __asan_get_free_bytes(); break; 2866fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org case 22: __asan_get_heap_size(); break; 287474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 23: __asan_get_ownership(0); break; 288474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 24: __asan_get_unmapped_bytes(); break; 289474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 25: __asan_poison_memory_region(0, 0); break; 290474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 26: __asan_unpoison_memory_region(0, 0); break; 291474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 27: __asan_set_error_exit_code(0); break; 292474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org case 28: __asan_stack_free(0, 0, 0); break; 2936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org case 29: __asan_stack_malloc(0, 0); break; 2946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org case 30: __asan_before_dynamic_init(0, 0); break; 2956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org case 31: __asan_after_dynamic_init(); break; 2966fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org case 32: __asan_poison_stack_memory(0, 0); break; 2976fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org case 33: __asan_unpoison_stack_memory(0, 0); break; 2986fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org case 34: __asan_region_is_poisoned(0, 0); break; 2996fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org case 35: __asan_describe_address(0); break; 3006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 3016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org} 30247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org 3036fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgstatic void asan_atexit() { 3046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org Printf("AddressSanitizer exit stats:\n"); 30576e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org __asan_print_accumulated_stats(); 3066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // Print AsanMappingProfile. 3076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org for (uptr i = 0; i < kAsanMappingProfileSize; i++) { 30841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (AsanMappingProfile[i] == 0) continue; 3096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org Printf("asan_mapping.h:%zd -- %zd\n", i, AsanMappingProfile[i]); 3106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org } 3116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org} 3126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 3136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgstatic void InitializeHighMemEnd() { 3146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#if !ASAN_FIXED_MAPPING 3156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#if SANITIZER_WORDSIZE == 64 3166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org# if defined(__powerpc64__) 317474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org // FIXME: 318474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org // On PowerPC64 we have two different address space layouts: 44- and 46-bit. 319474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org // We somehow need to figure our which one we are using now and choose 3206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // one of 0x00000fffffffffffUL and 0x00003fffffffffffUL. 3216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // Note that with 'ulimit -s unlimited' the stack is moved away from the top 3226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // of the address space, so simply checking the stack address is not enough. 3236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org kHighMemEnd = (1ULL << 44) - 1; // 0x00000fffffffffffUL 3246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org# else 3256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org kHighMemEnd = (1ULL << 47) - 1; // 0x00007fffffffffffUL; 326474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org# endif 327474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#else // SANITIZER_WORDSIZE == 32 328474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org kHighMemEnd = (1ULL << 32) - 1; // 0xffffffff; 329474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif // SANITIZER_WORDSIZE 330474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#endif // !ASAN_FIXED_MAPPING 331474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 332474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 333474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgstatic void ProtectGap(uptr a, uptr size) { 334474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org CHECK_EQ(a, (uptr)Mprotect(a, size)); 335474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 336474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 3376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgstatic void PrintAddressSpaceLayout() { 3386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org Printf("|| `[%p, %p]` || HighMem ||\n", 3396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org (void*)kHighMemBeg, (void*)kHighMemEnd); 3406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org Printf("|| `[%p, %p]` || HighShadow ||\n", 3416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org (void*)kHighShadowBeg, (void*)kHighShadowEnd); 3426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org if (kMidMemBeg) { 3436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org Printf("|| `[%p, %p]` || ShadowGap3 ||\n", 3446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org (void*)kShadowGap3Beg, (void*)kShadowGap3End); 345d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org Printf("|| `[%p, %p]` || MidMem ||\n", 3466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org (void*)kMidMemBeg, (void*)kMidMemEnd); 3476fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org Printf("|| `[%p, %p]` || ShadowGap2 ||\n", 3486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org (void*)kShadowGap2Beg, (void*)kShadowGap2End); 3496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org Printf("|| `[%p, %p]` || MidShadow ||\n", 3506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org (void*)kMidShadowBeg, (void*)kMidShadowEnd); 351474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org } 352474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org Printf("|| `[%p, %p]` || ShadowGap ||\n", 353167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org (void*)kShadowGapBeg, (void*)kShadowGapEnd); 354167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org if (kLowShadowBeg) { 355167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org Printf("|| `[%p, %p]` || LowShadow ||\n", 356167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org (void*)kLowShadowBeg, (void*)kLowShadowEnd); 357167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org Printf("|| `[%p, %p]` || LowMem ||\n", 358167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org (void*)kLowMemBeg, (void*)kLowMemEnd); 359167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org } 360167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org Printf("MemToShadow(shadow): %p %p %p %p", 361167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org (void*)MEM_TO_SHADOW(kLowShadowBeg), 362167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org (void*)MEM_TO_SHADOW(kLowShadowEnd), 363167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org (void*)MEM_TO_SHADOW(kHighShadowBeg), 364474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org (void*)MEM_TO_SHADOW(kHighShadowEnd)); 365474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org if (kMidMemBeg) { 36641294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org Printf(" %p %p", 367474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org (void*)MEM_TO_SHADOW(kMidShadowBeg), 368474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org (void*)MEM_TO_SHADOW(kMidShadowEnd)); 369474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org } 37041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org Printf("\n"); 371474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org Printf("red_zone=%zu\n", (uptr)flags()->redzone); 372474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org Printf("malloc_context_size=%zu\n", (uptr)flags()->malloc_context_size); 373474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 374474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE); 375474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY); 376474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET); 377474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7); 378474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org if (kMidMemBeg) 379474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org CHECK(kMidShadowBeg > kLowShadowEnd && 380474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org kMidMemBeg > kMidShadowEnd && 381474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org kHighShadowBeg > kMidMemEnd); 382474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 383474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 3846fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org} // namespace __asan 3856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 386474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org// ---------------------- Interface ---------------- {{{1 387474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgusing namespace __asan; // NOLINT 388474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 389474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#if !SANITIZER_SUPPORTS_WEAK_HOOKS 390474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgextern "C" { 391474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgSANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE 392474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgconst char* __asan_default_options() { return ""; } 3936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org} // extern "C" 3946fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#endif 3956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 3966fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgint NOINLINE __asan_set_error_exit_code(int exit_code) { 397474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org int old = flags()->exitcode; 398474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org flags()->exitcode = exit_code; 399474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org return old; 4006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org} 4016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 4026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgvoid NOINLINE __asan_handle_no_return() { 403474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org int local_stack; 404474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org AsanThread *curr_thread = GetCurrentThread(); 4056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org CHECK(curr_thread); 4066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org uptr PageSize = GetPageSizeCached(); 407474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org uptr top = curr_thread->stack_top(); 408474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org uptr bottom = ((uptr)&local_stack - PageSize) & ~(PageSize-1); 409474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org PoisonShadow(bottom, top - bottom, 0); 410474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 411474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 4126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgvoid NOINLINE __asan_set_death_callback(void (*callback)(void)) { 413474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org death_callback = callback; 414474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org} 415474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org 416474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvoid __asan_init() { 417474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org if (asan_inited) return; 418474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org SanitizerToolName = "AddressSanitizer"; 419dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org CHECK(!asan_init_is_running && "ASan init calls itself!"); 4206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org asan_init_is_running = true; 4216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org InitializeHighMemEnd(); 4226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 4236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org // Make sure we are not statically linked. 4246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org AsanDoesNotSupportStaticLinkage(); 4256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org 426474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org // Install tool-specific callbacks in sanitizer_common. 427474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org SetDieCallback(AsanDie); 42841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org SetCheckFailedCallback(AsanCheckFailed); 42941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org SetPrintfAndReportCallback(AppendToErrorMessageBuffer); 43041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 43141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Check if external symbolizer is defined before parsing the flags. 43241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org asan_external_symbolizer = GetEnv("ASAN_SYMBOLIZER_PATH"); 433dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org // Initialize flags. This must be done early, because most of the 434dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org // initialization steps look at flags(). 435dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org const char *options = GetEnv("ASAN_OPTIONS"); 436dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org InitializeFlags(flags(), options); 4378b26fe55f3e4daa2311dbd2d95e8ac2b4e080685johannkoenig@chromium.org __sanitizer_set_report_path(flags()->log_path); 438 439 if (flags()->verbosity && options) { 440 Report("Parsed ASAN_OPTIONS: %s\n", options); 441 } 442 443 // Re-exec ourselves if we need to set additional env or command line args. 444 MaybeReexec(); 445 446 // Setup internal allocator callback. 447 SetLowLevelAllocateCallback(OnLowLevelAllocate); 448 449 if (flags()->atexit) { 450 Atexit(asan_atexit); 451 } 452 453 // interceptors 454 InitializeAsanInterceptors(); 455 456 ReplaceSystemMalloc(); 457 ReplaceOperatorsNewAndDelete(); 458 459 uptr shadow_start = kLowShadowBeg; 460 if (kLowShadowBeg) shadow_start -= GetMmapGranularity(); 461 uptr shadow_end = kHighShadowEnd; 462 bool full_shadow_is_available = 463 MemoryRangeIsAvailable(shadow_start, shadow_end); 464 465#if SANITIZER_LINUX && defined(__x86_64__) && !ASAN_FIXED_MAPPING 466 if (!full_shadow_is_available) { 467 kMidMemBeg = kLowMemEnd < 0x3000000000ULL ? 0x3000000000ULL : 0; 468 kMidMemEnd = kLowMemEnd < 0x3000000000ULL ? 0x4fffffffffULL : 0; 469 } 470#endif 471 472 if (flags()->verbosity) 473 PrintAddressSpaceLayout(); 474 475 if (flags()->disable_core) { 476 DisableCoreDumper(); 477 } 478 479 if (full_shadow_is_available) { 480 // mmap the low shadow plus at least one page at the left. 481 if (kLowShadowBeg) 482 ReserveShadowMemoryRange(shadow_start, kLowShadowEnd); 483 // mmap the high shadow. 484 ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd); 485 // protect the gap. 486 ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); 487 } else if (kMidMemBeg && 488 MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) && 489 MemoryRangeIsAvailable(kMidMemEnd + 1, shadow_end)) { 490 CHECK(kLowShadowBeg != kLowShadowEnd); 491 // mmap the low shadow plus at least one page at the left. 492 ReserveShadowMemoryRange(shadow_start, kLowShadowEnd); 493 // mmap the mid shadow. 494 ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd); 495 // mmap the high shadow. 496 ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd); 497 // protect the gaps. 498 ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); 499 ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1); 500 ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1); 501 } else { 502 Report("Shadow memory range interleaves with an existing memory mapping. " 503 "ASan cannot proceed correctly. ABORTING.\n"); 504 DumpProcessMap(); 505 Die(); 506 } 507 508 InstallSignalHandlers(); 509 // Start symbolizer process if necessary. 510 if (flags()->symbolize && asan_external_symbolizer && 511 asan_external_symbolizer[0]) { 512 InitializeExternalSymbolizer(asan_external_symbolizer); 513 } 514 515 // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited 516 // should be set to 1 prior to initializing the threads. 517 asan_inited = 1; 518 asan_init_is_running = false; 519 520 asanThreadRegistry().Init(); 521 asanThreadRegistry().GetMain()->ThreadStart(); 522 force_interface_symbols(); // no-op. 523 524 InitializeAllocator(); 525 526 if (flags()->verbosity) { 527 Report("AddressSanitizer Init done\n"); 528 } 529} 530