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 {
|
|
|
|
UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
|
|
|
|
}
|
|
|
|
}
|
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);
|
2012-09-07 23:50:19 +08:00
|
|
|
// FIXME: check for infinite recursion without a thread-local counter here.
|
2014-10-14 17:36:24 +08:00
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
// ---------------------- mmap -------------------- {{{1
|
2011-12-29 07:28:54 +08:00
|
|
|
// Reserve memory range [beg, end].
|
2015-01-21 10:05:31 +08:00
|
|
|
// We need to use inclusive range because end+1 may not be representable.
|
2015-05-30 06:31:28 +08:00
|
|
|
void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name) {
|
2016-02-19 01:58:22 +08:00
|
|
|
CHECK_EQ((beg % GetMmapGranularity()), 0);
|
|
|
|
CHECK_EQ(((end + 1) % GetMmapGranularity()), 0);
|
2012-05-31 22:35:53 +08:00
|
|
|
uptr size = end - beg + 1;
|
2014-04-14 22:51:01 +08:00
|
|
|
DecreaseTotalMmap(size); // Don't count the shadow against mmap_limit_mb.
|
2015-05-30 06:31:28 +08:00
|
|
|
void *res = MmapFixedNoReserve(beg, size, name);
|
2012-09-07 23:34:40 +08:00
|
|
|
if (res != (void*)beg) {
|
|
|
|
Report("ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. "
|
|
|
|
"Perhaps you're using ulimit -v\n", size);
|
|
|
|
Abort();
|
|
|
|
}
|
2015-01-21 10:05:31 +08:00
|
|
|
if (common_flags()->no_huge_pages_for_shadow)
|
|
|
|
NoHugePagesInRegion(beg, size);
|
2015-02-03 18:15:15 +08:00
|
|
|
if (common_flags()->use_madv_dontdump)
|
|
|
|
DontDumpShadowMemory(beg, size);
|
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) \
|
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() {
|
[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
|
2013-07-16 17:47:39 +08:00
|
|
|
kHighMemEnd = GetMaxVirtualAddress();
|
|
|
|
// 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);
|
[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-10 23:31:16 +08:00
|
|
|
static void ProtectGap(uptr addr, uptr size) {
|
2016-10-05 07:39:58 +08:00
|
|
|
if (!flags()->protect_shadow_gap) {
|
|
|
|
// The shadow gap is unprotected, so there is a chance that someone
|
|
|
|
// is actually using this memory. Which means it needs a shadow...
|
|
|
|
uptr GapShadowBeg = RoundDownTo(MEM_TO_SHADOW(addr), GetPageSizeCached());
|
|
|
|
uptr GapShadowEnd =
|
|
|
|
RoundUpTo(MEM_TO_SHADOW(addr + size), GetPageSizeCached()) - 1;
|
|
|
|
if (Verbosity())
|
|
|
|
Printf("protect_shadow_gap=0:"
|
|
|
|
" not protecting shadow gap, allocating gap's shadow\n"
|
|
|
|
"|| `[%p, %p]` || ShadowGap's shadow ||\n", GapShadowBeg,
|
|
|
|
GapShadowEnd);
|
|
|
|
ReserveShadowMemoryRange(GapShadowBeg, GapShadowEnd,
|
|
|
|
"unprotected gap shadow");
|
2015-11-14 08:50:23 +08:00
|
|
|
return;
|
2016-10-05 07:39:58 +08:00
|
|
|
}
|
2016-04-23 07:46:53 +08:00
|
|
|
void *res = MmapFixedNoAccess(addr, size, "shadow gap");
|
2015-04-10 23:31:16 +08:00
|
|
|
if (addr == (uptr)res)
|
2015-02-02 23:04:23 +08:00
|
|
|
return;
|
2015-08-08 06:38:44 +08:00
|
|
|
// A few pages at the start of the address space can not be protected.
|
|
|
|
// But we really want to protect as much as possible, to prevent this memory
|
|
|
|
// being returned as a result of a non-FIXED mmap().
|
|
|
|
if (addr == kZeroBaseShadowStart) {
|
2016-02-19 01:58:22 +08:00
|
|
|
uptr step = GetMmapGranularity();
|
2015-08-08 06:38:44 +08:00
|
|
|
while (size > step && addr < kZeroBaseMaxShadowStart) {
|
|
|
|
addr += step;
|
|
|
|
size -= step;
|
2016-04-23 07:46:53 +08:00
|
|
|
void *res = MmapFixedNoAccess(addr, size, "shadow gap");
|
2015-08-08 06:38:44 +08:00
|
|
|
if (addr == (uptr)res)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-02 23:04:23 +08:00
|
|
|
Report("ERROR: Failed to protect the shadow gap. "
|
|
|
|
"ASan cannot proceed correctly. ABORTING.\n");
|
|
|
|
DumpProcessMap();
|
|
|
|
Die();
|
[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
|
|
|
}
|
|
|
|
|
|
|
|
static void PrintAddressSpaceLayout() {
|
|
|
|
Printf("|| `[%p, %p]` || HighMem ||\n",
|
|
|
|
(void*)kHighMemBeg, (void*)kHighMemEnd);
|
|
|
|
Printf("|| `[%p, %p]` || HighShadow ||\n",
|
|
|
|
(void*)kHighShadowBeg, (void*)kHighShadowEnd);
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
Printf("MemToShadow(shadow): %p %p %p %p",
|
|
|
|
(void*)MEM_TO_SHADOW(kLowShadowBeg),
|
|
|
|
(void*)MEM_TO_SHADOW(kLowShadowEnd),
|
|
|
|
(void*)MEM_TO_SHADOW(kHighShadowBeg),
|
|
|
|
(void*)MEM_TO_SHADOW(kHighShadowEnd));
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2016-11-29 05:40:41 +08:00
|
|
|
static void InitializeShadowMemory() {
|
2016-10-01 01:47:34 +08:00
|
|
|
// Set the shadow memory address to uninitialized.
|
|
|
|
__asan_shadow_memory_dynamic_address = kDefaultShadowSentinel;
|
|
|
|
|
[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 shadow_start = kLowShadowBeg;
|
2016-10-01 01:47:34 +08:00
|
|
|
// Detect if a dynamic shadow address must used and find a available location
|
|
|
|
// when necessary. When dynamic address is used, the macro |kLowShadowBeg|
|
|
|
|
// expands to |__asan_shadow_memory_dynamic_address| which is
|
|
|
|
// |kDefaultShadowSentinel|.
|
|
|
|
if (shadow_start == kDefaultShadowSentinel) {
|
|
|
|
__asan_shadow_memory_dynamic_address = 0;
|
|
|
|
CHECK_EQ(0, kLowShadowBeg);
|
|
|
|
|
|
|
|
uptr granularity = GetMmapGranularity();
|
|
|
|
uptr alignment = 8 * granularity;
|
|
|
|
uptr left_padding = granularity;
|
|
|
|
uptr space_size = kHighShadowEnd + left_padding;
|
|
|
|
|
|
|
|
shadow_start = FindAvailableMemoryRange(space_size, alignment, granularity);
|
|
|
|
CHECK_NE((uptr)0, shadow_start);
|
|
|
|
CHECK(IsAligned(shadow_start, alignment));
|
|
|
|
}
|
|
|
|
// Update the shadow memory address (potentially) used by instrumentation.
|
|
|
|
__asan_shadow_memory_dynamic_address = shadow_start;
|
|
|
|
|
2013-07-16 17:47:39 +08:00
|
|
|
if (kLowShadowBeg)
|
|
|
|
shadow_start -= GetMmapGranularity();
|
[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
|
|
|
bool full_shadow_is_available =
|
2013-07-16 17:47:39 +08:00
|
|
|
MemoryRangeIsAvailable(shadow_start, 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
|
|
|
|
2014-07-11 23:22:45 +08:00
|
|
|
#if SANITIZER_LINUX && defined(__x86_64__) && defined(_LP64) && \
|
|
|
|
!ASAN_FIXED_MAPPING
|
[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 (!full_shadow_is_available) {
|
|
|
|
kMidMemBeg = kLowMemEnd < 0x3000000000ULL ? 0x3000000000ULL : 0;
|
2013-02-28 20:28:37 +08:00
|
|
|
kMidMemEnd = kLowMemEnd < 0x3000000000ULL ? 0x4fffffffffULL : 0;
|
2011-11-30 09:07:02 +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
|
|
|
#endif
|
|
|
|
|
2015-01-20 21:21:20 +08:00
|
|
|
if (Verbosity()) PrintAddressSpaceLayout();
|
2011-11-30 09:07:02 +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 (full_shadow_is_available) {
|
|
|
|
// mmap the low shadow plus at least one page at the left.
|
|
|
|
if (kLowShadowBeg)
|
2015-05-30 06:31:28 +08:00
|
|
|
ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, "low shadow");
|
[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
|
|
|
// mmap the high shadow.
|
2015-05-30 06:31:28 +08:00
|
|
|
ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, "high shadow");
|
[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
|
|
|
// protect the gap.
|
|
|
|
ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
|
2014-03-27 15:36:26 +08:00
|
|
|
CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 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
|
|
|
} else if (kMidMemBeg &&
|
|
|
|
MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) &&
|
2013-07-16 17:47:39 +08:00
|
|
|
MemoryRangeIsAvailable(kMidMemEnd + 1, 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
|
|
|
CHECK(kLowShadowBeg != kLowShadowEnd);
|
|
|
|
// mmap the low shadow plus at least one page at the left.
|
2015-05-30 06:31:28 +08:00
|
|
|
ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, "low shadow");
|
[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
|
|
|
// mmap the mid shadow.
|
2015-05-30 06:31:28 +08:00
|
|
|
ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd, "mid shadow");
|
2012-01-10 03:18:27 +08:00
|
|
|
// mmap the high shadow.
|
2015-05-30 06:31:28 +08:00
|
|
|
ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, "high shadow");
|
[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
|
|
|
// protect the gaps.
|
|
|
|
ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
|
|
|
|
ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1);
|
|
|
|
ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1);
|
2012-02-13 23:11:23 +08:00
|
|
|
} else {
|
|
|
|
Report("Shadow memory range interleaves with an existing memory mapping. "
|
|
|
|
"ASan cannot proceed correctly. ABORTING.\n");
|
2015-01-22 20:05:27 +08:00
|
|
|
Report("ASan shadow was supposed to be located in the [%p-%p] range.\n",
|
|
|
|
shadow_start, kHighShadowEnd);
|
2012-06-15 14:08:19 +08:00
|
|
|
DumpProcessMap();
|
2012-06-06 15:02:44 +08:00
|
|
|
Die();
|
2011-11-30 09:07:02 +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();
|
|
|
|
|
|
|
|
// Initialize flags. This must be done early, because most of the
|
|
|
|
// initialization steps look at flags().
|
|
|
|
InitializeFlags();
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
// Re-exec ourselves if we need to set additional env or command line args.
|
|
|
|
MaybeReexec();
|
|
|
|
|
|
|
|
// Setup internal allocator callback.
|
|
|
|
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
|
|
|
|
2014-12-17 03:13:01 +08:00
|
|
|
MaybeStartBackgroudThread();
|
2015-01-07 07:53:32 +08:00
|
|
|
SetSoftRssLimitExceededCallback(AsanSoftRssLimitExceededCallback);
|
2014-12-17 03:13:01 +08:00
|
|
|
|
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.
|
2014-12-06 01:31:13 +08:00
|
|
|
AsanThread *main_thread = AsanThread::Create(
|
|
|
|
/* start_routine */ nullptr, /* arg */ nullptr, /* parent_tid */ 0,
|
|
|
|
/* stack */ nullptr, /* detached */ true);
|
|
|
|
CHECK_EQ(0, main_thread->tid());
|
2013-03-21 19:23:41 +08:00
|
|
|
SetCurrentThread(main_thread);
|
2014-12-05 08:10:15 +08:00
|
|
|
main_thread->ThreadStart(internal_getpid(),
|
|
|
|
/* signal_thread_is_registered */ nullptr);
|
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) {
|
|
|
|
Atexit(__lsan::DoLeakCheck);
|
|
|
|
}
|
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");
|
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);
|
|
|
|
} else {
|
|
|
|
// 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.
|
|
|
|
}
|