1//===-- asan_rtl.cpp ------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a part of AddressSanitizer, an address sanity checker.
10//
11// Main file of the ASan run-time library.
12//===----------------------------------------------------------------------===//
13
14#include "asan_activation.h"
15#include "asan_allocator.h"
16#include "asan_fake_stack.h"
17#include "asan_interceptors.h"
18#include "asan_interface_internal.h"
19#include "asan_internal.h"
20#include "asan_mapping.h"
21#include "asan_poisoning.h"
22#include "asan_report.h"
23#include "asan_stack.h"
24#include "asan_stats.h"
25#include "asan_suppressions.h"
26#include "asan_thread.h"
27#include "lsan/lsan_common.h"
28#include "sanitizer_common/sanitizer_atomic.h"
29#include "sanitizer_common/sanitizer_flags.h"
30#include "sanitizer_common/sanitizer_interface_internal.h"
31#include "sanitizer_common/sanitizer_libc.h"
32#include "sanitizer_common/sanitizer_symbolizer.h"
33#include "ubsan/ubsan_init.h"
34#include "ubsan/ubsan_platform.h"
35
36uptr __asan_shadow_memory_dynamic_address; // Global interface symbol.
37int __asan_option_detect_stack_use_after_return; // Global interface symbol.
38uptr *__asan_test_only_reported_buggy_pointer; // Used only for testing asan.
39
40namespace __asan {
41
42uptr AsanMappingProfile[kAsanMappingProfileSize];
43
44static void AsanDie() {
45 static atomic_uint32_t num_calls;
46 if (atomic_fetch_add(a: &num_calls, v: 1, mo: memory_order_relaxed) != 0) {
47 // Don't die twice - run a busy loop.
48 while (1) {
49 internal_sched_yield();
50 }
51 }
52 if (common_flags()->print_module_map >= 1)
53 DumpProcessMap();
54
55 WaitForDebugger(seconds: flags()->sleep_before_dying, label: "before dying");
56
57 if (flags()->unmap_shadow_on_exit) {
58#if SANITIZER_AIX && SANITIZER_WORDSIZE == 64
59 UnmapOrDie((void*)kHighShadowBeg, kHighShadowEnd - kHighShadowBeg);
60 UnmapOrDie((void*)kMidShadowBeg, kMidShadowEnd - kMidShadowBeg);
61
62 UnmapOrDie((void*)kMid2ShadowBeg, kMid2ShadowEnd - kMid2ShadowBeg);
63 UnmapOrDie((void*)kMid3ShadowBeg, kMid3ShadowEnd - kMid3ShadowBeg);
64
65 UnmapOrDie((void*)kLowShadowBeg, kLowShadowEnd - kLowShadowBeg);
66#else
67 if (kMidMemBeg) {
68 UnmapOrDie(addr: (void*)kLowShadowBeg, size: kMidMemBeg - kLowShadowBeg);
69 UnmapOrDie(addr: (void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd);
70 } else {
71 if (kHighShadowEnd)
72 UnmapOrDie(addr: (void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
73 }
74#endif
75 }
76}
77
78static void CheckUnwind() {
79 GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_check);
80 stack.Print();
81}
82
83// -------------------------- Globals --------------------- {{{1
84static StaticSpinMutex asan_inited_mutex;
85static atomic_uint8_t asan_inited = {.val_dont_use: 0};
86
87static void SetAsanInited() {
88 atomic_store(a: &asan_inited, v: 1, mo: memory_order_release);
89}
90
91bool AsanInited() {
92 return atomic_load(a: &asan_inited, mo: memory_order_acquire) == 1;
93}
94
95bool replace_intrin_cached;
96
97#if !ASAN_FIXED_MAPPING
98# if !(SANITIZER_AIX && SANITIZER_WORDSIZE == 64)
99uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;
100# else
101uptr kHighMemEnd;
102# endif
103#endif
104
105// -------------------------- Misc ---------------- {{{1
106void ShowStatsAndAbort() {
107 __asan_print_accumulated_stats();
108 Die();
109}
110
111NOINLINE
112static void ReportGenericErrorWrapper(uptr addr, bool is_write, int size,
113 int exp_arg, bool fatal) {
114 GET_CALLER_PC_BP_SP;
115 ReportGenericError(pc, bp, sp, addr, is_write, access_size: size, exp: exp_arg, fatal);
116}
117
118// --------------- LowLevelAllocateCallbac ---------- {{{1
119static void OnLowLevelAllocate(uptr ptr, uptr size) {
120 PoisonShadow(addr: ptr, size, value: kAsanInternalHeapMagic);
121}
122
123// -------------------------- Run-time entry ------------------- {{{1
124// exported functions
125#define ASAN_REPORT_ERROR(type, is_write, size) \
126extern "C" NOINLINE INTERFACE_ATTRIBUTE \
127void __asan_report_ ## type ## size(uptr addr) { \
128 GET_CALLER_PC_BP_SP; \
129 ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \
130} \
131extern "C" NOINLINE INTERFACE_ATTRIBUTE \
132void __asan_report_exp_ ## type ## size(uptr addr, u32 exp) { \
133 GET_CALLER_PC_BP_SP; \
134 ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \
135} \
136extern "C" NOINLINE INTERFACE_ATTRIBUTE \
137void __asan_report_ ## type ## size ## _noabort(uptr addr) { \
138 GET_CALLER_PC_BP_SP; \
139 ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \
140} \
141
142ASAN_REPORT_ERROR(load, false, 1)
143ASAN_REPORT_ERROR(load, false, 2)
144ASAN_REPORT_ERROR(load, false, 4)
145ASAN_REPORT_ERROR(load, false, 8)
146ASAN_REPORT_ERROR(load, false, 16)
147ASAN_REPORT_ERROR(store, true, 1)
148ASAN_REPORT_ERROR(store, true, 2)
149ASAN_REPORT_ERROR(store, true, 4)
150ASAN_REPORT_ERROR(store, true, 8)
151ASAN_REPORT_ERROR(store, true, 16)
152
153#define ASAN_REPORT_ERROR_N(type, is_write) \
154extern "C" NOINLINE INTERFACE_ATTRIBUTE \
155void __asan_report_ ## type ## _n(uptr addr, uptr size) { \
156 GET_CALLER_PC_BP_SP; \
157 ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \
158} \
159extern "C" NOINLINE INTERFACE_ATTRIBUTE \
160void __asan_report_exp_ ## type ## _n(uptr addr, uptr size, u32 exp) { \
161 GET_CALLER_PC_BP_SP; \
162 ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \
163} \
164extern "C" NOINLINE INTERFACE_ATTRIBUTE \
165void __asan_report_ ## type ## _n_noabort(uptr addr, uptr size) { \
166 GET_CALLER_PC_BP_SP; \
167 ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \
168} \
169
170ASAN_REPORT_ERROR_N(load, false)
171ASAN_REPORT_ERROR_N(store, true)
172
173extern "C" NOINLINE INTERFACE_ATTRIBUTE void
174__asan_report_assume_dereferenceable(uptr addr, uptr size) {
175 if (__asan_region_is_poisoned(beg: addr, size)) {
176 GET_CALLER_PC_BP_SP;
177 ReportAssumeDereferenceableError(pc, bp, sp, addr, dereferenceable_size: size, fatal: true);
178 }
179}
180
181extern "C" NOINLINE INTERFACE_ATTRIBUTE void
182__asan_report_assume_dereferenceable_noabort(uptr addr, uptr size) {
183 if (__asan_region_is_poisoned(beg: addr, size)) {
184 GET_CALLER_PC_BP_SP;
185 ReportAssumeDereferenceableError(pc, bp, sp, addr, dereferenceable_size: size, fatal: false);
186 }
187}
188
189#define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg, fatal) \
190 uptr sp = MEM_TO_SHADOW(addr); \
191 uptr s = size <= ASAN_SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp) \
192 : *reinterpret_cast<u16 *>(sp); \
193 if (UNLIKELY(s)) { \
194 if (UNLIKELY(size >= ASAN_SHADOW_GRANULARITY || \
195 ((s8)((addr & (ASAN_SHADOW_GRANULARITY - 1)) + size - 1)) >= \
196 (s8)s)) { \
197 ReportGenericErrorWrapper(addr, is_write, size, exp_arg, fatal); \
198 } \
199 }
200
201#define ASAN_MEMORY_ACCESS_CALLBACK(type, is_write, size) \
202 extern "C" NOINLINE INTERFACE_ATTRIBUTE \
203 void __asan_##type##size(uptr addr) { \
204 ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, true) \
205 } \
206 extern "C" NOINLINE INTERFACE_ATTRIBUTE \
207 void __asan_exp_##type##size(uptr addr, u32 exp) { \
208 ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp, true) \
209 } \
210 extern "C" NOINLINE INTERFACE_ATTRIBUTE \
211 void __asan_##type##size ## _noabort(uptr addr) { \
212 ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, false) \
213 } \
214
215ASAN_MEMORY_ACCESS_CALLBACK(load, false, 1)
216ASAN_MEMORY_ACCESS_CALLBACK(load, false, 2)
217ASAN_MEMORY_ACCESS_CALLBACK(load, false, 4)
218ASAN_MEMORY_ACCESS_CALLBACK(load, false, 8)
219ASAN_MEMORY_ACCESS_CALLBACK(load, false, 16)
220ASAN_MEMORY_ACCESS_CALLBACK(store, true, 1)
221ASAN_MEMORY_ACCESS_CALLBACK(store, true, 2)
222ASAN_MEMORY_ACCESS_CALLBACK(store, true, 4)
223ASAN_MEMORY_ACCESS_CALLBACK(store, true, 8)
224ASAN_MEMORY_ACCESS_CALLBACK(store, true, 16)
225
226extern "C"
227NOINLINE INTERFACE_ATTRIBUTE
228void __asan_loadN(uptr addr, uptr size) {
229 if ((addr = __asan_region_is_poisoned(beg: addr, size))) {
230 GET_CALLER_PC_BP_SP;
231 ReportGenericError(pc, bp, sp, addr, is_write: false, access_size: size, exp: 0, fatal: true);
232 }
233}
234
235extern "C"
236NOINLINE INTERFACE_ATTRIBUTE
237void __asan_exp_loadN(uptr addr, uptr size, u32 exp) {
238 if ((addr = __asan_region_is_poisoned(beg: addr, size))) {
239 GET_CALLER_PC_BP_SP;
240 ReportGenericError(pc, bp, sp, addr, is_write: false, access_size: size, exp, fatal: true);
241 }
242}
243
244extern "C"
245NOINLINE INTERFACE_ATTRIBUTE
246void __asan_loadN_noabort(uptr addr, uptr size) {
247 if ((addr = __asan_region_is_poisoned(beg: addr, size))) {
248 GET_CALLER_PC_BP_SP;
249 ReportGenericError(pc, bp, sp, addr, is_write: false, access_size: size, exp: 0, fatal: false);
250 }
251}
252
253extern "C"
254NOINLINE INTERFACE_ATTRIBUTE
255void __asan_storeN(uptr addr, uptr size) {
256 if ((addr = __asan_region_is_poisoned(beg: addr, size))) {
257 GET_CALLER_PC_BP_SP;
258 ReportGenericError(pc, bp, sp, addr, is_write: true, access_size: size, exp: 0, fatal: true);
259 }
260}
261
262extern "C"
263NOINLINE INTERFACE_ATTRIBUTE
264void __asan_exp_storeN(uptr addr, uptr size, u32 exp) {
265 if ((addr = __asan_region_is_poisoned(beg: addr, size))) {
266 GET_CALLER_PC_BP_SP;
267 ReportGenericError(pc, bp, sp, addr, is_write: true, access_size: size, exp, fatal: true);
268 }
269}
270
271extern "C"
272NOINLINE INTERFACE_ATTRIBUTE
273void __asan_storeN_noabort(uptr addr, uptr size) {
274 if ((addr = __asan_region_is_poisoned(beg: addr, size))) {
275 GET_CALLER_PC_BP_SP;
276 ReportGenericError(pc, bp, sp, addr, is_write: true, access_size: size, exp: 0, fatal: false);
277 }
278}
279
280// Force the linker to keep the symbols for various ASan interface functions.
281// We want to keep those in the executable in order to let the instrumented
282// dynamic libraries access the symbol even if it is not used by the executable
283// itself. This should help if the build system is removing dead code at link
284// time.
285static NOINLINE void force_interface_symbols() {
286 volatile int fake_condition = 0; // prevent dead condition elimination.
287 // __asan_report_* functions are noreturn, so we need a switch to prevent
288 // the compiler from removing any of them.
289 // clang-format off
290 switch (fake_condition) {
291 case 1: __asan_report_load1(addr: 0); break;
292 case 2: __asan_report_load2(addr: 0); break;
293 case 3: __asan_report_load4(addr: 0); break;
294 case 4: __asan_report_load8(addr: 0); break;
295 case 5: __asan_report_load16(addr: 0); break;
296 case 6: __asan_report_load_n(addr: 0, size: 0); break;
297 case 7: __asan_report_store1(addr: 0); break;
298 case 8: __asan_report_store2(addr: 0); break;
299 case 9: __asan_report_store4(addr: 0); break;
300 case 10: __asan_report_store8(addr: 0); break;
301 case 11: __asan_report_store16(addr: 0); break;
302 case 12: __asan_report_store_n(addr: 0, size: 0); break;
303 case 13: __asan_report_exp_load1(addr: 0, exp: 0); break;
304 case 14: __asan_report_exp_load2(addr: 0, exp: 0); break;
305 case 15: __asan_report_exp_load4(addr: 0, exp: 0); break;
306 case 16: __asan_report_exp_load8(addr: 0, exp: 0); break;
307 case 17: __asan_report_exp_load16(addr: 0, exp: 0); break;
308 case 18: __asan_report_exp_load_n(addr: 0, size: 0, exp: 0); break;
309 case 19: __asan_report_exp_store1(addr: 0, exp: 0); break;
310 case 20: __asan_report_exp_store2(addr: 0, exp: 0); break;
311 case 21: __asan_report_exp_store4(addr: 0, exp: 0); break;
312 case 22: __asan_report_exp_store8(addr: 0, exp: 0); break;
313 case 23: __asan_report_exp_store16(addr: 0, exp: 0); break;
314 case 24: __asan_report_exp_store_n(addr: 0, size: 0, exp: 0); break;
315 case 25: __asan_register_globals(globals: nullptr, n: 0); break;
316 case 26: __asan_unregister_globals(globals: nullptr, n: 0); break;
317 case 27: __asan_set_death_callback(callback: nullptr); break;
318 case 28: __asan_set_error_report_callback(callback: nullptr); break;
319 case 29: __asan_handle_no_return(); break;
320 case 30: __asan_address_is_poisoned(addr: nullptr); break;
321 case 31: __asan_poison_memory_region(addr: nullptr, size: 0); break;
322 case 32: __asan_unpoison_memory_region(addr: nullptr, size: 0); break;
323 case 34: __asan_before_dynamic_init(module_name: nullptr); break;
324 case 35: __asan_after_dynamic_init(); break;
325 case 36: __asan_poison_stack_memory(addr: 0, size: 0); break;
326 case 37: __asan_unpoison_stack_memory(addr: 0, size: 0); break;
327 case 38: __asan_region_is_poisoned(beg: 0, size: 0); break;
328 case 39: __asan_describe_address(addr: 0); break;
329 case 40: __asan_set_shadow_00(addr: 0, size: 0); break;
330 case 41: __asan_set_shadow_01(addr: 0, size: 0); break;
331 case 42: __asan_set_shadow_02(addr: 0, size: 0); break;
332 case 43: __asan_set_shadow_03(addr: 0, size: 0); break;
333 case 44: __asan_set_shadow_04(addr: 0, size: 0); break;
334 case 45: __asan_set_shadow_05(addr: 0, size: 0); break;
335 case 46: __asan_set_shadow_06(addr: 0, size: 0); break;
336 case 47: __asan_set_shadow_07(addr: 0, size: 0); break;
337 case 48: __asan_set_shadow_f1(addr: 0, size: 0); break;
338 case 49: __asan_set_shadow_f2(addr: 0, size: 0); break;
339 case 50: __asan_set_shadow_f3(addr: 0, size: 0); break;
340 case 51: __asan_set_shadow_f5(addr: 0, size: 0); break;
341 case 52: __asan_set_shadow_f8(addr: 0, size: 0); break;
342 }
343 // clang-format on
344}
345
346static void asan_atexit() {
347 Printf(format: "AddressSanitizer exit stats:\n");
348 __asan_print_accumulated_stats();
349 // Print AsanMappingProfile.
350 for (uptr i = 0; i < kAsanMappingProfileSize; i++) {
351 if (AsanMappingProfile[i] == 0) continue;
352 Printf(format: "asan_mapping.h:%zd -- %zd\n", i, AsanMappingProfile[i]);
353 }
354}
355
356static void InitializeHighMemEnd() {
357#if !ASAN_FIXED_MAPPING
358 kHighMemEnd = GetMaxUserVirtualAddress();
359 // Increase kHighMemEnd to make sure it's properly
360 // aligned together with kHighMemBeg:
361 kHighMemEnd |= (GetMmapGranularity() << ASAN_SHADOW_SCALE) - 1;
362#endif // !ASAN_FIXED_MAPPING
363 CHECK_EQ((kHighMemBeg % GetMmapGranularity()), 0);
364}
365
366void PrintAddressSpaceLayout() {
367 if (kHighMemBeg) {
368 Printf(format: "|| `[%p, %p]` || HighMem ||\n",
369 (void*)kHighMemBeg, (void*)kHighMemEnd);
370 Printf(format: "|| `[%p, %p]` || HighShadow ||\n",
371 (void*)kHighShadowBeg, (void*)kHighShadowEnd);
372 }
373 if (kMidMemBeg) {
374 Printf(format: "|| `[%p, %p]` || ShadowGap3 ||\n",
375 (void*)kShadowGap3Beg, (void*)kShadowGap3End);
376 Printf(format: "|| `[%p, %p]` || MidMem ||\n",
377 (void*)kMidMemBeg, (void*)kMidMemEnd);
378 Printf(format: "|| `[%p, %p]` || ShadowGap2 ||\n",
379 (void*)kShadowGap2Beg, (void*)kShadowGap2End);
380 Printf(format: "|| `[%p, %p]` || MidShadow ||\n",
381 (void*)kMidShadowBeg, (void*)kMidShadowEnd);
382 }
383 Printf(format: "|| `[%p, %p]` || ShadowGap ||\n",
384 (void*)kShadowGapBeg, (void*)kShadowGapEnd);
385 if (kLowShadowBeg) {
386 Printf(format: "|| `[%p, %p]` || LowShadow ||\n",
387 (void*)kLowShadowBeg, (void*)kLowShadowEnd);
388 Printf(format: "|| `[%p, %p]` || LowMem ||\n",
389 (void*)kLowMemBeg, (void*)kLowMemEnd);
390 }
391 Printf(format: "MemToShadow(shadow): %p %p",
392 (void*)MEM_TO_SHADOW(kLowShadowBeg),
393 (void*)MEM_TO_SHADOW(kLowShadowEnd));
394 if (kHighMemBeg) {
395 Printf(format: " %p %p",
396 (void*)MEM_TO_SHADOW(kHighShadowBeg),
397 (void*)MEM_TO_SHADOW(kHighShadowEnd));
398 }
399 if (kMidMemBeg) {
400 Printf(format: " %p %p",
401 (void*)MEM_TO_SHADOW(kMidShadowBeg),
402 (void*)MEM_TO_SHADOW(kMidShadowEnd));
403 }
404 Printf(format: "\n");
405 Printf(format: "redzone=%zu\n", (uptr)flags()->redzone);
406 Printf(format: "max_redzone=%zu\n", (uptr)flags()->max_redzone);
407 Printf(format: "quarantine_size_mb=%zuM\n", (uptr)flags()->quarantine_size_mb);
408 Printf(format: "thread_local_quarantine_size_kb=%zuK\n",
409 (uptr)flags()->thread_local_quarantine_size_kb);
410 Printf(format: "malloc_context_size=%zu\n",
411 (uptr)common_flags()->malloc_context_size);
412
413 Printf(format: "SHADOW_SCALE: %d\n", (int)ASAN_SHADOW_SCALE);
414 Printf(format: "SHADOW_GRANULARITY: %d\n", (int)ASAN_SHADOW_GRANULARITY);
415 Printf(format: "SHADOW_OFFSET: %p\n", (void *)ASAN_SHADOW_OFFSET);
416 Printf(format: "kGaplessShadow: %d\n", kGaplessShadow);
417 CHECK(ASAN_SHADOW_SCALE >= 3 && ASAN_SHADOW_SCALE <= 7);
418 if (kMidMemBeg)
419 CHECK(kMidShadowBeg > kLowShadowEnd &&
420// On AIX 64-bit, we have a highly customized memory layout.
421#if !SANITIZER_AIX || SANITIZER_WORDSIZE != 64
422 kMidMemBeg > kMidShadowEnd &&
423#endif
424 kHighShadowBeg > kMidMemEnd);
425}
426
427// Apply most options specified either through the ASAN_OPTIONS
428// environment variable, or through the `__asan_default_options` user function.
429//
430// This function may be called multiple times, once per weak reference callback
431// on Windows, so it needs to be idempotent.
432//
433// Context:
434// For maximum compatibility on Windows, it is necessary for ASan options to be
435// configured/registered/applied inside this method (instead of in
436// ASanInitInternal, for example). That's because, on Windows, the user-provided
437// definition for `__asan_default_opts` may not be bound when `ASanInitInternal`
438// is invoked (it is bound later).
439//
440// To work around the late binding on windows, `ApplyOptions` will be called,
441// again, after binding to the user-provided `__asan_default_opts` function.
442// Therefore, any flags not configured here are not guaranteed to be
443// configurable through `__asan_default_opts` on Windows.
444//
445//
446// For more details on this issue, see:
447// https://github.com/llvm/llvm-project/issues/117925
448void ApplyFlags() {
449 SetCanPoisonMemory(flags()->poison_heap);
450 SetMallocContextSize(common_flags()->malloc_context_size);
451
452 __asan_option_detect_stack_use_after_return =
453 flags()->detect_stack_use_after_return;
454
455 AllocatorOptions allocator_options;
456 allocator_options.SetFrom(f: flags(), cf: common_flags());
457 ApplyAllocatorOptions(options: allocator_options);
458}
459
460static bool AsanInitInternal() {
461 if (LIKELY(AsanInited()))
462 return true;
463 SanitizerToolName = "AddressSanitizer";
464
465 CacheBinaryName();
466
467 // Initialize flags. On Windows it also also register weak function callbacks.
468 // This must be done early, because most of the initialization steps look at
469 // flags().
470 InitializeFlags();
471
472 WaitForDebugger(seconds: flags()->sleep_before_init, label: "before init");
473
474 // Stop performing init at this point if we are being loaded via
475 // dlopen() and the platform supports it.
476 if (SANITIZER_SUPPORTS_INIT_FOR_DLOPEN && UNLIKELY(HandleDlopenInit())) {
477 VReport(1, "AddressSanitizer init is being performed for dlopen().\n");
478 return false;
479 }
480
481 // Make sure we are not statically linked.
482 __interception::DoesNotSupportStaticLinking();
483 AsanCheckIncompatibleRT();
484 AsanCheckDynamicRTPrereqs();
485 AvoidCVE_2016_2143();
486
487 InitializePlatformExceptionHandlers();
488
489 InitializeHighMemEnd();
490
491 // Install tool-specific callbacks in sanitizer_common.
492 AddDieCallback(callback: AsanDie);
493 SetCheckUnwindCallback(CheckUnwind);
494 SetPrintfAndReportCallback(AppendToErrorMessageBuffer);
495
496 __sanitizer_set_report_path(path: common_flags()->log_path);
497 __sanitizer::InitializePlatformEarly();
498
499 // Setup internal allocator callback.
500 SetLowLevelAllocateMinAlignment(ASAN_SHADOW_GRANULARITY);
501 SetLowLevelAllocateCallback(OnLowLevelAllocate);
502
503 InitializeAsanInterceptors();
504 CheckASLR();
505
506 // Enable system log ("adb logcat") on Android.
507 // Doing this before interceptors are initialized crashes in:
508 // AsanInitInternal -> android_log_write -> __interceptor_strcmp
509 AndroidLogInit();
510
511 ReplaceSystemMalloc();
512
513 DisableCoreDumperIfNecessary();
514
515#if SANITIZER_POSIX
516 if (StackSizeIsUnlimited()) {
517 VPrintf(1,
518 "WARNING: Unlimited stack size detected. This may affect "
519 "compatibility with the shadow mappings.\n");
520 // MSan and TSan re-exec with a fixed size stack. We don't do that because
521 // it may break the program. InitializeShadowMemory() will, if needed,
522 // re-exec without ASLR, which solves most shadow mapping compatibility
523 // issues.
524 }
525#endif // SANITIZER_POSIX
526
527 InitializeShadowMemory();
528
529 AsanTSDInit(destructor: PlatformTSDDtor);
530 InstallDeadlySignalHandlers(handler: AsanOnDeadlySignal);
531
532 AllocatorOptions allocator_options;
533 allocator_options.SetFrom(f: flags(), cf: common_flags());
534 InitializeAllocator(options: allocator_options);
535
536 // Apply ASan flags.
537 // NOTE: In order for options specified through `__asan_default_options` to be
538 // honored on Windows, it is necessary for those options to be configured
539 // inside the `ApplyOptions` method. See the function-level comment for
540 // `ApplyFlags` for more details.
541 ApplyFlags();
542
543 if (SANITIZER_START_BACKGROUND_THREAD_IN_ASAN_INTERNAL)
544 MaybeStartBackgroudThread();
545
546 // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited
547 // should be set to 1 prior to initializing the threads.
548 replace_intrin_cached = flags()->replace_intrin;
549 SetAsanInited();
550
551 if (flags()->atexit)
552 Atexit(function: asan_atexit);
553
554 InitializeCoverage(enabled: common_flags()->coverage, coverage_dir: common_flags()->coverage_dir);
555
556 // Now that ASan runtime is (mostly) initialized, deactivate it if
557 // necessary, so that it can be re-activated when requested.
558 if (flags()->start_deactivated)
559 AsanDeactivate();
560
561 // Create main thread.
562 AsanThread *main_thread = CreateMainThread();
563 CHECK_EQ(0, main_thread->tid());
564 force_interface_symbols(); // no-op.
565
566 if (CAN_SANITIZE_LEAKS) {
567 __lsan::InitCommonLsan();
568 InstallAtExitCheckLeaks();
569 }
570
571 InstallAtForkHandler();
572
573#if CAN_SANITIZE_UB
574 __ubsan::InitAsPlugin();
575#endif
576
577 InitializeSuppressions();
578
579 if (CAN_SANITIZE_LEAKS) {
580 // LateInitialize() calls dlsym, which can allocate an error string buffer
581 // in the TLS. Let's ignore the allocation to avoid reporting a leak.
582 __lsan::ScopedInterceptorDisabler disabler;
583 Symbolizer::LateInitialize();
584 } else {
585 Symbolizer::LateInitialize();
586 }
587
588 VReport(1, "AddressSanitizer Init done\n");
589
590 WaitForDebugger(seconds: flags()->sleep_after_init, label: "after init");
591
592 return true;
593}
594
595// Initialize as requested from some part of ASan runtime library (interceptors,
596// allocator, etc).
597void AsanInitFromRtl() {
598 if (LIKELY(AsanInited()))
599 return;
600 SpinMutexLock lock(&asan_inited_mutex);
601 AsanInitInternal();
602}
603
604bool TryAsanInitFromRtl() {
605 if (LIKELY(AsanInited()))
606 return true;
607 if (!asan_inited_mutex.TryLock())
608 return false;
609 bool result = AsanInitInternal();
610 asan_inited_mutex.Unlock();
611 return result;
612}
613
614#if ASAN_DYNAMIC
615// Initialize runtime in case it's LD_PRELOAD-ed into unsanitized executable
616// (and thus normal initializers from .preinit_array or modules haven't run).
617
618class AsanInitializer {
619 public:
620 AsanInitializer() {
621 AsanInitFromRtl();
622 }
623};
624
625static AsanInitializer asan_initializer;
626#endif // ASAN_DYNAMIC
627
628void UnpoisonStack(uptr bottom, uptr top, const char *type) {
629 static const uptr kMaxExpectedCleanupSize = 64 << 20; // 64M
630 if (top - bottom > kMaxExpectedCleanupSize) {
631 static bool reported_warning = false;
632 if (reported_warning)
633 return;
634 reported_warning = true;
635 Report(
636 format: "WARNING: ASan is ignoring requested __asan_handle_no_return: "
637 "stack type: %s top: %p; bottom %p; size: %p (%zd)\n"
638 "False positive error reports may follow\n"
639 "For details see "
640 "https://github.com/google/sanitizers/issues/189\n",
641 type, (void *)top, (void *)bottom, (void *)(top - bottom),
642 top - bottom);
643 return;
644 }
645 PoisonShadow(addr: bottom, size: RoundUpTo(size: top - bottom, ASAN_SHADOW_GRANULARITY), value: 0);
646}
647
648static void UnpoisonDefaultStack() {
649 uptr bottom, top;
650
651 if (AsanThread *curr_thread = GetCurrentThread()) {
652 int local_stack;
653 const uptr page_size = GetPageSizeCached();
654 top = curr_thread->stack_top();
655 bottom = (uptr)&local_stack & ~(page_size - 1);
656 if (AddrIsInMem(a: bottom - page_size))
657 bottom -= page_size;
658 } else {
659 CHECK(!SANITIZER_FUCHSIA);
660 // If we haven't seen this thread, try asking the OS for stack bounds.
661 uptr tls_begin, tls_end;
662 GetThreadStackAndTls(/*main=*/false, stk_begin: &bottom, stk_end: &top, tls_begin: &tls_begin, tls_end: &tls_end);
663 }
664
665 UnpoisonStack(bottom, top, type: "default");
666}
667
668static void UnpoisonFakeStack() {
669 AsanThread *curr_thread = GetCurrentThread();
670 if (!curr_thread)
671 return;
672 FakeStack *stack = curr_thread->get_fake_stack();
673 if (!stack)
674 return;
675 stack->HandleNoReturn();
676}
677
678} // namespace __asan
679
680// ---------------------- Interface ---------------- {{{1
681using namespace __asan;
682
683void NOINLINE __asan_handle_no_return() {
684 if (UNLIKELY(!AsanInited()))
685 return;
686
687 if (!PlatformUnpoisonStacks())
688 UnpoisonDefaultStack();
689
690 UnpoisonFakeStack();
691}
692
693extern "C" void *__asan_extra_spill_area() {
694 AsanThread *t = GetCurrentThread();
695 CHECK(t);
696 return t->extra_spill_area();
697}
698
699void __asan_handle_vfork(void *sp) {
700 AsanThread *t = GetCurrentThread();
701 CHECK(t);
702 uptr bottom = t->stack_bottom();
703 PoisonShadow(addr: bottom, size: (uptr)sp - bottom, value: 0);
704}
705
706void NOINLINE __asan_set_death_callback(void (*callback)(void)) {
707 SetUserDieCallback(callback);
708}
709
710// Initialize as requested from instrumented application code.
711// We use this call as a trigger to wake up ASan from deactivated state.
712void __asan_init() {
713 AsanActivate();
714 AsanInitFromRtl();
715}
716
717void __asan_version_mismatch_check() {
718 // Do nothing.
719}
720