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