diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /compiler-rt/lib/hwasan/hwasan.cpp | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'compiler-rt/lib/hwasan/hwasan.cpp')
-rw-r--r-- | compiler-rt/lib/hwasan/hwasan.cpp | 140 |
1 files changed, 24 insertions, 116 deletions
diff --git a/compiler-rt/lib/hwasan/hwasan.cpp b/compiler-rt/lib/hwasan/hwasan.cpp index 7b5c6c694be9..d67a88d455ef 100644 --- a/compiler-rt/lib/hwasan/hwasan.cpp +++ b/compiler-rt/lib/hwasan/hwasan.cpp @@ -12,8 +12,10 @@ //===----------------------------------------------------------------------===// #include "hwasan.h" + #include "hwasan_checks.h" #include "hwasan_dynamic_shadow.h" +#include "hwasan_globals.h" #include "hwasan_poisoning.h" #include "hwasan_report.h" #include "hwasan_thread.h" @@ -36,21 +38,6 @@ using namespace __sanitizer; namespace __hwasan { -void EnterSymbolizer() { - Thread *t = GetCurrentThread(); - CHECK(t); - t->EnterSymbolizer(); -} -void ExitSymbolizer() { - Thread *t = GetCurrentThread(); - CHECK(t); - t->LeaveSymbolizer(); -} -bool IsInSymbolizer() { - Thread *t = GetCurrentThread(); - return t && t->InSymbolizer(); -} - static Flags hwasan_flags; Flags *flags() { @@ -201,108 +188,28 @@ void __sanitizer::BufferedStackTrace::UnwindImpl( uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) { Thread *t = GetCurrentThread(); if (!t) { - // the thread is still being created. + // The thread is still being created, or has already been destroyed. size = 0; return; } - if (!StackTrace::WillUseFastUnwind(request_fast)) { - // Block reports from our interceptors during _Unwind_Backtrace. - SymbolizerScope sym_scope; - return Unwind(max_depth, pc, bp, context, 0, 0, request_fast); - } - if (StackTrace::WillUseFastUnwind(request_fast)) - Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(), true); - else - Unwind(max_depth, pc, 0, context, 0, 0, false); -} - -struct hwasan_global { - s32 gv_relptr; - u32 info; -}; - -static void InitGlobals(const hwasan_global *begin, const hwasan_global *end) { - for (auto *desc = begin; desc != end; ++desc) { - uptr gv = reinterpret_cast<uptr>(desc) + desc->gv_relptr; - uptr size = desc->info & 0xffffff; - uptr full_granule_size = RoundDownTo(size, 16); - u8 tag = desc->info >> 24; - TagMemoryAligned(gv, full_granule_size, tag); - if (size % 16) - TagMemoryAligned(gv + full_granule_size, 16, size % 16); - } + Unwind(max_depth, pc, bp, context, t->stack_top(), t->stack_bottom(), + request_fast); } -enum { NT_LLVM_HWASAN_GLOBALS = 3 }; - -struct hwasan_global_note { - s32 begin_relptr; - s32 end_relptr; -}; - -// Check that the given library meets the code model requirements for tagged -// globals. These properties are not checked at link time so they need to be -// checked at runtime. -static void CheckCodeModel(ElfW(Addr) base, const ElfW(Phdr) * phdr, - ElfW(Half) phnum) { - ElfW(Addr) min_addr = -1ull, max_addr = 0; - for (unsigned i = 0; i != phnum; ++i) { - if (phdr[i].p_type != PT_LOAD) - continue; - ElfW(Addr) lo = base + phdr[i].p_vaddr, hi = lo + phdr[i].p_memsz; - if (min_addr > lo) - min_addr = lo; - if (max_addr < hi) - max_addr = hi; - } - - if (max_addr - min_addr > 1ull << 32) { - Report("FATAL: HWAddressSanitizer: library size exceeds 2^32\n"); - Die(); - } - if (max_addr > 1ull << 48) { - Report("FATAL: HWAddressSanitizer: library loaded above address 2^48\n"); - Die(); - } -} - -static void InitGlobalsFromPhdrs(ElfW(Addr) base, const ElfW(Phdr) * phdr, - ElfW(Half) phnum) { - for (unsigned i = 0; i != phnum; ++i) { - if (phdr[i].p_type != PT_NOTE) - continue; - const char *note = reinterpret_cast<const char *>(base + phdr[i].p_vaddr); - const char *nend = note + phdr[i].p_memsz; - while (note < nend) { - auto *nhdr = reinterpret_cast<const ElfW(Nhdr) *>(note); - const char *name = note + sizeof(ElfW(Nhdr)); - const char *desc = name + RoundUpTo(nhdr->n_namesz, 4); - if (nhdr->n_type != NT_LLVM_HWASAN_GLOBALS || - internal_strcmp(name, "LLVM") != 0) { - note = desc + RoundUpTo(nhdr->n_descsz, 4); - continue; - } - - // Only libraries with instrumented globals need to be checked against the - // code model since they use relocations that aren't checked at link time. - CheckCodeModel(base, phdr, phnum); - - auto *global_note = reinterpret_cast<const hwasan_global_note *>(desc); - auto *global_begin = reinterpret_cast<const hwasan_global *>( - note + global_note->begin_relptr); - auto *global_end = reinterpret_cast<const hwasan_global *>( - note + global_note->end_relptr); - InitGlobals(global_begin, global_end); - return; - } - } +static bool InitializeSingleGlobal(const hwasan_global &global) { + uptr full_granule_size = RoundDownTo(global.size(), 16); + TagMemoryAligned(global.addr(), full_granule_size, global.tag()); + if (global.size() % 16) + TagMemoryAligned(global.addr() + full_granule_size, 16, global.size() % 16); + return false; } static void InitLoadedGlobals() { dl_iterate_phdr( - [](dl_phdr_info *info, size_t size, void *data) { - InitGlobalsFromPhdrs(info->dlpi_addr, info->dlpi_phdr, - info->dlpi_phnum); + [](dl_phdr_info *info, size_t /* size */, void * /* data */) -> int { + for (const hwasan_global &global : HwasanGlobalsFor( + info->dlpi_addr, info->dlpi_phdr, info->dlpi_phnum)) + InitializeSingleGlobal(global); return 0; }, nullptr); @@ -343,11 +250,13 @@ void __hwasan_init_static() { // Fortunately, since this is a statically linked executable we can use the // linker-defined symbol __ehdr_start to find the only relevant set of phdrs. extern ElfW(Ehdr) __ehdr_start; - InitGlobalsFromPhdrs( - 0, - reinterpret_cast<const ElfW(Phdr) *>( - reinterpret_cast<const char *>(&__ehdr_start) + __ehdr_start.e_phoff), - __ehdr_start.e_phnum); + for (const hwasan_global &global : HwasanGlobalsFor( + /* base */ 0, + reinterpret_cast<const ElfW(Phdr) *>( + reinterpret_cast<const char *>(&__ehdr_start) + + __ehdr_start.e_phoff), + __ehdr_start.e_phnum)) + InitializeSingleGlobal(global); } void __hwasan_init() { @@ -387,8 +296,6 @@ void __hwasan_init() { InstallDeadlySignalHandlers(HwasanOnDeadlySignal); InstallAtExitHandler(); // Needs __cxa_atexit interceptor. - Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer); - InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); HwasanTSDInit(); @@ -408,7 +315,8 @@ void __hwasan_init() { void __hwasan_library_loaded(ElfW(Addr) base, const ElfW(Phdr) * phdr, ElfW(Half) phnum) { - InitGlobalsFromPhdrs(base, phdr, phnum); + for (const hwasan_global &global : HwasanGlobalsFor(base, phdr, phnum)) + InitializeSingleGlobal(global); } void __hwasan_library_unloaded(ElfW(Addr) base, const ElfW(Phdr) * phdr, |