Home | History | Annotate | Line # | Download | only in hwasan
      1  1.1  mrg //===-- hwasan.cpp --------------------------------------------------------===//
      2  1.1  mrg //
      3  1.1  mrg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4  1.1  mrg // See https://llvm.org/LICENSE.txt for license information.
      5  1.1  mrg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6  1.1  mrg //
      7  1.1  mrg //===----------------------------------------------------------------------===//
      8  1.1  mrg //
      9  1.1  mrg // This file is a part of HWAddressSanitizer.
     10  1.1  mrg //
     11  1.1  mrg // HWAddressSanitizer runtime.
     12  1.1  mrg //===----------------------------------------------------------------------===//
     13  1.1  mrg 
     14  1.1  mrg #include "hwasan.h"
     15  1.1  mrg 
     16  1.1  mrg #include "hwasan_checks.h"
     17  1.1  mrg #include "hwasan_dynamic_shadow.h"
     18  1.1  mrg #include "hwasan_globals.h"
     19  1.1  mrg #include "hwasan_mapping.h"
     20  1.1  mrg #include "hwasan_poisoning.h"
     21  1.1  mrg #include "hwasan_report.h"
     22  1.1  mrg #include "hwasan_thread.h"
     23  1.1  mrg #include "hwasan_thread_list.h"
     24  1.1  mrg #include "sanitizer_common/sanitizer_atomic.h"
     25  1.1  mrg #include "sanitizer_common/sanitizer_common.h"
     26  1.1  mrg #include "sanitizer_common/sanitizer_flag_parser.h"
     27  1.1  mrg #include "sanitizer_common/sanitizer_flags.h"
     28  1.1  mrg #include "sanitizer_common/sanitizer_libc.h"
     29  1.1  mrg #include "sanitizer_common/sanitizer_procmaps.h"
     30  1.1  mrg #include "sanitizer_common/sanitizer_stackdepot.h"
     31  1.1  mrg #include "sanitizer_common/sanitizer_stacktrace.h"
     32  1.1  mrg #include "sanitizer_common/sanitizer_symbolizer.h"
     33  1.1  mrg #include "ubsan/ubsan_flags.h"
     34  1.1  mrg #include "ubsan/ubsan_init.h"
     35  1.1  mrg 
     36  1.1  mrg // ACHTUNG! No system header includes in this file.
     37  1.1  mrg 
     38  1.1  mrg using namespace __sanitizer;
     39  1.1  mrg 
     40  1.1  mrg namespace __hwasan {
     41  1.1  mrg 
     42  1.1  mrg static Flags hwasan_flags;
     43  1.1  mrg 
     44  1.1  mrg Flags *flags() {
     45  1.1  mrg   return &hwasan_flags;
     46  1.1  mrg }
     47  1.1  mrg 
     48  1.1  mrg int hwasan_inited = 0;
     49  1.1  mrg int hwasan_instrumentation_inited = 0;
     50  1.1  mrg bool hwasan_init_is_running;
     51  1.1  mrg 
     52  1.1  mrg int hwasan_report_count = 0;
     53  1.1  mrg 
     54  1.1  mrg uptr kLowShadowStart;
     55  1.1  mrg uptr kLowShadowEnd;
     56  1.1  mrg uptr kHighShadowStart;
     57  1.1  mrg uptr kHighShadowEnd;
     58  1.1  mrg 
     59  1.1  mrg void Flags::SetDefaults() {
     60  1.1  mrg #define HWASAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
     61  1.1  mrg #include "hwasan_flags.inc"
     62  1.1  mrg #undef HWASAN_FLAG
     63  1.1  mrg }
     64  1.1  mrg 
     65  1.1  mrg static void RegisterHwasanFlags(FlagParser *parser, Flags *f) {
     66  1.1  mrg #define HWASAN_FLAG(Type, Name, DefaultValue, Description) \
     67  1.1  mrg   RegisterFlag(parser, #Name, Description, &f->Name);
     68  1.1  mrg #include "hwasan_flags.inc"
     69  1.1  mrg #undef HWASAN_FLAG
     70  1.1  mrg }
     71  1.1  mrg 
     72  1.1  mrg static void InitializeFlags() {
     73  1.1  mrg   SetCommonFlagsDefaults();
     74  1.1  mrg   {
     75  1.1  mrg     CommonFlags cf;
     76  1.1  mrg     cf.CopyFrom(*common_flags());
     77  1.1  mrg     cf.external_symbolizer_path = GetEnv("HWASAN_SYMBOLIZER_PATH");
     78  1.1  mrg     cf.malloc_context_size = 20;
     79  1.1  mrg     cf.handle_ioctl = true;
     80  1.1  mrg     // FIXME: test and enable.
     81  1.1  mrg     cf.check_printf = false;
     82  1.1  mrg     cf.intercept_tls_get_addr = true;
     83  1.1  mrg     cf.exitcode = 99;
     84  1.1  mrg     // 8 shadow pages ~512kB, small enough to cover common stack sizes.
     85  1.1  mrg     cf.clear_shadow_mmap_threshold = 4096 * (SANITIZER_ANDROID ? 2 : 8);
     86  1.1  mrg     // Sigtrap is used in error reporting.
     87  1.1  mrg     cf.handle_sigtrap = kHandleSignalExclusive;
     88  1.1  mrg 
     89  1.1  mrg #if SANITIZER_ANDROID
     90  1.1  mrg     // Let platform handle other signals. It is better at reporting them then we
     91  1.1  mrg     // are.
     92  1.1  mrg     cf.handle_segv = kHandleSignalNo;
     93  1.1  mrg     cf.handle_sigbus = kHandleSignalNo;
     94  1.1  mrg     cf.handle_abort = kHandleSignalNo;
     95  1.1  mrg     cf.handle_sigill = kHandleSignalNo;
     96  1.1  mrg     cf.handle_sigfpe = kHandleSignalNo;
     97  1.1  mrg #endif
     98  1.1  mrg     OverrideCommonFlags(cf);
     99  1.1  mrg   }
    100  1.1  mrg 
    101  1.1  mrg   Flags *f = flags();
    102  1.1  mrg   f->SetDefaults();
    103  1.1  mrg 
    104  1.1  mrg   FlagParser parser;
    105  1.1  mrg   RegisterHwasanFlags(&parser, f);
    106  1.1  mrg   RegisterCommonFlags(&parser);
    107  1.1  mrg 
    108  1.1  mrg #if HWASAN_CONTAINS_UBSAN
    109  1.1  mrg   __ubsan::Flags *uf = __ubsan::flags();
    110  1.1  mrg   uf->SetDefaults();
    111  1.1  mrg 
    112  1.1  mrg   FlagParser ubsan_parser;
    113  1.1  mrg   __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);
    114  1.1  mrg   RegisterCommonFlags(&ubsan_parser);
    115  1.1  mrg #endif
    116  1.1  mrg 
    117  1.1  mrg   // Override from user-specified string.
    118  1.1  mrg   if (__hwasan_default_options)
    119  1.1  mrg     parser.ParseString(__hwasan_default_options());
    120  1.1  mrg #if HWASAN_CONTAINS_UBSAN
    121  1.1  mrg   const char *ubsan_default_options = __ubsan_default_options();
    122  1.1  mrg   ubsan_parser.ParseString(ubsan_default_options);
    123  1.1  mrg #endif
    124  1.1  mrg 
    125  1.1  mrg   parser.ParseStringFromEnv("HWASAN_OPTIONS");
    126  1.1  mrg #if HWASAN_CONTAINS_UBSAN
    127  1.1  mrg   ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS");
    128  1.1  mrg #endif
    129  1.1  mrg 
    130  1.1  mrg   InitializeCommonFlags();
    131  1.1  mrg 
    132  1.1  mrg   if (Verbosity()) ReportUnrecognizedFlags();
    133  1.1  mrg 
    134  1.1  mrg   if (common_flags()->help) parser.PrintFlagDescriptions();
    135  1.1  mrg }
    136  1.1  mrg 
    137  1.1  mrg static void CheckUnwind() {
    138  1.1  mrg   GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME());
    139  1.1  mrg   stack.Print();
    140  1.1  mrg }
    141  1.1  mrg 
    142  1.1  mrg static void HwasanFormatMemoryUsage(InternalScopedString &s) {
    143  1.1  mrg   HwasanThreadList &thread_list = hwasanThreadList();
    144  1.1  mrg   auto thread_stats = thread_list.GetThreadStats();
    145  1.1  mrg   auto sds = StackDepotGetStats();
    146  1.1  mrg   AllocatorStatCounters asc;
    147  1.1  mrg   GetAllocatorStats(asc);
    148  1.1  mrg   s.append(
    149  1.1  mrg       "HWASAN pid: %d rss: %zd threads: %zd stacks: %zd"
    150  1.1  mrg       " thr_aux: %zd stack_depot: %zd uniq_stacks: %zd"
    151  1.1  mrg       " heap: %zd",
    152  1.1  mrg       internal_getpid(), GetRSS(), thread_stats.n_live_threads,
    153  1.1  mrg       thread_stats.total_stack_size,
    154  1.1  mrg       thread_stats.n_live_threads * thread_list.MemoryUsedPerThread(),
    155  1.1  mrg       sds.allocated, sds.n_uniq_ids, asc[AllocatorStatMapped]);
    156  1.1  mrg }
    157  1.1  mrg 
    158  1.1  mrg #if SANITIZER_ANDROID
    159  1.1  mrg static constexpr uptr kMemoryUsageBufferSize = 4096;
    160  1.1  mrg 
    161  1.1  mrg static char *memory_usage_buffer = nullptr;
    162  1.1  mrg 
    163  1.1  mrg static void InitMemoryUsage() {
    164  1.1  mrg   memory_usage_buffer =
    165  1.1  mrg       (char *)MmapOrDie(kMemoryUsageBufferSize, "memory usage string");
    166  1.1  mrg   CHECK(memory_usage_buffer);
    167  1.1  mrg   memory_usage_buffer[0] = '\0';
    168  1.1  mrg   DecorateMapping((uptr)memory_usage_buffer, kMemoryUsageBufferSize,
    169  1.1  mrg                   memory_usage_buffer);
    170  1.1  mrg }
    171  1.1  mrg 
    172  1.1  mrg void UpdateMemoryUsage() {
    173  1.1  mrg   if (!flags()->export_memory_stats)
    174  1.1  mrg     return;
    175  1.1  mrg   if (!memory_usage_buffer)
    176  1.1  mrg     InitMemoryUsage();
    177  1.1  mrg   InternalScopedString s;
    178  1.1  mrg   HwasanFormatMemoryUsage(s);
    179  1.1  mrg   internal_strncpy(memory_usage_buffer, s.data(), kMemoryUsageBufferSize - 1);
    180  1.1  mrg   memory_usage_buffer[kMemoryUsageBufferSize - 1] = '\0';
    181  1.1  mrg }
    182  1.1  mrg #else
    183  1.1  mrg void UpdateMemoryUsage() {}
    184  1.1  mrg #endif
    185  1.1  mrg 
    186  1.1  mrg void HwasanAtExit() {
    187  1.1  mrg   if (common_flags()->print_module_map)
    188  1.1  mrg     DumpProcessMap();
    189  1.1  mrg   if (flags()->print_stats && (flags()->atexit || hwasan_report_count > 0))
    190  1.1  mrg     ReportStats();
    191  1.1  mrg   if (hwasan_report_count > 0) {
    192  1.1  mrg     // ReportAtExitStatistics();
    193  1.1  mrg     if (common_flags()->exitcode)
    194  1.1  mrg       internal__exit(common_flags()->exitcode);
    195  1.1  mrg   }
    196  1.1  mrg }
    197  1.1  mrg 
    198  1.1  mrg void HandleTagMismatch(AccessInfo ai, uptr pc, uptr frame, void *uc,
    199  1.1  mrg                        uptr *registers_frame) {
    200  1.1  mrg   InternalMmapVector<BufferedStackTrace> stack_buffer(1);
    201  1.1  mrg   BufferedStackTrace *stack = stack_buffer.data();
    202  1.1  mrg   stack->Reset();
    203  1.1  mrg   stack->Unwind(pc, frame, uc, common_flags()->fast_unwind_on_fatal);
    204  1.1  mrg 
    205  1.1  mrg   // The second stack frame contains the failure __hwasan_check function, as
    206  1.1  mrg   // we have a stack frame for the registers saved in __hwasan_tag_mismatch that
    207  1.1  mrg   // we wish to ignore. This (currently) only occurs on AArch64, as x64
    208  1.1  mrg   // implementations use SIGTRAP to implement the failure, and thus do not go
    209  1.1  mrg   // through the stack saver.
    210  1.1  mrg   if (registers_frame && stack->trace && stack->size > 0) {
    211  1.1  mrg     stack->trace++;
    212  1.1  mrg     stack->size--;
    213  1.1  mrg   }
    214  1.1  mrg 
    215  1.1  mrg   bool fatal = flags()->halt_on_error || !ai.recover;
    216  1.1  mrg   ReportTagMismatch(stack, ai.addr, ai.size, ai.is_store, fatal,
    217  1.1  mrg                     registers_frame);
    218  1.1  mrg }
    219  1.1  mrg 
    220  1.1  mrg void HwasanTagMismatch(uptr addr, uptr access_info, uptr *registers_frame,
    221  1.1  mrg                        size_t outsize) {
    222  1.1  mrg   __hwasan::AccessInfo ai;
    223  1.1  mrg   ai.is_store = access_info & 0x10;
    224  1.1  mrg   ai.is_load = !ai.is_store;
    225  1.1  mrg   ai.recover = access_info & 0x20;
    226  1.1  mrg   ai.addr = addr;
    227  1.1  mrg   if ((access_info & 0xf) == 0xf)
    228  1.1  mrg     ai.size = outsize;
    229  1.1  mrg   else
    230  1.1  mrg     ai.size = 1 << (access_info & 0xf);
    231  1.1  mrg 
    232  1.1  mrg   HandleTagMismatch(ai, (uptr)__builtin_return_address(0),
    233  1.1  mrg                     (uptr)__builtin_frame_address(0), nullptr, registers_frame);
    234  1.1  mrg   __builtin_unreachable();
    235  1.1  mrg }
    236  1.1  mrg 
    237  1.1  mrg Thread *GetCurrentThread() {
    238  1.1  mrg   uptr *ThreadLongPtr = GetCurrentThreadLongPtr();
    239  1.1  mrg   if (UNLIKELY(*ThreadLongPtr == 0))
    240  1.1  mrg     return nullptr;
    241  1.1  mrg   auto *R = (StackAllocationsRingBuffer *)ThreadLongPtr;
    242  1.1  mrg   return hwasanThreadList().GetThreadByBufferAddress((uptr)R->Next());
    243  1.1  mrg }
    244  1.1  mrg 
    245  1.1  mrg } // namespace __hwasan
    246  1.1  mrg 
    247  1.1  mrg using namespace __hwasan;
    248  1.1  mrg 
    249  1.1  mrg void __sanitizer::BufferedStackTrace::UnwindImpl(
    250  1.1  mrg     uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
    251  1.1  mrg   Thread *t = GetCurrentThread();
    252  1.1  mrg   if (!t) {
    253  1.1  mrg     // The thread is still being created, or has already been destroyed.
    254  1.1  mrg     size = 0;
    255  1.1  mrg     return;
    256  1.1  mrg   }
    257  1.1  mrg   Unwind(max_depth, pc, bp, context, t->stack_top(), t->stack_bottom(),
    258  1.1  mrg          request_fast);
    259  1.1  mrg }
    260  1.1  mrg 
    261  1.1  mrg static bool InitializeSingleGlobal(const hwasan_global &global) {
    262  1.1  mrg   uptr full_granule_size = RoundDownTo(global.size(), 16);
    263  1.1  mrg   TagMemoryAligned(global.addr(), full_granule_size, global.tag());
    264  1.1  mrg   if (global.size() % 16)
    265  1.1  mrg     TagMemoryAligned(global.addr() + full_granule_size, 16, global.size() % 16);
    266  1.1  mrg   return false;
    267  1.1  mrg }
    268  1.1  mrg 
    269  1.1  mrg static void InitLoadedGlobals() {
    270  1.1  mrg   dl_iterate_phdr(
    271  1.1  mrg       [](dl_phdr_info *info, size_t /* size */, void * /* data */) -> int {
    272  1.1  mrg         for (const hwasan_global &global : HwasanGlobalsFor(
    273  1.1  mrg                  info->dlpi_addr, info->dlpi_phdr, info->dlpi_phnum))
    274  1.1  mrg           InitializeSingleGlobal(global);
    275  1.1  mrg         return 0;
    276  1.1  mrg       },
    277  1.1  mrg       nullptr);
    278  1.1  mrg }
    279  1.1  mrg 
    280  1.1  mrg // Prepare to run instrumented code on the main thread.
    281  1.1  mrg static void InitInstrumentation() {
    282  1.1  mrg   if (hwasan_instrumentation_inited) return;
    283  1.1  mrg 
    284  1.1  mrg   InitializeOsSupport();
    285  1.1  mrg 
    286  1.1  mrg   if (!InitShadow()) {
    287  1.1  mrg     Printf("FATAL: HWAddressSanitizer cannot mmap the shadow memory.\n");
    288  1.1  mrg     DumpProcessMap();
    289  1.1  mrg     Die();
    290  1.1  mrg   }
    291  1.1  mrg 
    292  1.1  mrg   InitThreads();
    293  1.1  mrg 
    294  1.1  mrg   hwasan_instrumentation_inited = 1;
    295  1.1  mrg }
    296  1.1  mrg 
    297  1.1  mrg // Interface.
    298  1.1  mrg 
    299  1.1  mrg uptr __hwasan_shadow_memory_dynamic_address;  // Global interface symbol.
    300  1.1  mrg 
    301  1.1  mrg // This function was used by the old frame descriptor mechanism. We keep it
    302  1.1  mrg // around to avoid breaking ABI.
    303  1.1  mrg void __hwasan_init_frames(uptr beg, uptr end) {}
    304  1.1  mrg 
    305  1.1  mrg void __hwasan_init_static() {
    306  1.1  mrg   InitShadowGOT();
    307  1.1  mrg   InitInstrumentation();
    308  1.1  mrg 
    309  1.1  mrg   // In the non-static code path we call dl_iterate_phdr here. But at this point
    310  1.1  mrg   // libc might not have been initialized enough for dl_iterate_phdr to work.
    311  1.1  mrg   // Fortunately, since this is a statically linked executable we can use the
    312  1.1  mrg   // linker-defined symbol __ehdr_start to find the only relevant set of phdrs.
    313  1.1  mrg   extern ElfW(Ehdr) __ehdr_start;
    314  1.1  mrg   for (const hwasan_global &global : HwasanGlobalsFor(
    315  1.1  mrg            /* base */ 0,
    316  1.1  mrg            reinterpret_cast<const ElfW(Phdr) *>(
    317  1.1  mrg                reinterpret_cast<const char *>(&__ehdr_start) +
    318  1.1  mrg                __ehdr_start.e_phoff),
    319  1.1  mrg            __ehdr_start.e_phnum))
    320  1.1  mrg     InitializeSingleGlobal(global);
    321  1.1  mrg }
    322  1.1  mrg 
    323  1.1  mrg __attribute__((constructor(0))) void __hwasan_init() {
    324  1.1  mrg   CHECK(!hwasan_init_is_running);
    325  1.1  mrg   if (hwasan_inited) return;
    326  1.1  mrg   hwasan_init_is_running = 1;
    327  1.1  mrg   SanitizerToolName = "HWAddressSanitizer";
    328  1.1  mrg 
    329  1.1  mrg   InitTlsSize();
    330  1.1  mrg 
    331  1.1  mrg   CacheBinaryName();
    332  1.1  mrg   InitializeFlags();
    333  1.1  mrg 
    334  1.1  mrg   // Install tool-specific callbacks in sanitizer_common.
    335  1.1  mrg   SetCheckUnwindCallback(CheckUnwind);
    336  1.1  mrg 
    337  1.1  mrg   __sanitizer_set_report_path(common_flags()->log_path);
    338  1.1  mrg 
    339  1.1  mrg   AndroidTestTlsSlot();
    340  1.1  mrg 
    341  1.1  mrg   DisableCoreDumperIfNecessary();
    342  1.1  mrg 
    343  1.1  mrg   InitInstrumentation();
    344  1.1  mrg   InitLoadedGlobals();
    345  1.1  mrg 
    346  1.1  mrg   // Needs to be called here because flags()->random_tags might not have been
    347  1.1  mrg   // initialized when InitInstrumentation() was called.
    348  1.1  mrg   GetCurrentThread()->EnsureRandomStateInited();
    349  1.1  mrg 
    350  1.1  mrg   SetPrintfAndReportCallback(AppendToErrorMessageBuffer);
    351  1.1  mrg   // This may call libc -> needs initialized shadow.
    352  1.1  mrg   AndroidLogInit();
    353  1.1  mrg 
    354  1.1  mrg   InitializeInterceptors();
    355  1.1  mrg   InstallDeadlySignalHandlers(HwasanOnDeadlySignal);
    356  1.1  mrg   InstallAtExitHandler(); // Needs __cxa_atexit interceptor.
    357  1.1  mrg 
    358  1.1  mrg   InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
    359  1.1  mrg 
    360  1.1  mrg   HwasanTSDInit();
    361  1.1  mrg   HwasanTSDThreadInit();
    362  1.1  mrg 
    363  1.1  mrg   HwasanAllocatorInit();
    364  1.1  mrg   HwasanInstallAtForkHandler();
    365  1.1  mrg 
    366  1.1  mrg #if HWASAN_CONTAINS_UBSAN
    367  1.1  mrg   __ubsan::InitAsPlugin();
    368  1.1  mrg #endif
    369  1.1  mrg 
    370  1.1  mrg   VPrintf(1, "HWAddressSanitizer init done\n");
    371  1.1  mrg 
    372  1.1  mrg   hwasan_init_is_running = 0;
    373  1.1  mrg   hwasan_inited = 1;
    374  1.1  mrg }
    375  1.1  mrg 
    376  1.1  mrg void __hwasan_library_loaded(ElfW(Addr) base, const ElfW(Phdr) * phdr,
    377  1.1  mrg                              ElfW(Half) phnum) {
    378  1.1  mrg   for (const hwasan_global &global : HwasanGlobalsFor(base, phdr, phnum))
    379  1.1  mrg     InitializeSingleGlobal(global);
    380  1.1  mrg }
    381  1.1  mrg 
    382  1.1  mrg void __hwasan_library_unloaded(ElfW(Addr) base, const ElfW(Phdr) * phdr,
    383  1.1  mrg                                ElfW(Half) phnum) {
    384  1.1  mrg   for (; phnum != 0; ++phdr, --phnum)
    385  1.1  mrg     if (phdr->p_type == PT_LOAD)
    386  1.1  mrg       TagMemory(base + phdr->p_vaddr, phdr->p_memsz, 0);
    387  1.1  mrg }
    388  1.1  mrg 
    389  1.1  mrg void __hwasan_print_shadow(const void *p, uptr sz) {
    390  1.1  mrg   uptr ptr_raw = UntagAddr(reinterpret_cast<uptr>(p));
    391  1.1  mrg   uptr shadow_first = MemToShadow(ptr_raw);
    392  1.1  mrg   uptr shadow_last = MemToShadow(ptr_raw + sz - 1);
    393  1.1  mrg   Printf("HWASan shadow map for %zx .. %zx (pointer tag %x)\n", ptr_raw,
    394  1.1  mrg          ptr_raw + sz, GetTagFromPointer((uptr)p));
    395  1.1  mrg   for (uptr s = shadow_first; s <= shadow_last; ++s) {
    396  1.1  mrg     tag_t mem_tag = *reinterpret_cast<tag_t *>(s);
    397  1.1  mrg     uptr granule_addr = ShadowToMem(s);
    398  1.1  mrg     if (mem_tag && mem_tag < kShadowAlignment)
    399  1.1  mrg       Printf("  %zx: %02x(%02x)\n", granule_addr, mem_tag,
    400  1.1  mrg              *reinterpret_cast<tag_t *>(granule_addr + kShadowAlignment - 1));
    401  1.1  mrg     else
    402  1.1  mrg       Printf("  %zx: %02x\n", granule_addr, mem_tag);
    403  1.1  mrg   }
    404  1.1  mrg }
    405  1.1  mrg 
    406  1.1  mrg sptr __hwasan_test_shadow(const void *p, uptr sz) {
    407  1.1  mrg   if (sz == 0)
    408  1.1  mrg     return -1;
    409  1.1  mrg   tag_t ptr_tag = GetTagFromPointer((uptr)p);
    410  1.1  mrg   uptr ptr_raw = UntagAddr(reinterpret_cast<uptr>(p));
    411  1.1  mrg   uptr shadow_first = MemToShadow(ptr_raw);
    412  1.1  mrg   uptr shadow_last = MemToShadow(ptr_raw + sz - 1);
    413  1.1  mrg   for (uptr s = shadow_first; s <= shadow_last; ++s)
    414  1.1  mrg     if (*(tag_t *)s != ptr_tag) {
    415  1.1  mrg       sptr offset = ShadowToMem(s) - ptr_raw;
    416  1.1  mrg       return offset < 0 ? 0 : offset;
    417  1.1  mrg     }
    418  1.1  mrg   return -1;
    419  1.1  mrg }
    420  1.1  mrg 
    421  1.1  mrg u16 __sanitizer_unaligned_load16(const uu16 *p) {
    422  1.1  mrg   return *p;
    423  1.1  mrg }
    424  1.1  mrg u32 __sanitizer_unaligned_load32(const uu32 *p) {
    425  1.1  mrg   return *p;
    426  1.1  mrg }
    427  1.1  mrg u64 __sanitizer_unaligned_load64(const uu64 *p) {
    428  1.1  mrg   return *p;
    429  1.1  mrg }
    430  1.1  mrg void __sanitizer_unaligned_store16(uu16 *p, u16 x) {
    431  1.1  mrg   *p = x;
    432  1.1  mrg }
    433  1.1  mrg void __sanitizer_unaligned_store32(uu32 *p, u32 x) {
    434  1.1  mrg   *p = x;
    435  1.1  mrg }
    436  1.1  mrg void __sanitizer_unaligned_store64(uu64 *p, u64 x) {
    437  1.1  mrg   *p = x;
    438  1.1  mrg }
    439  1.1  mrg 
    440  1.1  mrg void __hwasan_loadN(uptr p, uptr sz) {
    441  1.1  mrg   CheckAddressSized<ErrorAction::Abort, AccessType::Load>(p, sz);
    442  1.1  mrg }
    443  1.1  mrg void __hwasan_load1(uptr p) {
    444  1.1  mrg   CheckAddress<ErrorAction::Abort, AccessType::Load, 0>(p);
    445  1.1  mrg }
    446  1.1  mrg void __hwasan_load2(uptr p) {
    447  1.1  mrg   CheckAddress<ErrorAction::Abort, AccessType::Load, 1>(p);
    448  1.1  mrg }
    449  1.1  mrg void __hwasan_load4(uptr p) {
    450  1.1  mrg   CheckAddress<ErrorAction::Abort, AccessType::Load, 2>(p);
    451  1.1  mrg }
    452  1.1  mrg void __hwasan_load8(uptr p) {
    453  1.1  mrg   CheckAddress<ErrorAction::Abort, AccessType::Load, 3>(p);
    454  1.1  mrg }
    455  1.1  mrg void __hwasan_load16(uptr p) {
    456  1.1  mrg   CheckAddress<ErrorAction::Abort, AccessType::Load, 4>(p);
    457  1.1  mrg }
    458  1.1  mrg 
    459  1.1  mrg void __hwasan_loadN_noabort(uptr p, uptr sz) {
    460  1.1  mrg   CheckAddressSized<ErrorAction::Recover, AccessType::Load>(p, sz);
    461  1.1  mrg }
    462  1.1  mrg void __hwasan_load1_noabort(uptr p) {
    463  1.1  mrg   CheckAddress<ErrorAction::Recover, AccessType::Load, 0>(p);
    464  1.1  mrg }
    465  1.1  mrg void __hwasan_load2_noabort(uptr p) {
    466  1.1  mrg   CheckAddress<ErrorAction::Recover, AccessType::Load, 1>(p);
    467  1.1  mrg }
    468  1.1  mrg void __hwasan_load4_noabort(uptr p) {
    469  1.1  mrg   CheckAddress<ErrorAction::Recover, AccessType::Load, 2>(p);
    470  1.1  mrg }
    471  1.1  mrg void __hwasan_load8_noabort(uptr p) {
    472  1.1  mrg   CheckAddress<ErrorAction::Recover, AccessType::Load, 3>(p);
    473  1.1  mrg }
    474  1.1  mrg void __hwasan_load16_noabort(uptr p) {
    475  1.1  mrg   CheckAddress<ErrorAction::Recover, AccessType::Load, 4>(p);
    476  1.1  mrg }
    477  1.1  mrg 
    478  1.1  mrg void __hwasan_storeN(uptr p, uptr sz) {
    479  1.1  mrg   CheckAddressSized<ErrorAction::Abort, AccessType::Store>(p, sz);
    480  1.1  mrg }
    481  1.1  mrg void __hwasan_store1(uptr p) {
    482  1.1  mrg   CheckAddress<ErrorAction::Abort, AccessType::Store, 0>(p);
    483  1.1  mrg }
    484  1.1  mrg void __hwasan_store2(uptr p) {
    485  1.1  mrg   CheckAddress<ErrorAction::Abort, AccessType::Store, 1>(p);
    486  1.1  mrg }
    487  1.1  mrg void __hwasan_store4(uptr p) {
    488  1.1  mrg   CheckAddress<ErrorAction::Abort, AccessType::Store, 2>(p);
    489  1.1  mrg }
    490  1.1  mrg void __hwasan_store8(uptr p) {
    491  1.1  mrg   CheckAddress<ErrorAction::Abort, AccessType::Store, 3>(p);
    492  1.1  mrg }
    493  1.1  mrg void __hwasan_store16(uptr p) {
    494  1.1  mrg   CheckAddress<ErrorAction::Abort, AccessType::Store, 4>(p);
    495  1.1  mrg }
    496  1.1  mrg 
    497  1.1  mrg void __hwasan_storeN_noabort(uptr p, uptr sz) {
    498  1.1  mrg   CheckAddressSized<ErrorAction::Recover, AccessType::Store>(p, sz);
    499  1.1  mrg }
    500  1.1  mrg void __hwasan_store1_noabort(uptr p) {
    501  1.1  mrg   CheckAddress<ErrorAction::Recover, AccessType::Store, 0>(p);
    502  1.1  mrg }
    503  1.1  mrg void __hwasan_store2_noabort(uptr p) {
    504  1.1  mrg   CheckAddress<ErrorAction::Recover, AccessType::Store, 1>(p);
    505  1.1  mrg }
    506  1.1  mrg void __hwasan_store4_noabort(uptr p) {
    507  1.1  mrg   CheckAddress<ErrorAction::Recover, AccessType::Store, 2>(p);
    508  1.1  mrg }
    509  1.1  mrg void __hwasan_store8_noabort(uptr p) {
    510  1.1  mrg   CheckAddress<ErrorAction::Recover, AccessType::Store, 3>(p);
    511  1.1  mrg }
    512  1.1  mrg void __hwasan_store16_noabort(uptr p) {
    513  1.1  mrg   CheckAddress<ErrorAction::Recover, AccessType::Store, 4>(p);
    514  1.1  mrg }
    515  1.1  mrg 
    516  1.1  mrg void __hwasan_tag_memory(uptr p, u8 tag, uptr sz) {
    517  1.1  mrg   TagMemoryAligned(p, sz, tag);
    518  1.1  mrg }
    519  1.1  mrg 
    520  1.1  mrg uptr __hwasan_tag_pointer(uptr p, u8 tag) {
    521  1.1  mrg   return AddTagToPointer(p, tag);
    522  1.1  mrg }
    523  1.1  mrg 
    524  1.1  mrg void __hwasan_handle_longjmp(const void *sp_dst) {
    525  1.1  mrg   uptr dst = (uptr)sp_dst;
    526  1.1  mrg   // HWASan does not support tagged SP.
    527  1.1  mrg   CHECK(GetTagFromPointer(dst) == 0);
    528  1.1  mrg 
    529  1.1  mrg   uptr sp = (uptr)__builtin_frame_address(0);
    530  1.1  mrg   static const uptr kMaxExpectedCleanupSize = 64 << 20;  // 64M
    531  1.1  mrg   if (dst < sp || dst - sp > kMaxExpectedCleanupSize) {
    532  1.1  mrg     Report(
    533  1.1  mrg         "WARNING: HWASan is ignoring requested __hwasan_handle_longjmp: "
    534  1.1  mrg         "stack top: %p; target %p; distance: %p (%zd)\n"
    535  1.1  mrg         "False positive error reports may follow\n",
    536  1.1  mrg         (void *)sp, (void *)dst, dst - sp);
    537  1.1  mrg     return;
    538  1.1  mrg   }
    539  1.1  mrg   TagMemory(sp, dst - sp, 0);
    540  1.1  mrg }
    541  1.1  mrg 
    542  1.1  mrg void __hwasan_handle_vfork(const void *sp_dst) {
    543  1.1  mrg   uptr sp = (uptr)sp_dst;
    544  1.1  mrg   Thread *t = GetCurrentThread();
    545  1.1  mrg   CHECK(t);
    546  1.1  mrg   uptr top = t->stack_top();
    547  1.1  mrg   uptr bottom = t->stack_bottom();
    548  1.1  mrg   if (top == 0 || bottom == 0 || sp < bottom || sp >= top) {
    549  1.1  mrg     Report(
    550  1.1  mrg         "WARNING: HWASan is ignoring requested __hwasan_handle_vfork: "
    551  1.1  mrg         "stack top: %zx; current %zx; bottom: %zx \n"
    552  1.1  mrg         "False positive error reports may follow\n",
    553  1.1  mrg         top, sp, bottom);
    554  1.1  mrg     return;
    555  1.1  mrg   }
    556  1.1  mrg   TagMemory(bottom, sp - bottom, 0);
    557  1.1  mrg }
    558  1.1  mrg 
    559  1.1  mrg extern "C" void *__hwasan_extra_spill_area() {
    560  1.1  mrg   Thread *t = GetCurrentThread();
    561  1.1  mrg   return &t->vfork_spill();
    562  1.1  mrg }
    563  1.1  mrg 
    564  1.1  mrg void __hwasan_print_memory_usage() {
    565  1.1  mrg   InternalScopedString s;
    566  1.1  mrg   HwasanFormatMemoryUsage(s);
    567  1.1  mrg   Printf("%s\n", s.data());
    568  1.1  mrg }
    569  1.1  mrg 
    570  1.1  mrg static const u8 kFallbackTag = 0xBB & kTagMask;
    571  1.1  mrg 
    572  1.1  mrg u8 __hwasan_generate_tag() {
    573  1.1  mrg   Thread *t = GetCurrentThread();
    574  1.1  mrg   if (!t) return kFallbackTag;
    575  1.1  mrg   return t->GenerateRandomTag();
    576  1.1  mrg }
    577  1.1  mrg 
    578  1.1  mrg #if !SANITIZER_SUPPORTS_WEAK_HOOKS
    579  1.1  mrg extern "C" {
    580  1.1  mrg SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
    581  1.1  mrg const char* __hwasan_default_options() { return ""; }
    582  1.1  mrg }  // extern "C"
    583  1.1  mrg #endif
    584  1.1  mrg 
    585  1.1  mrg extern "C" {
    586  1.1  mrg SANITIZER_INTERFACE_ATTRIBUTE
    587  1.1  mrg void __sanitizer_print_stack_trace() {
    588  1.1  mrg   GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME());
    589  1.1  mrg   stack.Print();
    590  1.1  mrg }
    591  1.1  mrg 
    592  1.1  mrg // Entry point for interoperability between __hwasan_tag_mismatch (ASM) and the
    593  1.1  mrg // rest of the mismatch handling code (C++).
    594  1.1  mrg void __hwasan_tag_mismatch4(uptr addr, uptr access_info, uptr *registers_frame,
    595  1.1  mrg                             size_t outsize) {
    596  1.1  mrg   __hwasan::HwasanTagMismatch(addr, access_info, registers_frame, outsize);
    597  1.1  mrg }
    598  1.1  mrg 
    599  1.1  mrg } // extern "C"
    600