]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/asan/asan_rtl.cc
Upgrade Unbound to 1.5.3.
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / asan / asan_rtl.cc
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_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"
31
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.
34
35 namespace __asan {
36
37 uptr AsanMappingProfile[kAsanMappingProfileSize];
38
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.
43     while (1) { }
44   }
45   if (flags()->sleep_before_dying) {
46     Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying);
47     SleepForSeconds(flags()->sleep_before_dying);
48   }
49   if (flags()->unmap_shadow_on_exit) {
50     if (kMidMemBeg) {
51       UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
52       UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd);
53     } else {
54       UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
55     }
56   }
57   if (common_flags()->coverage)
58     __sanitizer_cov_dump();
59   if (flags()->abort_on_error)
60     Abort();
61   internal__exit(flags()->exitcode);
62 }
63
64 static void AsanCheckFailed(const char *file, int line, const char *cond,
65                             u64 v1, u64 v2) {
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();
70   Die();
71 }
72
73 // -------------------------- Globals --------------------- {{{1
74 int asan_inited;
75 bool asan_init_is_running;
76
77 #if !ASAN_FIXED_MAPPING
78 uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;
79 #endif
80
81 // -------------------------- Misc ---------------- {{{1
82 void ShowStatsAndAbort() {
83   __asan_print_accumulated_stats();
84   Die();
85 }
86
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);
99     Abort();
100   }
101   if (common_flags()->no_huge_pages_for_shadow)
102     NoHugePagesInRegion(beg, size);
103   if (common_flags()->use_madv_dontdump)
104     DontDumpShadowMemory(beg, size);
105 }
106
107 // --------------- LowLevelAllocateCallbac ---------- {{{1
108 static void OnLowLevelAllocate(uptr ptr, uptr size) {
109   PoisonShadow(ptr, size, kAsanInternalHeapMagic);
110 }
111
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);            \
120 }
121
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)
132
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);       \
139 }
140
141 ASAN_REPORT_ERROR_N(load, false)
142 ASAN_REPORT_ERROR_N(store, true)
143
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);        \
150     if (UNLIKELY(s)) {                                                         \
151       if (UNLIKELY(size >= SHADOW_GRANULARITY ||                               \
152                    ((s8)((addr & (SHADOW_GRANULARITY - 1)) + size - 1)) >=     \
153                        (s8)s)) {                                               \
154         if (__asan_test_only_reported_buggy_pointer) {                         \
155           *__asan_test_only_reported_buggy_pointer = addr;                     \
156         } else {                                                               \
157           GET_CALLER_PC_BP_SP;                                                 \
158           __asan_report_error(pc, bp, sp, addr, is_write, size);               \
159         }                                                                      \
160       }                                                                        \
161     }                                                                          \
162   }
163
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)
174
175 extern "C"
176 NOINLINE INTERFACE_ATTRIBUTE void __asan_loadN(uptr addr, uptr size) {
177   if (__asan_region_is_poisoned(addr, size)) {
178     GET_CALLER_PC_BP_SP;
179     __asan_report_error(pc, bp, sp, addr, false, size);
180   }
181 }
182
183 extern "C"
184 NOINLINE INTERFACE_ATTRIBUTE void __asan_storeN(uptr addr, uptr size) {
185   if (__asan_region_is_poisoned(addr, size)) {
186     GET_CALLER_PC_BP_SP;
187     __asan_report_error(pc, bp, sp, addr, true, size);
188   }
189 }
190
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
195 // time.
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;
226   }
227 }
228
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]);
236   }
237 }
238
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);
247 }
248
249 static void ProtectGap(uptr a, uptr size) {
250   void *res = Mprotect(a, size);
251   if (a == (uptr)res)
252     return;
253   Report("ERROR: Failed to protect the shadow gap. "
254          "ASan cannot proceed correctly. ABORTING.\n");
255   DumpProcessMap();
256   Die();
257 }
258
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);
264   if (kMidMemBeg) {
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);
273   }
274   Printf("|| `[%p, %p]` || ShadowGap  ||\n",
275          (void*)kShadowGapBeg, (void*)kShadowGapEnd);
276   if (kLowShadowBeg) {
277     Printf("|| `[%p, %p]` || LowShadow  ||\n",
278            (void*)kLowShadowBeg, (void*)kLowShadowEnd);
279     Printf("|| `[%p, %p]` || LowMem     ||\n",
280            (void*)kLowMemBeg, (void*)kLowMemEnd);
281   }
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));
287   if (kMidMemBeg) {
288     Printf(" %p %p",
289            (void*)MEM_TO_SHADOW(kMidShadowBeg),
290            (void*)MEM_TO_SHADOW(kMidShadowEnd));
291   }
292   Printf("\n");
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);
298
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);
303   if (kMidMemBeg)
304     CHECK(kMidShadowBeg > kLowShadowEnd &&
305           kMidMemBeg > kMidShadowEnd &&
306           kHighShadowBeg > kMidMemEnd);
307 }
308
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;
314
315   // Initialize flags. This must be done early, because most of the
316   // initialization steps look at flags().
317   InitializeFlags();
318
319   SetCanPoisonMemory(flags()->poison_heap);
320   SetMallocContextSize(common_flags()->malloc_context_size);
321
322   InitializeHighMemEnd();
323
324   // Make sure we are not statically linked.
325   AsanDoesNotSupportStaticLinkage();
326
327   // Install tool-specific callbacks in sanitizer_common.
328   SetDieCallback(AsanDie);
329   SetCheckFailedCallback(AsanCheckFailed);
330   SetPrintfAndReportCallback(AppendToErrorMessageBuffer);
331
332   __sanitizer_set_report_path(common_flags()->log_path);
333
334   // Enable UAR detection, if required.
335   __asan_option_detect_stack_use_after_return =
336       flags()->detect_stack_use_after_return;
337
338   // Re-exec ourselves if we need to set additional env or command line args.
339   MaybeReexec();
340
341   // Setup internal allocator callback.
342   SetLowLevelAllocateCallback(OnLowLevelAllocate);
343
344   InitializeAsanInterceptors();
345
346   // Enable system log ("adb logcat") on Android.
347   // Doing this before interceptors are initialized crashes in:
348   // AsanInitInternal -> android_log_write -> __interceptor_strcmp
349   AndroidLogInit();
350
351   ReplaceSystemMalloc();
352
353   uptr shadow_start = kLowShadowBeg;
354   if (kLowShadowBeg)
355     shadow_start -= GetMmapGranularity();
356   bool full_shadow_is_available =
357       MemoryRangeIsAvailable(shadow_start, kHighShadowEnd);
358
359 #if SANITIZER_LINUX && defined(__x86_64__) && defined(_LP64) &&                \
360     !ASAN_FIXED_MAPPING
361   if (!full_shadow_is_available) {
362     kMidMemBeg = kLowMemEnd < 0x3000000000ULL ? 0x3000000000ULL : 0;
363     kMidMemEnd = kLowMemEnd < 0x3000000000ULL ? 0x4fffffffffULL : 0;
364   }
365 #endif
366
367   if (Verbosity()) PrintAddressSpaceLayout();
368
369   DisableCoreDumperIfNecessary();
370
371   if (full_shadow_is_available) {
372     // mmap the low shadow plus at least one page at the left.
373     if (kLowShadowBeg)
374       ReserveShadowMemoryRange(shadow_start, kLowShadowEnd);
375     // mmap the high shadow.
376     ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
377     // protect the gap.
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);
390     // protect the gaps.
391     ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
392     ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1);
393     ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1);
394   } else {
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);
399     DumpProcessMap();
400     Die();
401   }
402
403   AsanTSDInit(PlatformTSDDtor);
404   InstallDeadlySignalHandlers(AsanOnSIGSEGV);
405
406   AllocatorOptions allocator_options;
407   allocator_options.SetFrom(flags(), common_flags());
408   InitializeAllocator(allocator_options);
409
410   MaybeStartBackgroudThread();
411   SetSoftRssLimitExceededCallback(AsanSoftRssLimitExceededCallback);
412
413   // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited
414   // should be set to 1 prior to initializing the threads.
415   asan_inited = 1;
416   asan_init_is_running = false;
417
418   if (flags()->atexit)
419     Atexit(asan_atexit);
420
421   InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
422
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)
426     AsanDeactivate();
427
428   // interceptors
429   InitTlsSize();
430
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();
441
442 #if CAN_SANITIZE_LEAKS
443   __lsan::InitCommonLsan();
444   if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) {
445     Atexit(__lsan::DoLeakCheck);
446   }
447 #endif  // CAN_SANITIZE_LEAKS
448
449   InitializeSuppressions();
450
451   VReport(1, "AddressSanitizer Init done\n");
452 }
453
454 // Initialize as requested from some part of ASan runtime library (interceptors,
455 // allocator, etc).
456 void AsanInitFromRtl() {
457   AsanInitInternal();
458 }
459
460 #if ASAN_DYNAMIC
461 // Initialize runtime in case it's LD_PRELOAD-ed into unsanitized executable
462 // (and thus normal initializer from .preinit_array haven't run).
463
464 class AsanInitializer {
465 public:  // NOLINT
466   AsanInitializer() {
467     AsanCheckIncompatibleRT();
468     AsanCheckDynamicRTPrereqs();
469     AsanInitFromRtl();
470   }
471 };
472
473 static AsanInitializer asan_initializer;
474 #endif  // ASAN_DYNAMIC
475
476 }  // namespace __asan
477
478 // ---------------------- Interface ---------------- {{{1
479 using namespace __asan;  // NOLINT
480
481 int NOINLINE __asan_set_error_exit_code(int exit_code) {
482   int old = flags()->exitcode;
483   flags()->exitcode = exit_code;
484   return old;
485 }
486
487 void NOINLINE __asan_handle_no_return() {
488   int local_stack;
489   AsanThread *curr_thread = GetCurrentThread();
490   CHECK(curr_thread);
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)
498       return;
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"
503            "For details see "
504            "http://code.google.com/p/address-sanitizer/issues/detail?id=189\n",
505            top, bottom, top - bottom, top - bottom);
506     return;
507   }
508   PoisonShadow(bottom, top - bottom, 0);
509   if (curr_thread->has_fake_stack())
510     curr_thread->fake_stack()->HandleNoReturn();
511 }
512
513 void NOINLINE __asan_set_death_callback(void (*callback)(void)) {
514   SetUserDieCallback(callback);
515 }
516
517 // Initialize as requested from instrumented application code.
518 // We use this call as a trigger to wake up ASan from deactivated state.
519 void __asan_init() {
520   AsanCheckIncompatibleRT();
521   AsanActivate();
522   AsanInitInternal();
523 }