diff options
Diffstat (limited to 'lib/hwasan/hwasan.cc')
-rw-r--r-- | lib/hwasan/hwasan.cc | 89 |
1 files changed, 65 insertions, 24 deletions
diff --git a/lib/hwasan/hwasan.cc b/lib/hwasan/hwasan.cc index 8b1e5a7846af..7dab8249e3f7 100644 --- a/lib/hwasan/hwasan.cc +++ b/lib/hwasan/hwasan.cc @@ -1,4 +1,4 @@ -//===-- hwasan.cc -----------------------------------------------------------===// +//===-- hwasan.cc ---------------------------------------------------------===// // // The LLVM Compiler Infrastructure // @@ -13,8 +13,10 @@ //===----------------------------------------------------------------------===// #include "hwasan.h" -#include "hwasan_thread.h" +#include "hwasan_mapping.h" #include "hwasan_poisoning.h" +#include "hwasan_report.h" +#include "hwasan_thread.h" #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_flags.h" @@ -84,7 +86,7 @@ static void InitializeFlags() { cf.check_printf = false; cf.intercept_tls_get_addr = true; cf.exitcode = 99; - cf.handle_sigill = kHandleSignalExclusive; + cf.handle_sigtrap = kHandleSignalExclusive; OverrideCommonFlags(cf); } @@ -143,12 +145,22 @@ void PrintWarning(uptr pc, uptr bp) { ReportInvalidAccess(&stack, 0); } +static void HWAsanCheckFailed(const char *file, int line, const char *cond, + u64 v1, u64 v2) { + Report("HWAddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", file, + line, cond, (uptr)v1, (uptr)v2); + PRINT_CURRENT_STACK_CHECK(); + Die(); +} + } // namespace __hwasan // Interface. using namespace __hwasan; +uptr __hwasan_shadow_memory_dynamic_address; // Global interface symbol. + void __hwasan_init() { CHECK(!hwasan_init_is_running); if (hwasan_inited) return; @@ -160,23 +172,28 @@ void __hwasan_init() { CacheBinaryName(); InitializeFlags(); - __sanitizer_set_report_path(common_flags()->log_path); + // Install tool-specific callbacks in sanitizer_common. + SetCheckFailedCallback(HWAsanCheckFailed); - InitializeInterceptors(); - InstallDeadlySignalHandlers(HwasanOnDeadlySignal); - InstallAtExitHandler(); // Needs __cxa_atexit interceptor. + __sanitizer_set_report_path(common_flags()->log_path); DisableCoreDumperIfNecessary(); if (!InitShadow()) { - Printf("FATAL: HWAddressSanitizer can not mmap the shadow memory.\n"); - Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n"); - Printf("FATAL: Disabling ASLR is known to cause this error.\n"); - Printf("FATAL: If running under GDB, try " - "'set disable-randomization off'.\n"); + Printf("FATAL: HWAddressSanitizer cannot mmap the shadow memory.\n"); + if (HWASAN_FIXED_MAPPING) { + Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n"); + Printf("FATAL: Disabling ASLR is known to cause this error.\n"); + Printf("FATAL: If running under GDB, try " + "'set disable-randomization off'.\n"); + } DumpProcessMap(); Die(); } + InitializeInterceptors(); + InstallDeadlySignalHandlers(HwasanOnDeadlySignal); + InstallAtExitHandler(); // Needs __cxa_atexit interceptor. + Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer); InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); @@ -240,11 +257,23 @@ void __sanitizer_unaligned_store64(uu64 *p, u64 x) { template<unsigned X> __attribute__((always_inline)) -static void SigIll() { +static void SigTrap(uptr p) { #if defined(__aarch64__) - asm("hlt %0\n\t" ::"n"(X)); -#elif defined(__x86_64__) || defined(__i386__) - asm("ud2\n\t"); + (void)p; + // 0x900 is added to do not interfere with the kernel use of lower values of + // brk immediate. + // FIXME: Add a constraint to put the pointer into x0, the same as x86 branch. + asm("brk %0\n\t" ::"n"(0x900 + X)); +#elif defined(__x86_64__) + // INT3 + NOP DWORD ptr [EAX + X] to pass X to our signal handler, 5 bytes + // total. The pointer is passed via rdi. + // 0x40 is added as a safeguard, to help distinguish our trap from others and + // to avoid 0 offsets in the command (otherwise it'll be reduced to a + // different nop command, the three bytes one). + asm volatile( + "int3\n" + "nopl %c0(%%rax)\n" + :: "n"(0x40 + X), "D"(p)); #else // FIXME: not always sigill. __builtin_trap(); @@ -261,8 +290,8 @@ __attribute__((always_inline, nodebug)) static void CheckAddress(uptr p) { uptr ptr_raw = p & ~kAddressTagMask; tag_t mem_tag = *(tag_t *)MEM_TO_SHADOW(ptr_raw); if (UNLIKELY(ptr_tag != mem_tag)) { - SigIll<0x100 + 0x20 * (EA == ErrorAction::Recover) + - 0x10 * (AT == AccessType::Store) + LogSize>(); + SigTrap<0x20 * (EA == ErrorAction::Recover) + + 0x10 * (AT == AccessType::Store) + LogSize>(p); if (EA == ErrorAction::Abort) __builtin_unreachable(); } } @@ -277,13 +306,13 @@ __attribute__((always_inline, nodebug)) static void CheckAddressSized(uptr p, tag_t *shadow_last = (tag_t *)MEM_TO_SHADOW(ptr_raw + sz - 1); for (tag_t *t = shadow_first; t <= shadow_last; ++t) if (UNLIKELY(ptr_tag != *t)) { - SigIll<0x100 + 0x20 * (EA == ErrorAction::Recover) + - 0x10 * (AT == AccessType::Store) + 0xf>(); + SigTrap<0x20 * (EA == ErrorAction::Recover) + + 0x10 * (AT == AccessType::Store) + 0xf>(p); if (EA == ErrorAction::Abort) __builtin_unreachable(); } } -void __hwasan_load(uptr p, uptr sz) { +void __hwasan_loadN(uptr p, uptr sz) { CheckAddressSized<ErrorAction::Abort, AccessType::Load>(p, sz); } void __hwasan_load1(uptr p) { @@ -302,7 +331,7 @@ void __hwasan_load16(uptr p) { CheckAddress<ErrorAction::Abort, AccessType::Load, 4>(p); } -void __hwasan_load_noabort(uptr p, uptr sz) { +void __hwasan_loadN_noabort(uptr p, uptr sz) { CheckAddressSized<ErrorAction::Recover, AccessType::Load>(p, sz); } void __hwasan_load1_noabort(uptr p) { @@ -321,7 +350,7 @@ void __hwasan_load16_noabort(uptr p) { CheckAddress<ErrorAction::Recover, AccessType::Load, 4>(p); } -void __hwasan_store(uptr p, uptr sz) { +void __hwasan_storeN(uptr p, uptr sz) { CheckAddressSized<ErrorAction::Abort, AccessType::Store>(p, sz); } void __hwasan_store1(uptr p) { @@ -340,7 +369,7 @@ void __hwasan_store16(uptr p) { CheckAddress<ErrorAction::Abort, AccessType::Store, 4>(p); } -void __hwasan_store_noabort(uptr p, uptr sz) { +void __hwasan_storeN_noabort(uptr p, uptr sz) { CheckAddressSized<ErrorAction::Recover, AccessType::Store>(p, sz); } void __hwasan_store1_noabort(uptr p) { @@ -359,6 +388,18 @@ void __hwasan_store16_noabort(uptr p) { CheckAddress<ErrorAction::Recover, AccessType::Store, 4>(p); } +void __hwasan_tag_memory(uptr p, u8 tag, uptr sz) { + TagMemoryAligned(p, sz, tag); +} + +static const u8 kFallbackTag = 0xBB; + +u8 __hwasan_generate_tag() { + HwasanThread *t = GetCurrentThread(); + if (!t) return kFallbackTag; + return t->GenerateRandomTag(); +} + #if !SANITIZER_SUPPORTS_WEAK_HOOKS extern "C" { SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE |