1 //===-- asan_rtl.cc -------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is a part of AddressSanitizer, an address sanity checker.
12 // Main file of the ASan run-time library.
13 //===----------------------------------------------------------------------===//
14 #include "asan_activation.h"
15 #include "asan_allocator.h"
16 #include "asan_interceptors.h"
17 #include "asan_interface_internal.h"
18 #include "asan_internal.h"
19 #include "asan_mapping.h"
20 #include "asan_poisoning.h"
21 #include "asan_report.h"
22 #include "asan_stack.h"
23 #include "asan_stats.h"
24 #include "asan_suppressions.h"
25 #include "asan_thread.h"
26 #include "sanitizer_common/sanitizer_atomic.h"
27 #include "sanitizer_common/sanitizer_flags.h"
28 #include "sanitizer_common/sanitizer_libc.h"
29 #include "sanitizer_common/sanitizer_symbolizer.h"
30 #include "lsan/lsan_common.h"
32 int __asan_option_detect_stack_use_after_return; // Global interface symbol.
33 uptr *__asan_test_only_reported_buggy_pointer; // Used only for testing asan.
37 uptr AsanMappingProfile[kAsanMappingProfileSize];
39 static void AsanDie() {
40 static atomic_uint32_t num_calls;
41 if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
42 // Don't die twice - run a busy loop.
45 if (flags()->sleep_before_dying) {
46 Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying);
47 SleepForSeconds(flags()->sleep_before_dying);
49 if (flags()->unmap_shadow_on_exit) {
51 UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
52 UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd);
54 UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
57 if (common_flags()->coverage)
58 __sanitizer_cov_dump();
59 if (flags()->abort_on_error)
61 internal__exit(flags()->exitcode);
64 static void AsanCheckFailed(const char *file, int line, const char *cond,
66 Report("AddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", file,
67 line, cond, (uptr)v1, (uptr)v2);
68 // FIXME: check for infinite recursion without a thread-local counter here.
69 PRINT_CURRENT_STACK_CHECK();
73 // -------------------------- Globals --------------------- {{{1
75 bool asan_init_is_running;
77 #if !ASAN_FIXED_MAPPING
78 uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;
81 // -------------------------- Misc ---------------- {{{1
82 void ShowStatsAndAbort() {
83 __asan_print_accumulated_stats();
87 // ---------------------- mmap -------------------- {{{1
88 // Reserve memory range [beg, end].
89 // We need to use inclusive range because end+1 may not be representable.
90 void ReserveShadowMemoryRange(uptr beg, uptr end) {
91 CHECK_EQ((beg % GetPageSizeCached()), 0);
92 CHECK_EQ(((end + 1) % GetPageSizeCached()), 0);
93 uptr size = end - beg + 1;
94 DecreaseTotalMmap(size); // Don't count the shadow against mmap_limit_mb.
95 void *res = MmapFixedNoReserve(beg, size);
96 if (res != (void*)beg) {
97 Report("ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. "
98 "Perhaps you're using ulimit -v\n", size);
101 if (common_flags()->no_huge_pages_for_shadow)
102 NoHugePagesInRegion(beg, size);
103 if (common_flags()->use_madv_dontdump)
104 DontDumpShadowMemory(beg, size);
107 // --------------- LowLevelAllocateCallbac ---------- {{{1
108 static void OnLowLevelAllocate(uptr ptr, uptr size) {
109 PoisonShadow(ptr, size, kAsanInternalHeapMagic);
112 // -------------------------- Run-time entry ------------------- {{{1
113 // exported functions
114 #define ASAN_REPORT_ERROR(type, is_write, size) \
115 extern "C" NOINLINE INTERFACE_ATTRIBUTE \
116 void __asan_report_ ## type ## size(uptr addr); \
117 void __asan_report_ ## type ## size(uptr addr) { \
118 GET_CALLER_PC_BP_SP; \
119 __asan_report_error(pc, bp, sp, addr, is_write, size); \
122 ASAN_REPORT_ERROR(load, false, 1)
123 ASAN_REPORT_ERROR(load, false, 2)
124 ASAN_REPORT_ERROR(load, false, 4)
125 ASAN_REPORT_ERROR(load, false, 8)
126 ASAN_REPORT_ERROR(load, false, 16)
127 ASAN_REPORT_ERROR(store, true, 1)
128 ASAN_REPORT_ERROR(store, true, 2)
129 ASAN_REPORT_ERROR(store, true, 4)
130 ASAN_REPORT_ERROR(store, true, 8)
131 ASAN_REPORT_ERROR(store, true, 16)
133 #define ASAN_REPORT_ERROR_N(type, is_write) \
134 extern "C" NOINLINE INTERFACE_ATTRIBUTE \
135 void __asan_report_ ## type ## _n(uptr addr, uptr size); \
136 void __asan_report_ ## type ## _n(uptr addr, uptr size) { \
137 GET_CALLER_PC_BP_SP; \
138 __asan_report_error(pc, bp, sp, addr, is_write, size); \
141 ASAN_REPORT_ERROR_N(load, false)
142 ASAN_REPORT_ERROR_N(store, true)
144 #define ASAN_MEMORY_ACCESS_CALLBACK(type, is_write, size) \
145 extern "C" NOINLINE INTERFACE_ATTRIBUTE void __asan_##type##size(uptr addr); \
146 void __asan_##type##size(uptr addr) { \
147 uptr sp = MEM_TO_SHADOW(addr); \
148 uptr s = size <= SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp) \
149 : *reinterpret_cast<u16 *>(sp); \
151 if (UNLIKELY(size >= SHADOW_GRANULARITY || \
152 ((s8)((addr & (SHADOW_GRANULARITY - 1)) + size - 1)) >= \
154 if (__asan_test_only_reported_buggy_pointer) { \
155 *__asan_test_only_reported_buggy_pointer = addr; \
157 GET_CALLER_PC_BP_SP; \
158 __asan_report_error(pc, bp, sp, addr, is_write, size); \
164 ASAN_MEMORY_ACCESS_CALLBACK(load, false, 1)
165 ASAN_MEMORY_ACCESS_CALLBACK(load, false, 2)
166 ASAN_MEMORY_ACCESS_CALLBACK(load, false, 4)
167 ASAN_MEMORY_ACCESS_CALLBACK(load, false, 8)
168 ASAN_MEMORY_ACCESS_CALLBACK(load, false, 16)
169 ASAN_MEMORY_ACCESS_CALLBACK(store, true, 1)
170 ASAN_MEMORY_ACCESS_CALLBACK(store, true, 2)
171 ASAN_MEMORY_ACCESS_CALLBACK(store, true, 4)
172 ASAN_MEMORY_ACCESS_CALLBACK(store, true, 8)
173 ASAN_MEMORY_ACCESS_CALLBACK(store, true, 16)
176 NOINLINE INTERFACE_ATTRIBUTE void __asan_loadN(uptr addr, uptr size) {
177 if (__asan_region_is_poisoned(addr, size)) {
179 __asan_report_error(pc, bp, sp, addr, false, size);
184 NOINLINE INTERFACE_ATTRIBUTE void __asan_storeN(uptr addr, uptr size) {
185 if (__asan_region_is_poisoned(addr, size)) {
187 __asan_report_error(pc, bp, sp, addr, true, size);
191 // Force the linker to keep the symbols for various ASan interface functions.
192 // We want to keep those in the executable in order to let the instrumented
193 // dynamic libraries access the symbol even if it is not used by the executable
194 // itself. This should help if the build system is removing dead code at link
196 static NOINLINE void force_interface_symbols() {
197 volatile int fake_condition = 0; // prevent dead condition elimination.
198 // __asan_report_* functions are noreturn, so we need a switch to prevent
199 // the compiler from removing any of them.
200 switch (fake_condition) {
201 case 1: __asan_report_load1(0); break;
202 case 2: __asan_report_load2(0); break;
203 case 3: __asan_report_load4(0); break;
204 case 4: __asan_report_load8(0); break;
205 case 5: __asan_report_load16(0); break;
206 case 6: __asan_report_store1(0); break;
207 case 7: __asan_report_store2(0); break;
208 case 8: __asan_report_store4(0); break;
209 case 9: __asan_report_store8(0); break;
210 case 10: __asan_report_store16(0); break;
211 case 12: __asan_register_globals(0, 0); break;
212 case 13: __asan_unregister_globals(0, 0); break;
213 case 14: __asan_set_death_callback(0); break;
214 case 15: __asan_set_error_report_callback(0); break;
215 case 16: __asan_handle_no_return(); break;
216 case 17: __asan_address_is_poisoned(0); break;
217 case 25: __asan_poison_memory_region(0, 0); break;
218 case 26: __asan_unpoison_memory_region(0, 0); break;
219 case 27: __asan_set_error_exit_code(0); break;
220 case 30: __asan_before_dynamic_init(0); break;
221 case 31: __asan_after_dynamic_init(); break;
222 case 32: __asan_poison_stack_memory(0, 0); break;
223 case 33: __asan_unpoison_stack_memory(0, 0); break;
224 case 34: __asan_region_is_poisoned(0, 0); break;
225 case 35: __asan_describe_address(0); break;
229 static void asan_atexit() {
230 Printf("AddressSanitizer exit stats:\n");
231 __asan_print_accumulated_stats();
232 // Print AsanMappingProfile.
233 for (uptr i = 0; i < kAsanMappingProfileSize; i++) {
234 if (AsanMappingProfile[i] == 0) continue;
235 Printf("asan_mapping.h:%zd -- %zd\n", i, AsanMappingProfile[i]);
239 static void InitializeHighMemEnd() {
240 #if !ASAN_FIXED_MAPPING
241 kHighMemEnd = GetMaxVirtualAddress();
242 // Increase kHighMemEnd to make sure it's properly
243 // aligned together with kHighMemBeg:
244 kHighMemEnd |= SHADOW_GRANULARITY * GetPageSizeCached() - 1;
245 #endif // !ASAN_FIXED_MAPPING
246 CHECK_EQ((kHighMemBeg % GetPageSizeCached()), 0);
249 static void ProtectGap(uptr a, uptr size) {
250 void *res = Mprotect(a, size);
253 Report("ERROR: Failed to protect the shadow gap. "
254 "ASan cannot proceed correctly. ABORTING.\n");
259 static void PrintAddressSpaceLayout() {
260 Printf("|| `[%p, %p]` || HighMem ||\n",
261 (void*)kHighMemBeg, (void*)kHighMemEnd);
262 Printf("|| `[%p, %p]` || HighShadow ||\n",
263 (void*)kHighShadowBeg, (void*)kHighShadowEnd);
265 Printf("|| `[%p, %p]` || ShadowGap3 ||\n",
266 (void*)kShadowGap3Beg, (void*)kShadowGap3End);
267 Printf("|| `[%p, %p]` || MidMem ||\n",
268 (void*)kMidMemBeg, (void*)kMidMemEnd);
269 Printf("|| `[%p, %p]` || ShadowGap2 ||\n",
270 (void*)kShadowGap2Beg, (void*)kShadowGap2End);
271 Printf("|| `[%p, %p]` || MidShadow ||\n",
272 (void*)kMidShadowBeg, (void*)kMidShadowEnd);
274 Printf("|| `[%p, %p]` || ShadowGap ||\n",
275 (void*)kShadowGapBeg, (void*)kShadowGapEnd);
277 Printf("|| `[%p, %p]` || LowShadow ||\n",
278 (void*)kLowShadowBeg, (void*)kLowShadowEnd);
279 Printf("|| `[%p, %p]` || LowMem ||\n",
280 (void*)kLowMemBeg, (void*)kLowMemEnd);
282 Printf("MemToShadow(shadow): %p %p %p %p",
283 (void*)MEM_TO_SHADOW(kLowShadowBeg),
284 (void*)MEM_TO_SHADOW(kLowShadowEnd),
285 (void*)MEM_TO_SHADOW(kHighShadowBeg),
286 (void*)MEM_TO_SHADOW(kHighShadowEnd));
289 (void*)MEM_TO_SHADOW(kMidShadowBeg),
290 (void*)MEM_TO_SHADOW(kMidShadowEnd));
293 Printf("redzone=%zu\n", (uptr)flags()->redzone);
294 Printf("max_redzone=%zu\n", (uptr)flags()->max_redzone);
295 Printf("quarantine_size_mb=%zuM\n", (uptr)flags()->quarantine_size_mb);
296 Printf("malloc_context_size=%zu\n",
297 (uptr)common_flags()->malloc_context_size);
299 Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE);
300 Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY);
301 Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET);
302 CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
304 CHECK(kMidShadowBeg > kLowShadowEnd &&
305 kMidMemBeg > kMidShadowEnd &&
306 kHighShadowBeg > kMidMemEnd);
309 static void AsanInitInternal() {
310 if (LIKELY(asan_inited)) return;
311 SanitizerToolName = "AddressSanitizer";
312 CHECK(!asan_init_is_running && "ASan init calls itself!");
313 asan_init_is_running = true;
315 // Initialize flags. This must be done early, because most of the
316 // initialization steps look at flags().
319 SetCanPoisonMemory(flags()->poison_heap);
320 SetMallocContextSize(common_flags()->malloc_context_size);
322 InitializeHighMemEnd();
324 // Make sure we are not statically linked.
325 AsanDoesNotSupportStaticLinkage();
327 // Install tool-specific callbacks in sanitizer_common.
328 SetDieCallback(AsanDie);
329 SetCheckFailedCallback(AsanCheckFailed);
330 SetPrintfAndReportCallback(AppendToErrorMessageBuffer);
332 __sanitizer_set_report_path(common_flags()->log_path);
334 // Enable UAR detection, if required.
335 __asan_option_detect_stack_use_after_return =
336 flags()->detect_stack_use_after_return;
338 // Re-exec ourselves if we need to set additional env or command line args.
341 // Setup internal allocator callback.
342 SetLowLevelAllocateCallback(OnLowLevelAllocate);
344 InitializeAsanInterceptors();
346 // Enable system log ("adb logcat") on Android.
347 // Doing this before interceptors are initialized crashes in:
348 // AsanInitInternal -> android_log_write -> __interceptor_strcmp
351 ReplaceSystemMalloc();
353 uptr shadow_start = kLowShadowBeg;
355 shadow_start -= GetMmapGranularity();
356 bool full_shadow_is_available =
357 MemoryRangeIsAvailable(shadow_start, kHighShadowEnd);
359 #if SANITIZER_LINUX && defined(__x86_64__) && defined(_LP64) && \
361 if (!full_shadow_is_available) {
362 kMidMemBeg = kLowMemEnd < 0x3000000000ULL ? 0x3000000000ULL : 0;
363 kMidMemEnd = kLowMemEnd < 0x3000000000ULL ? 0x4fffffffffULL : 0;
367 if (Verbosity()) PrintAddressSpaceLayout();
369 DisableCoreDumperIfNecessary();
371 if (full_shadow_is_available) {
372 // mmap the low shadow plus at least one page at the left.
374 ReserveShadowMemoryRange(shadow_start, kLowShadowEnd);
375 // mmap the high shadow.
376 ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
378 ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
379 CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1);
380 } else if (kMidMemBeg &&
381 MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) &&
382 MemoryRangeIsAvailable(kMidMemEnd + 1, kHighShadowEnd)) {
383 CHECK(kLowShadowBeg != kLowShadowEnd);
384 // mmap the low shadow plus at least one page at the left.
385 ReserveShadowMemoryRange(shadow_start, kLowShadowEnd);
386 // mmap the mid shadow.
387 ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd);
388 // mmap the high shadow.
389 ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
391 ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
392 ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1);
393 ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1);
395 Report("Shadow memory range interleaves with an existing memory mapping. "
396 "ASan cannot proceed correctly. ABORTING.\n");
397 Report("ASan shadow was supposed to be located in the [%p-%p] range.\n",
398 shadow_start, kHighShadowEnd);
403 AsanTSDInit(PlatformTSDDtor);
404 InstallDeadlySignalHandlers(AsanOnSIGSEGV);
406 AllocatorOptions allocator_options;
407 allocator_options.SetFrom(flags(), common_flags());
408 InitializeAllocator(allocator_options);
410 MaybeStartBackgroudThread();
411 SetSoftRssLimitExceededCallback(AsanSoftRssLimitExceededCallback);
413 // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited
414 // should be set to 1 prior to initializing the threads.
416 asan_init_is_running = false;
421 InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
423 // Now that ASan runtime is (mostly) initialized, deactivate it if
424 // necessary, so that it can be re-activated when requested.
425 if (flags()->start_deactivated)
431 // Create main thread.
432 AsanThread *main_thread = AsanThread::Create(
433 /* start_routine */ nullptr, /* arg */ nullptr, /* parent_tid */ 0,
434 /* stack */ nullptr, /* detached */ true);
435 CHECK_EQ(0, main_thread->tid());
436 SetCurrentThread(main_thread);
437 main_thread->ThreadStart(internal_getpid(),
438 /* signal_thread_is_registered */ nullptr);
439 force_interface_symbols(); // no-op.
440 SanitizerInitializeUnwinder();
442 #if CAN_SANITIZE_LEAKS
443 __lsan::InitCommonLsan();
444 if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) {
445 Atexit(__lsan::DoLeakCheck);
447 #endif // CAN_SANITIZE_LEAKS
449 InitializeSuppressions();
451 VReport(1, "AddressSanitizer Init done\n");
454 // Initialize as requested from some part of ASan runtime library (interceptors,
456 void AsanInitFromRtl() {
461 // Initialize runtime in case it's LD_PRELOAD-ed into unsanitized executable
462 // (and thus normal initializer from .preinit_array haven't run).
464 class AsanInitializer {
467 AsanCheckIncompatibleRT();
468 AsanCheckDynamicRTPrereqs();
473 static AsanInitializer asan_initializer;
474 #endif // ASAN_DYNAMIC
476 } // namespace __asan
478 // ---------------------- Interface ---------------- {{{1
479 using namespace __asan; // NOLINT
481 int NOINLINE __asan_set_error_exit_code(int exit_code) {
482 int old = flags()->exitcode;
483 flags()->exitcode = exit_code;
487 void NOINLINE __asan_handle_no_return() {
489 AsanThread *curr_thread = GetCurrentThread();
491 uptr PageSize = GetPageSizeCached();
492 uptr top = curr_thread->stack_top();
493 uptr bottom = ((uptr)&local_stack - PageSize) & ~(PageSize-1);
494 static const uptr kMaxExpectedCleanupSize = 64 << 20; // 64M
495 if (top - bottom > kMaxExpectedCleanupSize) {
496 static bool reported_warning = false;
497 if (reported_warning)
499 reported_warning = true;
500 Report("WARNING: ASan is ignoring requested __asan_handle_no_return: "
501 "stack top: %p; bottom %p; size: %p (%zd)\n"
502 "False positive error reports may follow\n"
504 "http://code.google.com/p/address-sanitizer/issues/detail?id=189\n",
505 top, bottom, top - bottom, top - bottom);
508 PoisonShadow(bottom, top - bottom, 0);
509 if (curr_thread->has_fake_stack())
510 curr_thread->fake_stack()->HandleNoReturn();
513 void NOINLINE __asan_set_death_callback(void (*callback)(void)) {
514 SetUserDieCallback(callback);
517 // Initialize as requested from instrumented application code.
518 // We use this call as a trigger to wake up ASan from deactivated state.
520 AsanCheckIncompatibleRT();