2012-06-04 21:50:10 +08:00
|
|
|
//===-- asan_rtl.cc -------------------------------------------------------===//
|
2011-11-30 09:07:02 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file is a part of AddressSanitizer, an address sanity checker.
|
|
|
|
//
|
|
|
|
// Main file of the ASan run-time library.
|
|
|
|
//===----------------------------------------------------------------------===//
|
2015-10-01 08:22:21 +08:00
|
|
|
|
2014-01-16 20:31:50 +08:00
|
|
|
#include "asan_activation.h"
|
2011-11-30 09:07:02 +08:00
|
|
|
#include "asan_allocator.h"
|
|
|
|
#include "asan_interceptors.h"
|
2013-09-18 18:35:12 +08:00
|
|
|
#include "asan_interface_internal.h"
|
2011-11-30 09:07:02 +08:00
|
|
|
#include "asan_internal.h"
|
|
|
|
#include "asan_mapping.h"
|
2013-03-28 23:42:43 +08:00
|
|
|
#include "asan_poisoning.h"
|
2012-08-09 17:06:52 +08:00
|
|
|
#include "asan_report.h"
|
2011-11-30 09:07:02 +08:00
|
|
|
#include "asan_stack.h"
|
|
|
|
#include "asan_stats.h"
|
2014-12-06 04:26:09 +08:00
|
|
|
#include "asan_suppressions.h"
|
2011-11-30 09:07:02 +08:00
|
|
|
#include "asan_thread.h"
|
2012-06-30 00:58:33 +08:00
|
|
|
#include "sanitizer_common/sanitizer_atomic.h"
|
2012-07-09 22:36:04 +08:00
|
|
|
#include "sanitizer_common/sanitizer_flags.h"
|
2012-06-05 15:25:47 +08:00
|
|
|
#include "sanitizer_common/sanitizer_libc.h"
|
2012-08-23 15:32:06 +08:00
|
|
|
#include "sanitizer_common/sanitizer_symbolizer.h"
|
2013-05-21 22:15:35 +08:00
|
|
|
#include "lsan/lsan_common.h"
|
2015-04-02 06:42:36 +08:00
|
|
|
#include "ubsan/ubsan_init.h"
|
|
|
|
#include "ubsan/ubsan_platform.h"
|
2011-11-30 09:07:02 +08:00
|
|
|
|
2016-10-01 01:47:34 +08:00
|
|
|
uptr __asan_shadow_memory_dynamic_address; // Global interface symbol.
|
2013-09-18 18:35:12 +08:00
|
|
|
int __asan_option_detect_stack_use_after_return; // Global interface symbol.
|
2014-04-16 21:52:28 +08:00
|
|
|
uptr *__asan_test_only_reported_buggy_pointer; // Used only for testing asan.
|
2013-09-18 18:35:12 +08:00
|
|
|
|
2012-09-11 17:44:48 +08:00
|
|
|
namespace __asan {
|
2012-06-06 15:02:44 +08:00
|
|
|
|
[asan] make asan work with 7fff8000 offset and prelink
When prelink is installed in the system, prelink-ed
libraries map between 0x003000000000 and 0x004000000000 thus occupying the shadow Gap,
so we need so split the address space even further, like this:
|| [0x10007fff8000, 0x7fffffffffff] || HighMem ||
|| [0x02008fff7000, 0x10007fff7fff] || HighShadow ||
|| [0x004000000000, 0x02008fff6fff] || ShadowGap3 ||
|| [0x003000000000, 0x003fffffffff] || MidMem ||
|| [0x00087fff8000, 0x002fffffffff] || ShadowGap2 ||
|| [0x00067fff8000, 0x00087fff7fff] || MidShadow ||
|| [0x00008fff7000, 0x00067fff7fff] || ShadowGap ||
|| [0x00007fff8000, 0x00008fff6fff] || LowShadow ||
|| [0x000000000000, 0x00007fff7fff] || LowMem ||
Do it only if necessary.
Also added a bit of profiling code to make sure that the
mapping code is efficient.
Added a lit test to simulate prelink-ed libraries.
Unfortunately, this test does not work with binutils-gold linker.
If gold is the default linker the test silently passes.
Also replaced
__has_feature(address_sanitizer)
with
__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
in two places.
Patch partially by Jakub Jelinek.
llvm-svn: 175263
2013-02-15 20:00:24 +08:00
|
|
|
uptr AsanMappingProfile[kAsanMappingProfileSize];
|
|
|
|
|
2012-09-11 17:44:48 +08:00
|
|
|
static void AsanDie() {
|
2012-06-30 00:58:33 +08:00
|
|
|
static atomic_uint32_t num_calls;
|
|
|
|
if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
|
2012-06-06 15:02:44 +08:00
|
|
|
// Don't die twice - run a busy loop.
|
|
|
|
while (1) { }
|
|
|
|
}
|
2017-01-07 04:57:47 +08:00
|
|
|
if (common_flags()->print_module_map >= 1) PrintModuleMap();
|
2012-07-09 22:36:04 +08:00
|
|
|
if (flags()->sleep_before_dying) {
|
2012-08-06 21:00:21 +08:00
|
|
|
Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying);
|
2012-07-09 22:36:04 +08:00
|
|
|
SleepForSeconds(flags()->sleep_before_dying);
|
2012-06-06 15:02:44 +08:00
|
|
|
}
|
[asan] make asan work with 7fff8000 offset and prelink
When prelink is installed in the system, prelink-ed
libraries map between 0x003000000000 and 0x004000000000 thus occupying the shadow Gap,
so we need so split the address space even further, like this:
|| [0x10007fff8000, 0x7fffffffffff] || HighMem ||
|| [0x02008fff7000, 0x10007fff7fff] || HighShadow ||
|| [0x004000000000, 0x02008fff6fff] || ShadowGap3 ||
|| [0x003000000000, 0x003fffffffff] || MidMem ||
|| [0x00087fff8000, 0x002fffffffff] || ShadowGap2 ||
|| [0x00067fff8000, 0x00087fff7fff] || MidShadow ||
|| [0x00008fff7000, 0x00067fff7fff] || ShadowGap ||
|| [0x00007fff8000, 0x00008fff6fff] || LowShadow ||
|| [0x000000000000, 0x00007fff7fff] || LowMem ||
Do it only if necessary.
Also added a bit of profiling code to make sure that the
mapping code is efficient.
Added a lit test to simulate prelink-ed libraries.
Unfortunately, this test does not work with binutils-gold linker.
If gold is the default linker the test silently passes.
Also replaced
__has_feature(address_sanitizer)
with
__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
in two places.
Patch partially by Jakub Jelinek.
llvm-svn: 175263
2013-02-15 20:00:24 +08:00
|
|
|
if (flags()->unmap_shadow_on_exit) {
|
|
|
|
if (kMidMemBeg) {
|
|
|
|
UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
|
|
|
|
UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd);
|
|
|
|
} else {
|
2018-05-18 12:09:45 +08:00
|
|
|
if (kHighShadowEnd)
|
|
|
|
UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
|
[asan] make asan work with 7fff8000 offset and prelink
When prelink is installed in the system, prelink-ed
libraries map between 0x003000000000 and 0x004000000000 thus occupying the shadow Gap,
so we need so split the address space even further, like this:
|| [0x10007fff8000, 0x7fffffffffff] || HighMem ||
|| [0x02008fff7000, 0x10007fff7fff] || HighShadow ||
|| [0x004000000000, 0x02008fff6fff] || ShadowGap3 ||
|| [0x003000000000, 0x003fffffffff] || MidMem ||
|| [0x00087fff8000, 0x002fffffffff] || ShadowGap2 ||
|| [0x00067fff8000, 0x00087fff7fff] || MidShadow ||
|| [0x00008fff7000, 0x00067fff7fff] || ShadowGap ||
|| [0x00007fff8000, 0x00008fff6fff] || LowShadow ||
|| [0x000000000000, 0x00007fff7fff] || LowMem ||
Do it only if necessary.
Also added a bit of profiling code to make sure that the
mapping code is efficient.
Added a lit test to simulate prelink-ed libraries.
Unfortunately, this test does not work with binutils-gold linker.
If gold is the default linker the test silently passes.
Also replaced
__has_feature(address_sanitizer)
with
__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
in two places.
Patch partially by Jakub Jelinek.
llvm-svn: 175263
2013-02-15 20:00:24 +08:00
|
|
|
}
|
|
|
|
}
|
2012-06-06 15:02:44 +08:00
|
|
|
}
|
|
|
|
|
2012-09-11 17:44:48 +08:00
|
|
|
static void AsanCheckFailed(const char *file, int line, const char *cond,
|
|
|
|
u64 v1, u64 v2) {
|
2013-12-05 20:04:51 +08:00
|
|
|
Report("AddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", file,
|
|
|
|
line, cond, (uptr)v1, (uptr)v2);
|
2018-06-19 08:36:47 +08:00
|
|
|
|
|
|
|
// Print a stack trace the first time we come here. Otherwise, we probably
|
|
|
|
// failed a CHECK during symbolization.
|
|
|
|
static atomic_uint32_t num_calls;
|
|
|
|
if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) == 0) {
|
|
|
|
PRINT_CURRENT_STACK_CHECK();
|
|
|
|
}
|
|
|
|
|
2012-12-13 19:09:26 +08:00
|
|
|
Die();
|
2012-06-06 23:22:20 +08:00
|
|
|
}
|
|
|
|
|
2011-11-30 09:07:02 +08:00
|
|
|
// -------------------------- Globals --------------------- {{{1
|
|
|
|
int asan_inited;
|
|
|
|
bool asan_init_is_running;
|
[asan] make asan work with 7fff8000 offset and prelink
When prelink is installed in the system, prelink-ed
libraries map between 0x003000000000 and 0x004000000000 thus occupying the shadow Gap,
so we need so split the address space even further, like this:
|| [0x10007fff8000, 0x7fffffffffff] || HighMem ||
|| [0x02008fff7000, 0x10007fff7fff] || HighShadow ||
|| [0x004000000000, 0x02008fff6fff] || ShadowGap3 ||
|| [0x003000000000, 0x003fffffffff] || MidMem ||
|| [0x00087fff8000, 0x002fffffffff] || ShadowGap2 ||
|| [0x00067fff8000, 0x00087fff7fff] || MidShadow ||
|| [0x00008fff7000, 0x00067fff7fff] || ShadowGap ||
|| [0x00007fff8000, 0x00008fff6fff] || LowShadow ||
|| [0x000000000000, 0x00007fff7fff] || LowMem ||
Do it only if necessary.
Also added a bit of profiling code to make sure that the
mapping code is efficient.
Added a lit test to simulate prelink-ed libraries.
Unfortunately, this test does not work with binutils-gold linker.
If gold is the default linker the test silently passes.
Also replaced
__has_feature(address_sanitizer)
with
__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
in two places.
Patch partially by Jakub Jelinek.
llvm-svn: 175263
2013-02-15 20:00:24 +08:00
|
|
|
|
|
|
|
#if !ASAN_FIXED_MAPPING
|
|
|
|
uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;
|
|
|
|
#endif
|
2011-11-30 09:07:02 +08:00
|
|
|
|
|
|
|
// -------------------------- Misc ---------------- {{{1
|
|
|
|
void ShowStatsAndAbort() {
|
|
|
|
__asan_print_accumulated_stats();
|
2012-06-06 15:02:44 +08:00
|
|
|
Die();
|
2011-11-30 09:07:02 +08:00
|
|
|
}
|
|
|
|
|
2012-08-27 17:30:58 +08:00
|
|
|
// --------------- LowLevelAllocateCallbac ---------- {{{1
|
|
|
|
static void OnLowLevelAllocate(uptr ptr, uptr size) {
|
|
|
|
PoisonShadow(ptr, size, kAsanInternalHeapMagic);
|
2011-12-03 05:02:20 +08:00
|
|
|
}
|
|
|
|
|
2011-11-30 09:07:02 +08:00
|
|
|
// -------------------------- Run-time entry ------------------- {{{1
|
|
|
|
// exported functions
|
2011-12-28 08:59:39 +08:00
|
|
|
#define ASAN_REPORT_ERROR(type, is_write, size) \
|
2015-03-18 00:59:11 +08:00
|
|
|
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
|
|
|
void __asan_report_ ## type ## size(uptr addr) { \
|
|
|
|
GET_CALLER_PC_BP_SP; \
|
2015-11-11 19:59:38 +08:00
|
|
|
ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \
|
2015-03-18 00:59:11 +08:00
|
|
|
} \
|
|
|
|
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
|
|
|
void __asan_report_exp_ ## type ## size(uptr addr, u32 exp) { \
|
2012-03-15 09:36:00 +08:00
|
|
|
GET_CALLER_PC_BP_SP; \
|
2015-11-11 19:59:38 +08:00
|
|
|
ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \
|
|
|
|
} \
|
|
|
|
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
|
|
|
void __asan_report_ ## type ## size ## _noabort(uptr addr) { \
|
|
|
|
GET_CALLER_PC_BP_SP; \
|
|
|
|
ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \
|
|
|
|
} \
|
2011-11-30 09:07:02 +08:00
|
|
|
|
|
|
|
ASAN_REPORT_ERROR(load, false, 1)
|
|
|
|
ASAN_REPORT_ERROR(load, false, 2)
|
|
|
|
ASAN_REPORT_ERROR(load, false, 4)
|
|
|
|
ASAN_REPORT_ERROR(load, false, 8)
|
|
|
|
ASAN_REPORT_ERROR(load, false, 16)
|
|
|
|
ASAN_REPORT_ERROR(store, true, 1)
|
|
|
|
ASAN_REPORT_ERROR(store, true, 2)
|
|
|
|
ASAN_REPORT_ERROR(store, true, 4)
|
|
|
|
ASAN_REPORT_ERROR(store, true, 8)
|
|
|
|
ASAN_REPORT_ERROR(store, true, 16)
|
|
|
|
|
2015-11-11 19:59:38 +08:00
|
|
|
#define ASAN_REPORT_ERROR_N(type, is_write) \
|
|
|
|
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
|
|
|
void __asan_report_ ## type ## _n(uptr addr, uptr size) { \
|
|
|
|
GET_CALLER_PC_BP_SP; \
|
|
|
|
ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \
|
|
|
|
} \
|
|
|
|
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
2015-03-18 00:59:11 +08:00
|
|
|
void __asan_report_exp_ ## type ## _n(uptr addr, uptr size, u32 exp) { \
|
|
|
|
GET_CALLER_PC_BP_SP; \
|
2015-11-11 19:59:38 +08:00
|
|
|
ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \
|
|
|
|
} \
|
|
|
|
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
|
|
|
void __asan_report_ ## type ## _n_noabort(uptr addr, uptr size) { \
|
|
|
|
GET_CALLER_PC_BP_SP; \
|
|
|
|
ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \
|
|
|
|
} \
|
2013-02-19 19:30:25 +08:00
|
|
|
|
|
|
|
ASAN_REPORT_ERROR_N(load, false)
|
|
|
|
ASAN_REPORT_ERROR_N(store, true)
|
|
|
|
|
2015-11-11 19:59:38 +08:00
|
|
|
#define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg, fatal) \
|
2018-05-18 12:09:45 +08:00
|
|
|
if (SANITIZER_MYRIAD2 && !AddrIsInMem(addr) && !AddrIsInShadow(addr)) \
|
|
|
|
return; \
|
2014-04-16 21:52:28 +08:00
|
|
|
uptr sp = MEM_TO_SHADOW(addr); \
|
|
|
|
uptr s = size <= SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp) \
|
|
|
|
: *reinterpret_cast<u16 *>(sp); \
|
2014-04-21 15:09:01 +08:00
|
|
|
if (UNLIKELY(s)) { \
|
|
|
|
if (UNLIKELY(size >= SHADOW_GRANULARITY || \
|
|
|
|
((s8)((addr & (SHADOW_GRANULARITY - 1)) + size - 1)) >= \
|
|
|
|
(s8)s)) { \
|
2014-04-16 21:52:28 +08:00
|
|
|
if (__asan_test_only_reported_buggy_pointer) { \
|
|
|
|
*__asan_test_only_reported_buggy_pointer = addr; \
|
|
|
|
} else { \
|
|
|
|
GET_CALLER_PC_BP_SP; \
|
2015-11-11 19:59:38 +08:00
|
|
|
ReportGenericError(pc, bp, sp, addr, is_write, size, exp_arg, \
|
|
|
|
fatal); \
|
2014-04-16 21:52:28 +08:00
|
|
|
} \
|
|
|
|
} \
|
2015-03-18 00:59:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#define ASAN_MEMORY_ACCESS_CALLBACK(type, is_write, size) \
|
|
|
|
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
|
|
|
void __asan_##type##size(uptr addr) { \
|
2015-11-11 19:59:38 +08:00
|
|
|
ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, true) \
|
2015-03-18 00:59:11 +08:00
|
|
|
} \
|
|
|
|
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
|
|
|
void __asan_exp_##type##size(uptr addr, u32 exp) { \
|
2015-11-11 19:59:38 +08:00
|
|
|
ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp, true) \
|
|
|
|
} \
|
|
|
|
extern "C" NOINLINE INTERFACE_ATTRIBUTE \
|
|
|
|
void __asan_##type##size ## _noabort(uptr addr) { \
|
|
|
|
ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, false) \
|
|
|
|
} \
|
2014-04-16 21:52:28 +08:00
|
|
|
|
|
|
|
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 1)
|
|
|
|
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 2)
|
|
|
|
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 4)
|
|
|
|
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 8)
|
|
|
|
ASAN_MEMORY_ACCESS_CALLBACK(load, false, 16)
|
|
|
|
ASAN_MEMORY_ACCESS_CALLBACK(store, true, 1)
|
|
|
|
ASAN_MEMORY_ACCESS_CALLBACK(store, true, 2)
|
|
|
|
ASAN_MEMORY_ACCESS_CALLBACK(store, true, 4)
|
|
|
|
ASAN_MEMORY_ACCESS_CALLBACK(store, true, 8)
|
|
|
|
ASAN_MEMORY_ACCESS_CALLBACK(store, true, 16)
|
|
|
|
|
2014-04-21 15:09:01 +08:00
|
|
|
extern "C"
|
2015-03-18 00:59:11 +08:00
|
|
|
NOINLINE INTERFACE_ATTRIBUTE
|
|
|
|
void __asan_loadN(uptr addr, uptr size) {
|
|
|
|
if (__asan_region_is_poisoned(addr, size)) {
|
|
|
|
GET_CALLER_PC_BP_SP;
|
2015-11-11 19:59:38 +08:00
|
|
|
ReportGenericError(pc, bp, sp, addr, false, size, 0, true);
|
2015-03-18 00:59:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
NOINLINE INTERFACE_ATTRIBUTE
|
|
|
|
void __asan_exp_loadN(uptr addr, uptr size, u32 exp) {
|
|
|
|
if (__asan_region_is_poisoned(addr, size)) {
|
|
|
|
GET_CALLER_PC_BP_SP;
|
2015-11-11 19:59:38 +08:00
|
|
|
ReportGenericError(pc, bp, sp, addr, false, size, exp, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
NOINLINE INTERFACE_ATTRIBUTE
|
|
|
|
void __asan_loadN_noabort(uptr addr, uptr size) {
|
|
|
|
if (__asan_region_is_poisoned(addr, size)) {
|
|
|
|
GET_CALLER_PC_BP_SP;
|
|
|
|
ReportGenericError(pc, bp, sp, addr, false, size, 0, false);
|
2015-03-18 00:59:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
NOINLINE INTERFACE_ATTRIBUTE
|
|
|
|
void __asan_storeN(uptr addr, uptr size) {
|
2014-04-21 15:09:01 +08:00
|
|
|
if (__asan_region_is_poisoned(addr, size)) {
|
|
|
|
GET_CALLER_PC_BP_SP;
|
2015-11-11 19:59:38 +08:00
|
|
|
ReportGenericError(pc, bp, sp, addr, true, size, 0, true);
|
2014-04-21 15:09:01 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
2015-03-18 00:59:11 +08:00
|
|
|
NOINLINE INTERFACE_ATTRIBUTE
|
|
|
|
void __asan_exp_storeN(uptr addr, uptr size, u32 exp) {
|
2014-04-21 15:09:01 +08:00
|
|
|
if (__asan_region_is_poisoned(addr, size)) {
|
|
|
|
GET_CALLER_PC_BP_SP;
|
2015-11-11 19:59:38 +08:00
|
|
|
ReportGenericError(pc, bp, sp, addr, true, size, exp, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
NOINLINE INTERFACE_ATTRIBUTE
|
|
|
|
void __asan_storeN_noabort(uptr addr, uptr size) {
|
|
|
|
if (__asan_region_is_poisoned(addr, size)) {
|
|
|
|
GET_CALLER_PC_BP_SP;
|
|
|
|
ReportGenericError(pc, bp, sp, addr, true, size, 0, false);
|
2014-04-21 15:09:01 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-30 09:07:02 +08:00
|
|
|
// Force the linker to keep the symbols for various ASan interface functions.
|
|
|
|
// We want to keep those in the executable in order to let the instrumented
|
|
|
|
// dynamic libraries access the symbol even if it is not used by the executable
|
|
|
|
// itself. This should help if the build system is removing dead code at link
|
|
|
|
// time.
|
2012-02-27 22:06:48 +08:00
|
|
|
static NOINLINE void force_interface_symbols() {
|
2011-11-30 09:07:02 +08:00
|
|
|
volatile int fake_condition = 0; // prevent dead condition elimination.
|
2012-08-09 17:46:12 +08:00
|
|
|
// __asan_report_* functions are noreturn, so we need a switch to prevent
|
|
|
|
// the compiler from removing any of them.
|
2016-08-18 08:56:11 +08:00
|
|
|
// clang-format off
|
2012-08-09 17:46:12 +08:00
|
|
|
switch (fake_condition) {
|
|
|
|
case 1: __asan_report_load1(0); break;
|
|
|
|
case 2: __asan_report_load2(0); break;
|
|
|
|
case 3: __asan_report_load4(0); break;
|
|
|
|
case 4: __asan_report_load8(0); break;
|
|
|
|
case 5: __asan_report_load16(0); break;
|
2015-03-18 00:59:11 +08:00
|
|
|
case 6: __asan_report_load_n(0, 0); break;
|
|
|
|
case 7: __asan_report_store1(0); break;
|
|
|
|
case 8: __asan_report_store2(0); break;
|
|
|
|
case 9: __asan_report_store4(0); break;
|
|
|
|
case 10: __asan_report_store8(0); break;
|
|
|
|
case 11: __asan_report_store16(0); break;
|
|
|
|
case 12: __asan_report_store_n(0, 0); break;
|
|
|
|
case 13: __asan_report_exp_load1(0, 0); break;
|
|
|
|
case 14: __asan_report_exp_load2(0, 0); break;
|
|
|
|
case 15: __asan_report_exp_load4(0, 0); break;
|
|
|
|
case 16: __asan_report_exp_load8(0, 0); break;
|
|
|
|
case 17: __asan_report_exp_load16(0, 0); break;
|
|
|
|
case 18: __asan_report_exp_load_n(0, 0, 0); break;
|
|
|
|
case 19: __asan_report_exp_store1(0, 0); break;
|
|
|
|
case 20: __asan_report_exp_store2(0, 0); break;
|
|
|
|
case 21: __asan_report_exp_store4(0, 0); break;
|
|
|
|
case 22: __asan_report_exp_store8(0, 0); break;
|
|
|
|
case 23: __asan_report_exp_store16(0, 0); break;
|
|
|
|
case 24: __asan_report_exp_store_n(0, 0, 0); break;
|
2015-10-01 08:22:21 +08:00
|
|
|
case 25: __asan_register_globals(nullptr, 0); break;
|
|
|
|
case 26: __asan_unregister_globals(nullptr, 0); break;
|
|
|
|
case 27: __asan_set_death_callback(nullptr); break;
|
|
|
|
case 28: __asan_set_error_report_callback(nullptr); break;
|
2015-03-18 00:59:11 +08:00
|
|
|
case 29: __asan_handle_no_return(); break;
|
2015-10-01 08:22:21 +08:00
|
|
|
case 30: __asan_address_is_poisoned(nullptr); break;
|
|
|
|
case 31: __asan_poison_memory_region(nullptr, 0); break;
|
|
|
|
case 32: __asan_unpoison_memory_region(nullptr, 0); break;
|
|
|
|
case 34: __asan_before_dynamic_init(nullptr); break;
|
2015-03-18 00:59:11 +08:00
|
|
|
case 35: __asan_after_dynamic_init(); break;
|
|
|
|
case 36: __asan_poison_stack_memory(0, 0); break;
|
|
|
|
case 37: __asan_unpoison_stack_memory(0, 0); break;
|
|
|
|
case 38: __asan_region_is_poisoned(0, 0); break;
|
|
|
|
case 39: __asan_describe_address(0); break;
|
2016-08-18 08:56:11 +08:00
|
|
|
case 40: __asan_set_shadow_00(0, 0); break;
|
|
|
|
case 41: __asan_set_shadow_f1(0, 0); break;
|
|
|
|
case 42: __asan_set_shadow_f2(0, 0); break;
|
|
|
|
case 43: __asan_set_shadow_f3(0, 0); break;
|
|
|
|
case 44: __asan_set_shadow_f5(0, 0); break;
|
|
|
|
case 45: __asan_set_shadow_f8(0, 0); break;
|
2011-11-30 09:07:02 +08:00
|
|
|
}
|
2016-08-18 08:56:11 +08:00
|
|
|
// clang-format on
|
2011-11-30 09:07:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void asan_atexit() {
|
2012-08-28 19:34:40 +08:00
|
|
|
Printf("AddressSanitizer exit stats:\n");
|
2011-11-30 09:07:02 +08:00
|
|
|
__asan_print_accumulated_stats();
|
[asan] make asan work with 7fff8000 offset and prelink
When prelink is installed in the system, prelink-ed
libraries map between 0x003000000000 and 0x004000000000 thus occupying the shadow Gap,
so we need so split the address space even further, like this:
|| [0x10007fff8000, 0x7fffffffffff] || HighMem ||
|| [0x02008fff7000, 0x10007fff7fff] || HighShadow ||
|| [0x004000000000, 0x02008fff6fff] || ShadowGap3 ||
|| [0x003000000000, 0x003fffffffff] || MidMem ||
|| [0x00087fff8000, 0x002fffffffff] || ShadowGap2 ||
|| [0x00067fff8000, 0x00087fff7fff] || MidShadow ||
|| [0x00008fff7000, 0x00067fff7fff] || ShadowGap ||
|| [0x00007fff8000, 0x00008fff6fff] || LowShadow ||
|| [0x000000000000, 0x00007fff7fff] || LowMem ||
Do it only if necessary.
Also added a bit of profiling code to make sure that the
mapping code is efficient.
Added a lit test to simulate prelink-ed libraries.
Unfortunately, this test does not work with binutils-gold linker.
If gold is the default linker the test silently passes.
Also replaced
__has_feature(address_sanitizer)
with
__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
in two places.
Patch partially by Jakub Jelinek.
llvm-svn: 175263
2013-02-15 20:00:24 +08:00
|
|
|
// Print AsanMappingProfile.
|
|
|
|
for (uptr i = 0; i < kAsanMappingProfileSize; i++) {
|
|
|
|
if (AsanMappingProfile[i] == 0) continue;
|
|
|
|
Printf("asan_mapping.h:%zd -- %zd\n", i, AsanMappingProfile[i]);
|
|
|
|
}
|
2011-11-30 09:07:02 +08:00
|
|
|
}
|
|
|
|
|
2013-01-23 21:27:43 +08:00
|
|
|
static void InitializeHighMemEnd() {
|
2018-05-18 12:09:45 +08:00
|
|
|
#if !SANITIZER_MYRIAD2
|
[asan] make asan work with 7fff8000 offset and prelink
When prelink is installed in the system, prelink-ed
libraries map between 0x003000000000 and 0x004000000000 thus occupying the shadow Gap,
so we need so split the address space even further, like this:
|| [0x10007fff8000, 0x7fffffffffff] || HighMem ||
|| [0x02008fff7000, 0x10007fff7fff] || HighShadow ||
|| [0x004000000000, 0x02008fff6fff] || ShadowGap3 ||
|| [0x003000000000, 0x003fffffffff] || MidMem ||
|| [0x00087fff8000, 0x002fffffffff] || ShadowGap2 ||
|| [0x00067fff8000, 0x00087fff7fff] || MidShadow ||
|| [0x00008fff7000, 0x00067fff7fff] || ShadowGap ||
|| [0x00007fff8000, 0x00008fff6fff] || LowShadow ||
|| [0x000000000000, 0x00007fff7fff] || LowMem ||
Do it only if necessary.
Also added a bit of profiling code to make sure that the
mapping code is efficient.
Added a lit test to simulate prelink-ed libraries.
Unfortunately, this test does not work with binutils-gold linker.
If gold is the default linker the test silently passes.
Also replaced
__has_feature(address_sanitizer)
with
__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
in two places.
Patch partially by Jakub Jelinek.
llvm-svn: 175263
2013-02-15 20:00:24 +08:00
|
|
|
#if !ASAN_FIXED_MAPPING
|
2017-11-08 07:51:22 +08:00
|
|
|
kHighMemEnd = GetMaxUserVirtualAddress();
|
2013-07-16 17:47:39 +08:00
|
|
|
// Increase kHighMemEnd to make sure it's properly
|
|
|
|
// aligned together with kHighMemBeg:
|
2016-02-19 01:58:22 +08:00
|
|
|
kHighMemEnd |= SHADOW_GRANULARITY * GetMmapGranularity() - 1;
|
[asan] make asan work with 7fff8000 offset and prelink
When prelink is installed in the system, prelink-ed
libraries map between 0x003000000000 and 0x004000000000 thus occupying the shadow Gap,
so we need so split the address space even further, like this:
|| [0x10007fff8000, 0x7fffffffffff] || HighMem ||
|| [0x02008fff7000, 0x10007fff7fff] || HighShadow ||
|| [0x004000000000, 0x02008fff6fff] || ShadowGap3 ||
|| [0x003000000000, 0x003fffffffff] || MidMem ||
|| [0x00087fff8000, 0x002fffffffff] || ShadowGap2 ||
|| [0x00067fff8000, 0x00087fff7fff] || MidShadow ||
|| [0x00008fff7000, 0x00067fff7fff] || ShadowGap ||
|| [0x00007fff8000, 0x00008fff6fff] || LowShadow ||
|| [0x000000000000, 0x00007fff7fff] || LowMem ||
Do it only if necessary.
Also added a bit of profiling code to make sure that the
mapping code is efficient.
Added a lit test to simulate prelink-ed libraries.
Unfortunately, this test does not work with binutils-gold linker.
If gold is the default linker the test silently passes.
Also replaced
__has_feature(address_sanitizer)
with
__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
in two places.
Patch partially by Jakub Jelinek.
llvm-svn: 175263
2013-02-15 20:00:24 +08:00
|
|
|
#endif // !ASAN_FIXED_MAPPING
|
2016-02-19 01:58:22 +08:00
|
|
|
CHECK_EQ((kHighMemBeg % GetMmapGranularity()), 0);
|
2018-05-18 12:09:45 +08:00
|
|
|
#endif // !SANITIZER_MYRIAD2
|
[asan] make asan work with 7fff8000 offset and prelink
When prelink is installed in the system, prelink-ed
libraries map between 0x003000000000 and 0x004000000000 thus occupying the shadow Gap,
so we need so split the address space even further, like this:
|| [0x10007fff8000, 0x7fffffffffff] || HighMem ||
|| [0x02008fff7000, 0x10007fff7fff] || HighShadow ||
|| [0x004000000000, 0x02008fff6fff] || ShadowGap3 ||
|| [0x003000000000, 0x003fffffffff] || MidMem ||
|| [0x00087fff8000, 0x002fffffffff] || ShadowGap2 ||
|| [0x00067fff8000, 0x00087fff7fff] || MidShadow ||
|| [0x00008fff7000, 0x00067fff7fff] || ShadowGap ||
|| [0x00007fff8000, 0x00008fff6fff] || LowShadow ||
|| [0x000000000000, 0x00007fff7fff] || LowMem ||
Do it only if necessary.
Also added a bit of profiling code to make sure that the
mapping code is efficient.
Added a lit test to simulate prelink-ed libraries.
Unfortunately, this test does not work with binutils-gold linker.
If gold is the default linker the test silently passes.
Also replaced
__has_feature(address_sanitizer)
with
__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
in two places.
Patch partially by Jakub Jelinek.
llvm-svn: 175263
2013-02-15 20:00:24 +08:00
|
|
|
}
|
|
|
|
|
2017-07-31 14:48:34 +08:00
|
|
|
void PrintAddressSpaceLayout() {
|
2018-05-18 12:09:45 +08:00
|
|
|
if (kHighMemBeg) {
|
|
|
|
Printf("|| `[%p, %p]` || HighMem ||\n",
|
|
|
|
(void*)kHighMemBeg, (void*)kHighMemEnd);
|
|
|
|
Printf("|| `[%p, %p]` || HighShadow ||\n",
|
|
|
|
(void*)kHighShadowBeg, (void*)kHighShadowEnd);
|
|
|
|
}
|
[asan] make asan work with 7fff8000 offset and prelink
When prelink is installed in the system, prelink-ed
libraries map between 0x003000000000 and 0x004000000000 thus occupying the shadow Gap,
so we need so split the address space even further, like this:
|| [0x10007fff8000, 0x7fffffffffff] || HighMem ||
|| [0x02008fff7000, 0x10007fff7fff] || HighShadow ||
|| [0x004000000000, 0x02008fff6fff] || ShadowGap3 ||
|| [0x003000000000, 0x003fffffffff] || MidMem ||
|| [0x00087fff8000, 0x002fffffffff] || ShadowGap2 ||
|| [0x00067fff8000, 0x00087fff7fff] || MidShadow ||
|| [0x00008fff7000, 0x00067fff7fff] || ShadowGap ||
|| [0x00007fff8000, 0x00008fff6fff] || LowShadow ||
|| [0x000000000000, 0x00007fff7fff] || LowMem ||
Do it only if necessary.
Also added a bit of profiling code to make sure that the
mapping code is efficient.
Added a lit test to simulate prelink-ed libraries.
Unfortunately, this test does not work with binutils-gold linker.
If gold is the default linker the test silently passes.
Also replaced
__has_feature(address_sanitizer)
with
__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
in two places.
Patch partially by Jakub Jelinek.
llvm-svn: 175263
2013-02-15 20:00:24 +08:00
|
|
|
if (kMidMemBeg) {
|
|
|
|
Printf("|| `[%p, %p]` || ShadowGap3 ||\n",
|
|
|
|
(void*)kShadowGap3Beg, (void*)kShadowGap3End);
|
|
|
|
Printf("|| `[%p, %p]` || MidMem ||\n",
|
|
|
|
(void*)kMidMemBeg, (void*)kMidMemEnd);
|
|
|
|
Printf("|| `[%p, %p]` || ShadowGap2 ||\n",
|
|
|
|
(void*)kShadowGap2Beg, (void*)kShadowGap2End);
|
|
|
|
Printf("|| `[%p, %p]` || MidShadow ||\n",
|
|
|
|
(void*)kMidShadowBeg, (void*)kMidShadowEnd);
|
|
|
|
}
|
|
|
|
Printf("|| `[%p, %p]` || ShadowGap ||\n",
|
|
|
|
(void*)kShadowGapBeg, (void*)kShadowGapEnd);
|
|
|
|
if (kLowShadowBeg) {
|
|
|
|
Printf("|| `[%p, %p]` || LowShadow ||\n",
|
|
|
|
(void*)kLowShadowBeg, (void*)kLowShadowEnd);
|
|
|
|
Printf("|| `[%p, %p]` || LowMem ||\n",
|
|
|
|
(void*)kLowMemBeg, (void*)kLowMemEnd);
|
|
|
|
}
|
2018-05-18 12:09:45 +08:00
|
|
|
Printf("MemToShadow(shadow): %p %p",
|
[asan] make asan work with 7fff8000 offset and prelink
When prelink is installed in the system, prelink-ed
libraries map between 0x003000000000 and 0x004000000000 thus occupying the shadow Gap,
so we need so split the address space even further, like this:
|| [0x10007fff8000, 0x7fffffffffff] || HighMem ||
|| [0x02008fff7000, 0x10007fff7fff] || HighShadow ||
|| [0x004000000000, 0x02008fff6fff] || ShadowGap3 ||
|| [0x003000000000, 0x003fffffffff] || MidMem ||
|| [0x00087fff8000, 0x002fffffffff] || ShadowGap2 ||
|| [0x00067fff8000, 0x00087fff7fff] || MidShadow ||
|| [0x00008fff7000, 0x00067fff7fff] || ShadowGap ||
|| [0x00007fff8000, 0x00008fff6fff] || LowShadow ||
|| [0x000000000000, 0x00007fff7fff] || LowMem ||
Do it only if necessary.
Also added a bit of profiling code to make sure that the
mapping code is efficient.
Added a lit test to simulate prelink-ed libraries.
Unfortunately, this test does not work with binutils-gold linker.
If gold is the default linker the test silently passes.
Also replaced
__has_feature(address_sanitizer)
with
__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
in two places.
Patch partially by Jakub Jelinek.
llvm-svn: 175263
2013-02-15 20:00:24 +08:00
|
|
|
(void*)MEM_TO_SHADOW(kLowShadowBeg),
|
2018-05-18 12:09:45 +08:00
|
|
|
(void*)MEM_TO_SHADOW(kLowShadowEnd));
|
|
|
|
if (kHighMemBeg) {
|
|
|
|
Printf(" %p %p",
|
|
|
|
(void*)MEM_TO_SHADOW(kHighShadowBeg),
|
|
|
|
(void*)MEM_TO_SHADOW(kHighShadowEnd));
|
|
|
|
}
|
[asan] make asan work with 7fff8000 offset and prelink
When prelink is installed in the system, prelink-ed
libraries map between 0x003000000000 and 0x004000000000 thus occupying the shadow Gap,
so we need so split the address space even further, like this:
|| [0x10007fff8000, 0x7fffffffffff] || HighMem ||
|| [0x02008fff7000, 0x10007fff7fff] || HighShadow ||
|| [0x004000000000, 0x02008fff6fff] || ShadowGap3 ||
|| [0x003000000000, 0x003fffffffff] || MidMem ||
|| [0x00087fff8000, 0x002fffffffff] || ShadowGap2 ||
|| [0x00067fff8000, 0x00087fff7fff] || MidShadow ||
|| [0x00008fff7000, 0x00067fff7fff] || ShadowGap ||
|| [0x00007fff8000, 0x00008fff6fff] || LowShadow ||
|| [0x000000000000, 0x00007fff7fff] || LowMem ||
Do it only if necessary.
Also added a bit of profiling code to make sure that the
mapping code is efficient.
Added a lit test to simulate prelink-ed libraries.
Unfortunately, this test does not work with binutils-gold linker.
If gold is the default linker the test silently passes.
Also replaced
__has_feature(address_sanitizer)
with
__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
in two places.
Patch partially by Jakub Jelinek.
llvm-svn: 175263
2013-02-15 20:00:24 +08:00
|
|
|
if (kMidMemBeg) {
|
|
|
|
Printf(" %p %p",
|
|
|
|
(void*)MEM_TO_SHADOW(kMidShadowBeg),
|
|
|
|
(void*)MEM_TO_SHADOW(kMidShadowEnd));
|
|
|
|
}
|
|
|
|
Printf("\n");
|
2014-01-09 22:41:03 +08:00
|
|
|
Printf("redzone=%zu\n", (uptr)flags()->redzone);
|
|
|
|
Printf("max_redzone=%zu\n", (uptr)flags()->max_redzone);
|
2015-01-07 10:37:52 +08:00
|
|
|
Printf("quarantine_size_mb=%zuM\n", (uptr)flags()->quarantine_size_mb);
|
2016-12-23 05:43:22 +08:00
|
|
|
Printf("thread_local_quarantine_size_kb=%zuK\n",
|
|
|
|
(uptr)flags()->thread_local_quarantine_size_kb);
|
2013-05-06 19:27:58 +08:00
|
|
|
Printf("malloc_context_size=%zu\n",
|
|
|
|
(uptr)common_flags()->malloc_context_size);
|
[asan] make asan work with 7fff8000 offset and prelink
When prelink is installed in the system, prelink-ed
libraries map between 0x003000000000 and 0x004000000000 thus occupying the shadow Gap,
so we need so split the address space even further, like this:
|| [0x10007fff8000, 0x7fffffffffff] || HighMem ||
|| [0x02008fff7000, 0x10007fff7fff] || HighShadow ||
|| [0x004000000000, 0x02008fff6fff] || ShadowGap3 ||
|| [0x003000000000, 0x003fffffffff] || MidMem ||
|| [0x00087fff8000, 0x002fffffffff] || ShadowGap2 ||
|| [0x00067fff8000, 0x00087fff7fff] || MidShadow ||
|| [0x00008fff7000, 0x00067fff7fff] || ShadowGap ||
|| [0x00007fff8000, 0x00008fff6fff] || LowShadow ||
|| [0x000000000000, 0x00007fff7fff] || LowMem ||
Do it only if necessary.
Also added a bit of profiling code to make sure that the
mapping code is efficient.
Added a lit test to simulate prelink-ed libraries.
Unfortunately, this test does not work with binutils-gold linker.
If gold is the default linker the test silently passes.
Also replaced
__has_feature(address_sanitizer)
with
__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
in two places.
Patch partially by Jakub Jelinek.
llvm-svn: 175263
2013-02-15 20:00:24 +08:00
|
|
|
|
2015-04-25 18:57:35 +08:00
|
|
|
Printf("SHADOW_SCALE: %d\n", (int)SHADOW_SCALE);
|
|
|
|
Printf("SHADOW_GRANULARITY: %d\n", (int)SHADOW_GRANULARITY);
|
|
|
|
Printf("SHADOW_OFFSET: 0x%zx\n", (uptr)SHADOW_OFFSET);
|
[asan] make asan work with 7fff8000 offset and prelink
When prelink is installed in the system, prelink-ed
libraries map between 0x003000000000 and 0x004000000000 thus occupying the shadow Gap,
so we need so split the address space even further, like this:
|| [0x10007fff8000, 0x7fffffffffff] || HighMem ||
|| [0x02008fff7000, 0x10007fff7fff] || HighShadow ||
|| [0x004000000000, 0x02008fff6fff] || ShadowGap3 ||
|| [0x003000000000, 0x003fffffffff] || MidMem ||
|| [0x00087fff8000, 0x002fffffffff] || ShadowGap2 ||
|| [0x00067fff8000, 0x00087fff7fff] || MidShadow ||
|| [0x00008fff7000, 0x00067fff7fff] || ShadowGap ||
|| [0x00007fff8000, 0x00008fff6fff] || LowShadow ||
|| [0x000000000000, 0x00007fff7fff] || LowMem ||
Do it only if necessary.
Also added a bit of profiling code to make sure that the
mapping code is efficient.
Added a lit test to simulate prelink-ed libraries.
Unfortunately, this test does not work with binutils-gold linker.
If gold is the default linker the test silently passes.
Also replaced
__has_feature(address_sanitizer)
with
__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
in two places.
Patch partially by Jakub Jelinek.
llvm-svn: 175263
2013-02-15 20:00:24 +08:00
|
|
|
CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
|
|
|
|
if (kMidMemBeg)
|
|
|
|
CHECK(kMidShadowBeg > kLowShadowEnd &&
|
|
|
|
kMidMemBeg > kMidShadowEnd &&
|
|
|
|
kHighShadowBeg > kMidMemEnd);
|
2013-01-23 21:27:43 +08:00
|
|
|
}
|
|
|
|
|
2019-01-14 17:45:49 +08:00
|
|
|
#if defined(__thumb__) && defined(__linux__)
|
|
|
|
#define START_BACKGROUND_THREAD_IN_ASAN_INTERNAL
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef START_BACKGROUND_THREAD_IN_ASAN_INTERNAL
|
2018-12-29 08:32:07 +08:00
|
|
|
static bool UNUSED __local_asan_dyninit = [] {
|
|
|
|
MaybeStartBackgroudThread();
|
|
|
|
SetSoftRssLimitExceededCallback(AsanSoftRssLimitExceededCallback);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}();
|
2019-01-14 17:45:49 +08:00
|
|
|
#endif
|
2018-12-29 08:32:07 +08:00
|
|
|
|
2016-11-29 05:40:41 +08:00
|
|
|
static void AsanInitInternal() {
|
|
|
|
if (LIKELY(asan_inited)) return;
|
|
|
|
SanitizerToolName = "AddressSanitizer";
|
|
|
|
CHECK(!asan_init_is_running && "ASan init calls itself!");
|
|
|
|
asan_init_is_running = true;
|
|
|
|
|
|
|
|
CacheBinaryName();
|
2018-06-05 15:29:23 +08:00
|
|
|
CheckASLR();
|
2016-11-29 05:40:41 +08:00
|
|
|
|
|
|
|
// Initialize flags. This must be done early, because most of the
|
|
|
|
// initialization steps look at flags().
|
|
|
|
InitializeFlags();
|
|
|
|
|
2018-12-01 23:45:42 +08:00
|
|
|
// Stop performing init at this point if we are being loaded via
|
|
|
|
// dlopen() and the platform supports it.
|
|
|
|
if (SANITIZER_SUPPORTS_INIT_FOR_DLOPEN && UNLIKELY(HandleDlopenInit())) {
|
|
|
|
asan_init_is_running = false;
|
|
|
|
VReport(1, "AddressSanitizer init is being performed for dlopen().\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-11-29 05:40:41 +08:00
|
|
|
AsanCheckIncompatibleRT();
|
|
|
|
AsanCheckDynamicRTPrereqs();
|
|
|
|
AvoidCVE_2016_2143();
|
|
|
|
|
|
|
|
SetCanPoisonMemory(flags()->poison_heap);
|
|
|
|
SetMallocContextSize(common_flags()->malloc_context_size);
|
|
|
|
|
|
|
|
InitializePlatformExceptionHandlers();
|
|
|
|
|
|
|
|
InitializeHighMemEnd();
|
|
|
|
|
|
|
|
// Make sure we are not statically linked.
|
|
|
|
AsanDoesNotSupportStaticLinkage();
|
|
|
|
|
|
|
|
// Install tool-specific callbacks in sanitizer_common.
|
|
|
|
AddDieCallback(AsanDie);
|
|
|
|
SetCheckFailedCallback(AsanCheckFailed);
|
|
|
|
SetPrintfAndReportCallback(AppendToErrorMessageBuffer);
|
|
|
|
|
|
|
|
__sanitizer_set_report_path(common_flags()->log_path);
|
|
|
|
|
|
|
|
__asan_option_detect_stack_use_after_return =
|
|
|
|
flags()->detect_stack_use_after_return;
|
|
|
|
|
2018-11-07 03:55:19 +08:00
|
|
|
__sanitizer::InitializePlatformEarly();
|
|
|
|
|
2016-11-29 05:40:41 +08:00
|
|
|
// Re-exec ourselves if we need to set additional env or command line args.
|
|
|
|
MaybeReexec();
|
|
|
|
|
|
|
|
// Setup internal allocator callback.
|
2017-11-21 09:01:32 +08:00
|
|
|
SetLowLevelAllocateMinAlignment(SHADOW_GRANULARITY);
|
2016-11-29 05:40:41 +08:00
|
|
|
SetLowLevelAllocateCallback(OnLowLevelAllocate);
|
|
|
|
|
|
|
|
InitializeAsanInterceptors();
|
|
|
|
|
|
|
|
// Enable system log ("adb logcat") on Android.
|
|
|
|
// Doing this before interceptors are initialized crashes in:
|
|
|
|
// AsanInitInternal -> android_log_write -> __interceptor_strcmp
|
|
|
|
AndroidLogInit();
|
|
|
|
|
|
|
|
ReplaceSystemMalloc();
|
|
|
|
|
|
|
|
DisableCoreDumperIfNecessary();
|
|
|
|
|
|
|
|
InitializeShadowMemory();
|
2011-11-30 09:07:02 +08:00
|
|
|
|
2013-10-17 21:18:21 +08:00
|
|
|
AsanTSDInit(PlatformTSDDtor);
|
2015-08-07 01:52:54 +08:00
|
|
|
InstallDeadlySignalHandlers(AsanOnDeadlySignal);
|
2013-06-11 16:13:36 +08:00
|
|
|
|
2014-12-20 03:35:11 +08:00
|
|
|
AllocatorOptions allocator_options;
|
|
|
|
allocator_options.SetFrom(flags(), common_flags());
|
|
|
|
InitializeAllocator(allocator_options);
|
2013-06-11 16:13:36 +08:00
|
|
|
|
2019-01-14 17:45:49 +08:00
|
|
|
#ifdef START_BACKGROUND_THREAD_IN_ASAN_INTERNAL
|
|
|
|
MaybeStartBackgroudThread();
|
|
|
|
SetSoftRssLimitExceededCallback(AsanSoftRssLimitExceededCallback);
|
|
|
|
#endif
|
|
|
|
|
2011-11-30 09:07:02 +08:00
|
|
|
// On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited
|
|
|
|
// should be set to 1 prior to initializing the threads.
|
|
|
|
asan_inited = 1;
|
|
|
|
asan_init_is_running = false;
|
|
|
|
|
2013-10-18 15:57:59 +08:00
|
|
|
if (flags()->atexit)
|
|
|
|
Atexit(asan_atexit);
|
|
|
|
|
2014-12-26 20:32:32 +08:00
|
|
|
InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
|
|
|
|
|
|
|
|
// Now that ASan runtime is (mostly) initialized, deactivate it if
|
|
|
|
// necessary, so that it can be re-activated when requested.
|
|
|
|
if (flags()->start_deactivated)
|
|
|
|
AsanDeactivate();
|
2013-11-15 15:18:15 +08:00
|
|
|
|
2013-10-18 15:57:59 +08:00
|
|
|
// interceptors
|
2013-05-29 21:09:44 +08:00
|
|
|
InitTlsSize();
|
|
|
|
|
2013-03-21 19:23:41 +08:00
|
|
|
// Create main thread.
|
2017-08-09 08:38:57 +08:00
|
|
|
AsanThread *main_thread = CreateMainThread();
|
2014-12-06 01:31:13 +08:00
|
|
|
CHECK_EQ(0, main_thread->tid());
|
2011-12-28 08:59:39 +08:00
|
|
|
force_interface_symbols(); // no-op.
|
2014-02-11 21:38:57 +08:00
|
|
|
SanitizerInitializeUnwinder();
|
2011-11-30 09:07:02 +08:00
|
|
|
|
2016-06-08 03:13:38 +08:00
|
|
|
if (CAN_SANITIZE_LEAKS) {
|
|
|
|
__lsan::InitCommonLsan();
|
|
|
|
if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) {
|
2017-09-22 15:11:43 +08:00
|
|
|
if (flags()->halt_on_error)
|
|
|
|
Atexit(__lsan::DoLeakCheck);
|
|
|
|
else
|
|
|
|
Atexit(__lsan::DoRecoverableLeakCheckVoid);
|
2016-06-08 03:13:38 +08:00
|
|
|
}
|
2013-05-22 01:56:45 +08:00
|
|
|
}
|
2013-05-21 22:15:35 +08:00
|
|
|
|
2015-04-02 06:42:36 +08:00
|
|
|
#if CAN_SANITIZE_UB
|
|
|
|
__ubsan::InitAsPlugin();
|
|
|
|
#endif
|
|
|
|
|
2014-12-06 04:26:09 +08:00
|
|
|
InitializeSuppressions();
|
|
|
|
|
2016-06-08 03:13:38 +08:00
|
|
|
if (CAN_SANITIZE_LEAKS) {
|
2016-05-18 21:00:20 +08:00
|
|
|
// LateInitialize() calls dlsym, which can allocate an error string buffer
|
|
|
|
// in the TLS. Let's ignore the allocation to avoid reporting a leak.
|
|
|
|
__lsan::ScopedInterceptorDisabler disabler;
|
2016-06-08 03:13:38 +08:00
|
|
|
Symbolizer::LateInitialize();
|
|
|
|
} else {
|
2016-05-18 21:00:20 +08:00
|
|
|
Symbolizer::LateInitialize();
|
|
|
|
}
|
2016-05-12 21:11:03 +08:00
|
|
|
|
2013-12-05 20:04:51 +08:00
|
|
|
VReport(1, "AddressSanitizer Init done\n");
|
2017-08-03 02:48:45 +08:00
|
|
|
|
|
|
|
if (flags()->sleep_after_init) {
|
|
|
|
Report("Sleeping for %d second(s)\n", flags()->sleep_after_init);
|
|
|
|
SleepForSeconds(flags()->sleep_after_init);
|
|
|
|
}
|
2011-11-30 09:07:02 +08:00
|
|
|
}
|
2014-01-16 20:31:50 +08:00
|
|
|
|
|
|
|
// Initialize as requested from some part of ASan runtime library (interceptors,
|
|
|
|
// allocator, etc).
|
|
|
|
void AsanInitFromRtl() {
|
|
|
|
AsanInitInternal();
|
|
|
|
}
|
|
|
|
|
2014-04-01 21:16:30 +08:00
|
|
|
#if ASAN_DYNAMIC
|
|
|
|
// Initialize runtime in case it's LD_PRELOAD-ed into unsanitized executable
|
2015-06-04 15:23:09 +08:00
|
|
|
// (and thus normal initializers from .preinit_array or modules haven't run).
|
2014-04-01 21:16:30 +08:00
|
|
|
|
|
|
|
class AsanInitializer {
|
|
|
|
public: // NOLINT
|
|
|
|
AsanInitializer() {
|
2014-11-25 15:10:30 +08:00
|
|
|
AsanInitFromRtl();
|
2014-04-01 21:16:30 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static AsanInitializer asan_initializer;
|
|
|
|
#endif // ASAN_DYNAMIC
|
|
|
|
|
2015-10-01 08:22:21 +08:00
|
|
|
} // namespace __asan
|
2014-01-16 20:31:50 +08:00
|
|
|
|
|
|
|
// ---------------------- Interface ---------------- {{{1
|
|
|
|
using namespace __asan; // NOLINT
|
|
|
|
|
|
|
|
void NOINLINE __asan_handle_no_return() {
|
Make __asan_handle_no_return a no-op during initialization
Some of our existing tests hang on the new Windows bot with this stack:
770, clang_rt.asan_dynamic-i386.dll!__asan::AsanTSDGet+0x3e
771, clang_rt.asan_dynamic-i386.dll!__asan::GetCurrentThread+0x9
772, clang_rt.asan_dynamic-i386.dll!__asan_handle_no_return+0xe
773, clang_rt.asan_dynamic-i386.dll!__asan_wrap__except_handler4_common+0x12
774, ntdll.dll!wcstombs+0xb0 (No unwind info)
775, ntdll.dll!ZwWow64CallFunction64+0x2001 (No unwind info)
776, ntdll.dll!ZwWow64CallFunction64+0x1fd3 (No unwind info)
777, ntdll.dll!KiUserExceptionDispatcher+0xf (No unwind info)
778, clang_rt.asan_dynamic-i386.dll!destroy_fls+0x13
779, ntdll.dll!RtlLockHeap+0xea (No unwind info)
780, ntdll.dll!LdrShutdownProcess+0x7f (No unwind info)
781, ntdll.dll!RtlExitUserProcess+0x81 (No unwind info)
782, kernel32.dll!ExitProcess+0x13 (No unwind info)
783, clang_rt.asan_dynamic-i386.dll!__sanitizer::internal__exit+0xc
784, clang_rt.asan_dynamic-i386.dll!__sanitizer::Die+0x3d
785, clang_rt.asan_dynamic-i386.dll!__asan::AsanInitInternal+0x50b
786, clang_rt.asan_dynamic-i386.dll!__asan::Allocator::Allocate+0x1c
787, clang_rt.asan_dynamic-i386.dll!__asan::Allocator::Calloc+0x43
We hang because AsanDie tries to defend against multi-threaded death by
infinite looping if someone is already exiting. We might want to
reconsider that, but one easy way to avoid getting here is not to let
our noreturn interceptors call back into fragile parts of ASan.
llvm-svn: 284067
2016-10-13 06:33:57 +08:00
|
|
|
if (asan_init_is_running)
|
|
|
|
return;
|
|
|
|
|
2014-01-16 20:31:50 +08:00
|
|
|
int local_stack;
|
|
|
|
AsanThread *curr_thread = GetCurrentThread();
|
|
|
|
uptr PageSize = GetPageSizeCached();
|
2015-07-23 05:58:31 +08:00
|
|
|
uptr top, bottom;
|
|
|
|
if (curr_thread) {
|
|
|
|
top = curr_thread->stack_top();
|
|
|
|
bottom = ((uptr)&local_stack - PageSize) & ~(PageSize - 1);
|
2018-05-22 04:43:36 +08:00
|
|
|
} else if (SANITIZER_RTEMS) {
|
|
|
|
// Give up On RTEMS.
|
|
|
|
return;
|
2015-07-23 05:58:31 +08:00
|
|
|
} else {
|
2017-08-09 08:21:45 +08:00
|
|
|
CHECK(!SANITIZER_FUCHSIA);
|
2015-07-23 05:58:31 +08:00
|
|
|
// If we haven't seen this thread, try asking the OS for stack bounds.
|
|
|
|
uptr tls_addr, tls_size, stack_size;
|
|
|
|
GetThreadStackAndTls(/*main=*/false, &bottom, &stack_size, &tls_addr,
|
|
|
|
&tls_size);
|
|
|
|
top = bottom + stack_size;
|
|
|
|
}
|
2014-01-16 20:31:50 +08:00
|
|
|
static const uptr kMaxExpectedCleanupSize = 64 << 20; // 64M
|
|
|
|
if (top - bottom > kMaxExpectedCleanupSize) {
|
|
|
|
static bool reported_warning = false;
|
|
|
|
if (reported_warning)
|
|
|
|
return;
|
|
|
|
reported_warning = true;
|
|
|
|
Report("WARNING: ASan is ignoring requested __asan_handle_no_return: "
|
|
|
|
"stack top: %p; bottom %p; size: %p (%zd)\n"
|
|
|
|
"False positive error reports may follow\n"
|
|
|
|
"For details see "
|
2015-12-05 01:37:40 +08:00
|
|
|
"https://github.com/google/sanitizers/issues/189\n",
|
2014-01-16 20:31:50 +08:00
|
|
|
top, bottom, top - bottom, top - bottom);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
PoisonShadow(bottom, top - bottom, 0);
|
2015-07-23 05:58:31 +08:00
|
|
|
if (curr_thread && curr_thread->has_fake_stack())
|
2014-01-16 20:31:50 +08:00
|
|
|
curr_thread->fake_stack()->HandleNoReturn();
|
|
|
|
}
|
|
|
|
|
|
|
|
void NOINLINE __asan_set_death_callback(void (*callback)(void)) {
|
2014-12-16 07:02:57 +08:00
|
|
|
SetUserDieCallback(callback);
|
2014-01-16 20:31:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize as requested from instrumented application code.
|
|
|
|
// We use this call as a trigger to wake up ASan from deactivated state.
|
|
|
|
void __asan_init() {
|
|
|
|
AsanActivate();
|
|
|
|
AsanInitInternal();
|
|
|
|
}
|
2015-07-23 18:55:13 +08:00
|
|
|
|
|
|
|
void __asan_version_mismatch_check() {
|
|
|
|
// Do nothing.
|
|
|
|
}
|