160c66db4SNico Weber //===-- msan.cpp ----------------------------------------------------------===// 260c66db4SNico Weber // 360c66db4SNico Weber // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 460c66db4SNico Weber // See https://llvm.org/LICENSE.txt for license information. 560c66db4SNico Weber // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 660c66db4SNico Weber // 760c66db4SNico Weber //===----------------------------------------------------------------------===// 860c66db4SNico Weber // 960c66db4SNico Weber // This file is a part of MemorySanitizer. 1060c66db4SNico Weber // 1160c66db4SNico Weber // MemorySanitizer runtime. 1260c66db4SNico Weber //===----------------------------------------------------------------------===// 1360c66db4SNico Weber 1460c66db4SNico Weber #include "msan.h" 15595d340dSDmitry Vyukov 1660c66db4SNico Weber #include "msan_chained_origin_depot.h" 1760c66db4SNico Weber #include "msan_origin.h" 18595d340dSDmitry Vyukov #include "msan_poisoning.h" 1960c66db4SNico Weber #include "msan_report.h" 2060c66db4SNico Weber #include "msan_thread.h" 2160c66db4SNico Weber #include "sanitizer_common/sanitizer_atomic.h" 2260c66db4SNico Weber #include "sanitizer_common/sanitizer_common.h" 2360c66db4SNico Weber #include "sanitizer_common/sanitizer_flag_parser.h" 24595d340dSDmitry Vyukov #include "sanitizer_common/sanitizer_flags.h" 25595d340dSDmitry Vyukov #include "sanitizer_common/sanitizer_interface_internal.h" 2660c66db4SNico Weber #include "sanitizer_common/sanitizer_libc.h" 2760c66db4SNico Weber #include "sanitizer_common/sanitizer_procmaps.h" 28595d340dSDmitry Vyukov #include "sanitizer_common/sanitizer_stackdepot.h" 2960c66db4SNico Weber #include "sanitizer_common/sanitizer_stacktrace.h" 3060c66db4SNico Weber #include "sanitizer_common/sanitizer_symbolizer.h" 3160c66db4SNico Weber #include "ubsan/ubsan_flags.h" 3260c66db4SNico Weber #include "ubsan/ubsan_init.h" 3360c66db4SNico Weber 3460c66db4SNico Weber // ACHTUNG! No system header includes in this file. 3560c66db4SNico Weber 3660c66db4SNico Weber using namespace __sanitizer; 3760c66db4SNico Weber 3860c66db4SNico Weber // Globals. 3960c66db4SNico Weber static THREADLOCAL int msan_expect_umr = 0; 4060c66db4SNico Weber static THREADLOCAL int msan_expected_umr_found = 0; 4160c66db4SNico Weber 4260c66db4SNico Weber // Function argument shadow. Each argument starts at the next available 8-byte 4360c66db4SNico Weber // aligned address. 4460c66db4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE 4560c66db4SNico Weber THREADLOCAL u64 __msan_param_tls[kMsanParamTlsSize / sizeof(u64)]; 4660c66db4SNico Weber 4760c66db4SNico Weber // Function argument origin. Each argument starts at the same offset as the 4860c66db4SNico Weber // corresponding shadow in (__msan_param_tls). Slightly weird, but changing this 4960c66db4SNico Weber // would break compatibility with older prebuilt binaries. 5060c66db4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE 5160c66db4SNico Weber THREADLOCAL u32 __msan_param_origin_tls[kMsanParamTlsSize / sizeof(u32)]; 5260c66db4SNico Weber 5360c66db4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE 5460c66db4SNico Weber THREADLOCAL u64 __msan_retval_tls[kMsanRetvalTlsSize / sizeof(u64)]; 5560c66db4SNico Weber 5660c66db4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE 5760c66db4SNico Weber THREADLOCAL u32 __msan_retval_origin_tls; 5860c66db4SNico Weber 59ba66d60bSFangrui Song alignas(16) SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u64 60ba66d60bSFangrui Song __msan_va_arg_tls[kMsanParamTlsSize / sizeof(u64)]; 6160c66db4SNico Weber 62ba66d60bSFangrui Song alignas(16) SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL u32 63ba66d60bSFangrui Song __msan_va_arg_origin_tls[kMsanParamTlsSize / sizeof(u32)]; 6460c66db4SNico Weber 6560c66db4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE 6660c66db4SNico Weber THREADLOCAL u64 __msan_va_arg_overflow_size_tls; 6760c66db4SNico Weber 6860c66db4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE 6960c66db4SNico Weber THREADLOCAL u32 __msan_origin_tls; 7060c66db4SNico Weber 7160c66db4SNico Weber extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_track_origins; 7260c66db4SNico Weber 7360c66db4SNico Weber int __msan_get_track_origins() { 7460c66db4SNico Weber return &__msan_track_origins ? __msan_track_origins : 0; 7560c66db4SNico Weber } 7660c66db4SNico Weber 7760c66db4SNico Weber extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_keep_going; 7860c66db4SNico Weber 7960c66db4SNico Weber namespace __msan { 8060c66db4SNico Weber 8147a9528fSVitaly Buka static THREADLOCAL int is_in_symbolizer_or_unwinder; 8247a9528fSVitaly Buka static void EnterSymbolizerOrUnwider() { ++is_in_symbolizer_or_unwinder; } 8347a9528fSVitaly Buka static void ExitSymbolizerOrUnwider() { --is_in_symbolizer_or_unwinder; } 8447a9528fSVitaly Buka bool IsInSymbolizerOrUnwider() { return is_in_symbolizer_or_unwinder; } 8547a9528fSVitaly Buka 8647a9528fSVitaly Buka struct UnwinderScope { 8747a9528fSVitaly Buka UnwinderScope() { EnterSymbolizerOrUnwider(); } 8847a9528fSVitaly Buka ~UnwinderScope() { ExitSymbolizerOrUnwider(); } 8947a9528fSVitaly Buka }; 9060c66db4SNico Weber 9160c66db4SNico Weber static Flags msan_flags; 9260c66db4SNico Weber 9347a9528fSVitaly Buka Flags *flags() { return &msan_flags; } 9460c66db4SNico Weber 9560c66db4SNico Weber int msan_inited = 0; 9660c66db4SNico Weber bool msan_init_is_running; 9760c66db4SNico Weber 9860c66db4SNico Weber int msan_report_count = 0; 9960c66db4SNico Weber 10060c66db4SNico Weber // Array of stack origins. 10160c66db4SNico Weber // FIXME: make it resizable. 1020e96eebcSThurston Dang // Although BSS memory doesn't cost anything until used, it is limited to 2GB 1030e96eebcSThurston Dang // in some configurations (e.g., "relocation R_X86_64_PC32 out of range: 1040e96eebcSThurston Dang // ... is not in [-2147483648, 2147483647]; references section '.bss'"). 1050e96eebcSThurston Dang // We use kNumStackOriginDescrs * (sizeof(char*) + sizeof(uptr)) == 64MB. 10662c61aa2SThurston Dang #if SANITIZER_PPC 1070e96eebcSThurston Dang // soft_rss_limit test (release_origin.c) fails on PPC if kNumStackOriginDescrs 1080e96eebcSThurston Dang // is too high 1090e96eebcSThurston Dang static const uptr kNumStackOriginDescrs = 1 * 1024 * 1024; 1100e96eebcSThurston Dang #else 1110e96eebcSThurston Dang static const uptr kNumStackOriginDescrs = 4 * 1024 * 1024; 1120e96eebcSThurston Dang #endif // SANITIZER_PPC 11360c66db4SNico Weber static const char *StackOriginDescr[kNumStackOriginDescrs]; 11460c66db4SNico Weber static uptr StackOriginPC[kNumStackOriginDescrs]; 11560c66db4SNico Weber static atomic_uint32_t NumStackOriginDescrs; 11660c66db4SNico Weber 11760c66db4SNico Weber void Flags::SetDefaults() { 11860c66db4SNico Weber #define MSAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; 11960c66db4SNico Weber #include "msan_flags.inc" 12060c66db4SNico Weber #undef MSAN_FLAG 12160c66db4SNico Weber } 12260c66db4SNico Weber 12360c66db4SNico Weber // keep_going is an old name for halt_on_error, 12460c66db4SNico Weber // and it has inverse meaning. 125d48f2d7cSVitaly Buka class FlagHandlerKeepGoing final : public FlagHandlerBase { 12660c66db4SNico Weber bool *halt_on_error_; 12760c66db4SNico Weber 12860c66db4SNico Weber public: 12960c66db4SNico Weber explicit FlagHandlerKeepGoing(bool *halt_on_error) 13060c66db4SNico Weber : halt_on_error_(halt_on_error) {} 13160c66db4SNico Weber bool Parse(const char *value) final { 13260c66db4SNico Weber bool tmp; 13360c66db4SNico Weber FlagHandler<bool> h(&tmp); 13460c66db4SNico Weber if (!h.Parse(value)) return false; 13560c66db4SNico Weber *halt_on_error_ = !tmp; 13660c66db4SNico Weber return true; 13760c66db4SNico Weber } 1384c39f341SDan Liew bool Format(char *buffer, uptr size) final { 1394c39f341SDan Liew const char *keep_going_str = (*halt_on_error_) ? "false" : "true"; 1404c39f341SDan Liew return FormatString(buffer, size, keep_going_str); 1414c39f341SDan Liew } 14260c66db4SNico Weber }; 14360c66db4SNico Weber 14460c66db4SNico Weber static void RegisterMsanFlags(FlagParser *parser, Flags *f) { 14560c66db4SNico Weber #define MSAN_FLAG(Type, Name, DefaultValue, Description) \ 14660c66db4SNico Weber RegisterFlag(parser, #Name, Description, &f->Name); 14760c66db4SNico Weber #include "msan_flags.inc" 14860c66db4SNico Weber #undef MSAN_FLAG 14960c66db4SNico Weber 150afd170bdSLeonard Chan FlagHandlerKeepGoing *fh_keep_going = new (GetGlobalLowLevelAllocator()) 151afd170bdSLeonard Chan FlagHandlerKeepGoing(&f->halt_on_error); 15260c66db4SNico Weber parser->RegisterHandler("keep_going", fh_keep_going, 15360c66db4SNico Weber "deprecated, use halt_on_error"); 15460c66db4SNico Weber } 15560c66db4SNico Weber 15660c66db4SNico Weber static void InitializeFlags() { 15760c66db4SNico Weber SetCommonFlagsDefaults(); 15860c66db4SNico Weber { 15960c66db4SNico Weber CommonFlags cf; 16060c66db4SNico Weber cf.CopyFrom(*common_flags()); 16160c66db4SNico Weber cf.external_symbolizer_path = GetEnv("MSAN_SYMBOLIZER_PATH"); 16260c66db4SNico Weber cf.malloc_context_size = 20; 16360c66db4SNico Weber cf.handle_ioctl = true; 16460c66db4SNico Weber // FIXME: test and enable. 16560c66db4SNico Weber cf.check_printf = false; 16660c66db4SNico Weber cf.intercept_tls_get_addr = true; 16760c66db4SNico Weber OverrideCommonFlags(cf); 16860c66db4SNico Weber } 16960c66db4SNico Weber 17060c66db4SNico Weber Flags *f = flags(); 17160c66db4SNico Weber f->SetDefaults(); 17260c66db4SNico Weber 17360c66db4SNico Weber FlagParser parser; 17460c66db4SNico Weber RegisterMsanFlags(&parser, f); 17560c66db4SNico Weber RegisterCommonFlags(&parser); 17660c66db4SNico Weber 17760c66db4SNico Weber #if MSAN_CONTAINS_UBSAN 17860c66db4SNico Weber __ubsan::Flags *uf = __ubsan::flags(); 17960c66db4SNico Weber uf->SetDefaults(); 18060c66db4SNico Weber 18160c66db4SNico Weber FlagParser ubsan_parser; 18260c66db4SNico Weber __ubsan::RegisterUbsanFlags(&ubsan_parser, uf); 18360c66db4SNico Weber RegisterCommonFlags(&ubsan_parser); 18460c66db4SNico Weber #endif 18560c66db4SNico Weber 18660c66db4SNico Weber // Override from user-specified string. 18760c66db4SNico Weber parser.ParseString(__msan_default_options()); 18860c66db4SNico Weber #if MSAN_CONTAINS_UBSAN 1892d7fd38cSFangrui Song const char *ubsan_default_options = __ubsan_default_options(); 19060c66db4SNico Weber ubsan_parser.ParseString(ubsan_default_options); 19160c66db4SNico Weber #endif 19260c66db4SNico Weber 19360c66db4SNico Weber parser.ParseStringFromEnv("MSAN_OPTIONS"); 19460c66db4SNico Weber #if MSAN_CONTAINS_UBSAN 19560c66db4SNico Weber ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS"); 19660c66db4SNico Weber #endif 19760c66db4SNico Weber 19860c66db4SNico Weber InitializeCommonFlags(); 19960c66db4SNico Weber 20060c66db4SNico Weber if (Verbosity()) ReportUnrecognizedFlags(); 20160c66db4SNico Weber 20260c66db4SNico Weber if (common_flags()->help) parser.PrintFlagDescriptions(); 20360c66db4SNico Weber 20460c66db4SNico Weber // Check if deprecated exit_code MSan flag is set. 20560c66db4SNico Weber if (f->exit_code != -1) { 20660c66db4SNico Weber if (Verbosity()) 20760c66db4SNico Weber Printf("MSAN_OPTIONS=exit_code is deprecated! " 20860c66db4SNico Weber "Please use MSAN_OPTIONS=exitcode instead.\n"); 20960c66db4SNico Weber CommonFlags cf; 21060c66db4SNico Weber cf.CopyFrom(*common_flags()); 21160c66db4SNico Weber cf.exitcode = f->exit_code; 21260c66db4SNico Weber OverrideCommonFlags(cf); 21360c66db4SNico Weber } 21460c66db4SNico Weber 21560c66db4SNico Weber // Check flag values: 21660c66db4SNico Weber if (f->origin_history_size < 0 || 21760c66db4SNico Weber f->origin_history_size > Origin::kMaxDepth) { 21860c66db4SNico Weber Printf( 21960c66db4SNico Weber "Origin history size invalid: %d. Must be 0 (unlimited) or in [1, %d] " 22060c66db4SNico Weber "range.\n", 22160c66db4SNico Weber f->origin_history_size, Origin::kMaxDepth); 22260c66db4SNico Weber Die(); 22360c66db4SNico Weber } 22460c66db4SNico Weber // Limiting to kStackDepotMaxUseCount / 2 to avoid overflow in 22560c66db4SNico Weber // StackDepotHandle::inc_use_count_unsafe. 22660c66db4SNico Weber if (f->origin_history_per_stack_limit < 0 || 22760c66db4SNico Weber f->origin_history_per_stack_limit > kStackDepotMaxUseCount / 2) { 22860c66db4SNico Weber Printf( 22960c66db4SNico Weber "Origin per-stack limit invalid: %d. Must be 0 (unlimited) or in [1, " 23060c66db4SNico Weber "%d] range.\n", 23160c66db4SNico Weber f->origin_history_per_stack_limit, kStackDepotMaxUseCount / 2); 23260c66db4SNico Weber Die(); 23360c66db4SNico Weber } 23460c66db4SNico Weber if (f->store_context_size < 1) f->store_context_size = 1; 23560c66db4SNico Weber } 23660c66db4SNico Weber 23760c66db4SNico Weber void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin) { 23860c66db4SNico Weber if (msan_expect_umr) { 23960c66db4SNico Weber // Printf("Expected UMR\n"); 24060c66db4SNico Weber __msan_origin_tls = origin; 24160c66db4SNico Weber msan_expected_umr_found = 1; 24260c66db4SNico Weber return; 24360c66db4SNico Weber } 24460c66db4SNico Weber 24560c66db4SNico Weber ++msan_report_count; 24660c66db4SNico Weber 24760c66db4SNico Weber GET_FATAL_STACK_TRACE_PC_BP(pc, bp); 24860c66db4SNico Weber 24960c66db4SNico Weber u32 report_origin = 25060c66db4SNico Weber (__msan_get_track_origins() && Origin::isValidId(origin)) ? origin : 0; 25160c66db4SNico Weber ReportUMR(&stack, report_origin); 25260c66db4SNico Weber 25360c66db4SNico Weber if (__msan_get_track_origins() && !Origin::isValidId(origin)) { 25460c66db4SNico Weber Printf( 25560c66db4SNico Weber " ORIGIN: invalid (%x). Might be a bug in MemorySanitizer origin " 25660c66db4SNico Weber "tracking.\n This could still be a bug in your code, too!\n", 25760c66db4SNico Weber origin); 25860c66db4SNico Weber } 25960c66db4SNico Weber } 26060c66db4SNico Weber 26160c66db4SNico Weber void UnpoisonParam(uptr n) { 26260c66db4SNico Weber internal_memset(__msan_param_tls, 0, n * sizeof(*__msan_param_tls)); 26360c66db4SNico Weber } 26460c66db4SNico Weber 26560c66db4SNico Weber // Backup MSan runtime TLS state. 26660c66db4SNico Weber // Implementation must be async-signal-safe. 26760c66db4SNico Weber // Instances of this class may live on the signal handler stack, and data size 26860c66db4SNico Weber // may be an issue. 26960c66db4SNico Weber void ScopedThreadLocalStateBackup::Backup() { 27060c66db4SNico Weber va_arg_overflow_size_tls = __msan_va_arg_overflow_size_tls; 27160c66db4SNico Weber } 27260c66db4SNico Weber 27360c66db4SNico Weber void ScopedThreadLocalStateBackup::Restore() { 27460c66db4SNico Weber // A lame implementation that only keeps essential state and resets the rest. 27560c66db4SNico Weber __msan_va_arg_overflow_size_tls = va_arg_overflow_size_tls; 27660c66db4SNico Weber 27760c66db4SNico Weber internal_memset(__msan_param_tls, 0, sizeof(__msan_param_tls)); 27860c66db4SNico Weber internal_memset(__msan_retval_tls, 0, sizeof(__msan_retval_tls)); 27960c66db4SNico Weber internal_memset(__msan_va_arg_tls, 0, sizeof(__msan_va_arg_tls)); 28060c66db4SNico Weber internal_memset(__msan_va_arg_origin_tls, 0, 28160c66db4SNico Weber sizeof(__msan_va_arg_origin_tls)); 28260c66db4SNico Weber 28360c66db4SNico Weber if (__msan_get_track_origins()) { 28460c66db4SNico Weber internal_memset(&__msan_retval_origin_tls, 0, 28560c66db4SNico Weber sizeof(__msan_retval_origin_tls)); 28660c66db4SNico Weber internal_memset(__msan_param_origin_tls, 0, 28760c66db4SNico Weber sizeof(__msan_param_origin_tls)); 28860c66db4SNico Weber } 28960c66db4SNico Weber } 29060c66db4SNico Weber 29160c66db4SNico Weber void UnpoisonThreadLocalState() { 29260c66db4SNico Weber } 29360c66db4SNico Weber 29460c66db4SNico Weber const char *GetStackOriginDescr(u32 id, uptr *pc) { 29560c66db4SNico Weber CHECK_LT(id, kNumStackOriginDescrs); 29660c66db4SNico Weber if (pc) *pc = StackOriginPC[id]; 29760c66db4SNico Weber return StackOriginDescr[id]; 29860c66db4SNico Weber } 29960c66db4SNico Weber 30060c66db4SNico Weber u32 ChainOrigin(u32 id, StackTrace *stack) { 30160c66db4SNico Weber MsanThread *t = GetCurrentThread(); 30260c66db4SNico Weber if (t && t->InSignalHandler()) 30360c66db4SNico Weber return id; 30460c66db4SNico Weber 30560c66db4SNico Weber Origin o = Origin::FromRawId(id); 30660c66db4SNico Weber stack->tag = StackTrace::TAG_UNKNOWN; 30760c66db4SNico Weber Origin chained = Origin::CreateChainedOrigin(o, stack); 30860c66db4SNico Weber return chained.raw_id(); 30960c66db4SNico Weber } 31060c66db4SNico Weber 311ec277b67SKevin Athey // Current implementation separates the 'id_ptr' from the 'descr' and makes 312ec277b67SKevin Athey // 'descr' constant. 313ec277b67SKevin Athey // Previous implementation 'descr' is created at compile time and contains 314ec277b67SKevin Athey // '----' in the beginning. When we see descr for the first time we replace 315ec277b67SKevin Athey // '----' with a uniq id and set the origin to (id | (31-th bit)). 316ec277b67SKevin Athey static inline void SetAllocaOrigin(void *a, uptr size, u32 *id_ptr, char *descr, 317ec277b67SKevin Athey uptr pc) { 318af77e5e4SVitaly Buka static const u32 dash = '-'; 319af77e5e4SVitaly Buka static const u32 first_timer = 320af77e5e4SVitaly Buka dash + (dash << 8) + (dash << 16) + (dash << 24); 321af77e5e4SVitaly Buka u32 id = *id_ptr; 322ec277b67SKevin Athey if (id == 0 || id == first_timer) { 323af77e5e4SVitaly Buka u32 idx = atomic_fetch_add(&NumStackOriginDescrs, 1, memory_order_relaxed); 324af77e5e4SVitaly Buka CHECK_LT(idx, kNumStackOriginDescrs); 325ec277b67SKevin Athey StackOriginDescr[idx] = descr; 326af77e5e4SVitaly Buka StackOriginPC[idx] = pc; 327af77e5e4SVitaly Buka id = Origin::CreateStackOrigin(idx).raw_id(); 328af77e5e4SVitaly Buka *id_ptr = id; 329af77e5e4SVitaly Buka } 330af77e5e4SVitaly Buka __msan_set_origin(a, size, id); 331af77e5e4SVitaly Buka } 332af77e5e4SVitaly Buka 33360c66db4SNico Weber } // namespace __msan 33460c66db4SNico Weber 33560c66db4SNico Weber void __sanitizer::BufferedStackTrace::UnwindImpl( 33660c66db4SNico Weber uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) { 33760c66db4SNico Weber using namespace __msan; 33860c66db4SNico Weber MsanThread *t = GetCurrentThread(); 33960c66db4SNico Weber if (!t || !StackTrace::WillUseFastUnwind(request_fast)) { 34060c66db4SNico Weber // Block reports from our interceptors during _Unwind_Backtrace. 34147a9528fSVitaly Buka UnwinderScope sym_scope; 342261d6e05SFangrui Song return Unwind(max_depth, pc, bp, context, t ? t->stack_top() : 0, 343261d6e05SFangrui Song t ? t->stack_bottom() : 0, false); 34460c66db4SNico Weber } 34560c66db4SNico Weber if (StackTrace::WillUseFastUnwind(request_fast)) 34660c66db4SNico Weber Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(), true); 34760c66db4SNico Weber else 34860c66db4SNico Weber Unwind(max_depth, pc, 0, context, 0, 0, false); 34960c66db4SNico Weber } 35060c66db4SNico Weber 35160c66db4SNico Weber // Interface. 35260c66db4SNico Weber 35360c66db4SNico Weber using namespace __msan; 35460c66db4SNico Weber 35560c66db4SNico Weber #define MSAN_MAYBE_WARNING(type, size) \ 35660c66db4SNico Weber void __msan_maybe_warning_##size(type s, u32 o) { \ 35739b8a271SFangrui Song GET_CALLER_PC_BP; \ 35860c66db4SNico Weber if (UNLIKELY(s)) { \ 35960c66db4SNico Weber PrintWarningWithOrigin(pc, bp, o); \ 36060c66db4SNico Weber if (__msan::flags()->halt_on_error) { \ 36160c66db4SNico Weber Printf("Exiting\n"); \ 36260c66db4SNico Weber Die(); \ 36360c66db4SNico Weber } \ 36460c66db4SNico Weber } \ 36560c66db4SNico Weber } 36660c66db4SNico Weber 36760c66db4SNico Weber MSAN_MAYBE_WARNING(u8, 1) 36860c66db4SNico Weber MSAN_MAYBE_WARNING(u16, 2) 36960c66db4SNico Weber MSAN_MAYBE_WARNING(u32, 4) 37060c66db4SNico Weber MSAN_MAYBE_WARNING(u64, 8) 37160c66db4SNico Weber 37260c66db4SNico Weber #define MSAN_MAYBE_STORE_ORIGIN(type, size) \ 37360c66db4SNico Weber void __msan_maybe_store_origin_##size(type s, void *p, u32 o) { \ 37460c66db4SNico Weber if (UNLIKELY(s)) { \ 37560c66db4SNico Weber if (__msan_get_track_origins() > 1) { \ 37639b8a271SFangrui Song GET_CALLER_PC_BP; \ 37760c66db4SNico Weber GET_STORE_STACK_TRACE_PC_BP(pc, bp); \ 37860c66db4SNico Weber o = ChainOrigin(o, &stack); \ 37960c66db4SNico Weber } \ 38060c66db4SNico Weber *(u32 *)MEM_TO_ORIGIN((uptr)p & ~3UL) = o; \ 38160c66db4SNico Weber } \ 38260c66db4SNico Weber } 38360c66db4SNico Weber 38460c66db4SNico Weber MSAN_MAYBE_STORE_ORIGIN(u8, 1) 38560c66db4SNico Weber MSAN_MAYBE_STORE_ORIGIN(u16, 2) 38660c66db4SNico Weber MSAN_MAYBE_STORE_ORIGIN(u32, 4) 38760c66db4SNico Weber MSAN_MAYBE_STORE_ORIGIN(u64, 8) 38860c66db4SNico Weber 38960c66db4SNico Weber void __msan_warning() { 39039b8a271SFangrui Song GET_CALLER_PC_BP; 391ad2b356fSVitaly Buka PrintWarningWithOrigin(pc, bp, 0); 39260c66db4SNico Weber if (__msan::flags()->halt_on_error) { 39360c66db4SNico Weber if (__msan::flags()->print_stats) 39460c66db4SNico Weber ReportStats(); 39560c66db4SNico Weber Printf("Exiting\n"); 39660c66db4SNico Weber Die(); 39760c66db4SNico Weber } 39860c66db4SNico Weber } 39960c66db4SNico Weber 40060c66db4SNico Weber void __msan_warning_noreturn() { 40139b8a271SFangrui Song GET_CALLER_PC_BP; 402ad2b356fSVitaly Buka PrintWarningWithOrigin(pc, bp, 0); 40360c66db4SNico Weber if (__msan::flags()->print_stats) 40460c66db4SNico Weber ReportStats(); 40560c66db4SNico Weber Printf("Exiting\n"); 40660c66db4SNico Weber Die(); 40760c66db4SNico Weber } 40860c66db4SNico Weber 409b0ffa8beSGui Andrade void __msan_warning_with_origin(u32 origin) { 41039b8a271SFangrui Song GET_CALLER_PC_BP; 411b0ffa8beSGui Andrade PrintWarningWithOrigin(pc, bp, origin); 412b0ffa8beSGui Andrade if (__msan::flags()->halt_on_error) { 413b0ffa8beSGui Andrade if (__msan::flags()->print_stats) 414b0ffa8beSGui Andrade ReportStats(); 415b0ffa8beSGui Andrade Printf("Exiting\n"); 416b0ffa8beSGui Andrade Die(); 417b0ffa8beSGui Andrade } 418b0ffa8beSGui Andrade } 419b0ffa8beSGui Andrade 420b0ffa8beSGui Andrade void __msan_warning_with_origin_noreturn(u32 origin) { 42139b8a271SFangrui Song GET_CALLER_PC_BP; 422b0ffa8beSGui Andrade PrintWarningWithOrigin(pc, bp, origin); 423b0ffa8beSGui Andrade if (__msan::flags()->print_stats) 424b0ffa8beSGui Andrade ReportStats(); 425b0ffa8beSGui Andrade Printf("Exiting\n"); 426b0ffa8beSGui Andrade Die(); 427b0ffa8beSGui Andrade } 428b0ffa8beSGui Andrade 42960c66db4SNico Weber static void OnStackUnwind(const SignalContext &sig, const void *, 43060c66db4SNico Weber BufferedStackTrace *stack) { 431d39e7e2cSVitaly Buka stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, 43260c66db4SNico Weber common_flags()->fast_unwind_on_fatal); 43360c66db4SNico Weber } 43460c66db4SNico Weber 43560c66db4SNico Weber static void MsanOnDeadlySignal(int signo, void *siginfo, void *context) { 43660c66db4SNico Weber HandleDeadlySignal(siginfo, context, GetTid(), &OnStackUnwind, nullptr); 43760c66db4SNico Weber } 43860c66db4SNico Weber 4392721e27cSDmitry Vyukov static void CheckUnwind() { 4402721e27cSDmitry Vyukov GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME()); 4412721e27cSDmitry Vyukov stack.Print(); 44260c66db4SNico Weber } 44360c66db4SNico Weber 44460c66db4SNico Weber void __msan_init() { 44560c66db4SNico Weber CHECK(!msan_init_is_running); 44660c66db4SNico Weber if (msan_inited) return; 44760c66db4SNico Weber msan_init_is_running = 1; 44860c66db4SNico Weber SanitizerToolName = "MemorySanitizer"; 44960c66db4SNico Weber 45060c66db4SNico Weber AvoidCVE_2016_2143(); 45160c66db4SNico Weber 45260c66db4SNico Weber CacheBinaryName(); 45360c66db4SNico Weber InitializeFlags(); 45460c66db4SNico Weber 45560c66db4SNico Weber // Install tool-specific callbacks in sanitizer_common. 4562721e27cSDmitry Vyukov SetCheckUnwindCallback(CheckUnwind); 45760c66db4SNico Weber 45860c66db4SNico Weber __sanitizer_set_report_path(common_flags()->log_path); 45960c66db4SNico Weber 460*a0bb2e21SVitaly Buka InitializePlatformEarly(); 461*a0bb2e21SVitaly Buka 46260c66db4SNico Weber InitializeInterceptors(); 463fcce8432SVitaly Buka InstallAtForkHandler(); 464e2ed800dSDavid Carlier CheckASLR(); 46560c66db4SNico Weber InstallDeadlySignalHandlers(MsanOnDeadlySignal); 46660c66db4SNico Weber InstallAtExitHandler(); // Needs __cxa_atexit interceptor. 46760c66db4SNico Weber 46860c66db4SNico Weber DisableCoreDumperIfNecessary(); 46960c66db4SNico Weber if (StackSizeIsUnlimited()) { 47060c66db4SNico Weber VPrintf(1, "Unlimited stack, doing reexec\n"); 47160c66db4SNico Weber // A reasonably large stack size. It is bigger than the usual 8Mb, because, 47260c66db4SNico Weber // well, the program could have been run with unlimited stack for a reason. 47360c66db4SNico Weber SetStackSizeLimitInBytes(32 * 1024 * 1024); 47460c66db4SNico Weber ReExec(); 47560c66db4SNico Weber } 47660c66db4SNico Weber 47760c66db4SNico Weber __msan_clear_on_return(); 47860c66db4SNico Weber if (__msan_get_track_origins()) 47960c66db4SNico Weber VPrintf(1, "msan_track_origins\n"); 48058f72518SThurston Dang if (!InitShadowWithReExec(__msan_get_track_origins())) { 48160c66db4SNico Weber Printf("FATAL: MemorySanitizer can not mmap the shadow memory.\n"); 48260c66db4SNico Weber Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n"); 48360c66db4SNico Weber Printf("FATAL: Disabling ASLR is known to cause this error.\n"); 48460c66db4SNico Weber Printf("FATAL: If running under GDB, try " 48560c66db4SNico Weber "'set disable-randomization off'.\n"); 48660c66db4SNico Weber DumpProcessMap(); 48760c66db4SNico Weber Die(); 48860c66db4SNico Weber } 48960c66db4SNico Weber 49047a9528fSVitaly Buka Symbolizer::GetOrInit()->AddHooks(EnterSymbolizerOrUnwider, 49147a9528fSVitaly Buka ExitSymbolizerOrUnwider); 49260c66db4SNico Weber 49360c66db4SNico Weber InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir); 49460c66db4SNico Weber 49560c66db4SNico Weber MsanTSDInit(MsanTSDDtor); 49660c66db4SNico Weber 49760c66db4SNico Weber MsanAllocatorInit(); 49860c66db4SNico Weber 49960c66db4SNico Weber MsanThread *main_thread = MsanThread::Create(nullptr, nullptr); 50060c66db4SNico Weber SetCurrentThread(main_thread); 501b3267bb3SVitaly Buka main_thread->Init(); 50260c66db4SNico Weber 50360c66db4SNico Weber #if MSAN_CONTAINS_UBSAN 50460c66db4SNico Weber __ubsan::InitAsPlugin(); 50560c66db4SNico Weber #endif 50660c66db4SNico Weber 50760c66db4SNico Weber VPrintf(1, "MemorySanitizer init done\n"); 50860c66db4SNico Weber 50960c66db4SNico Weber msan_init_is_running = 0; 51060c66db4SNico Weber msan_inited = 1; 51160c66db4SNico Weber } 51260c66db4SNico Weber 51360c66db4SNico Weber void __msan_set_keep_going(int keep_going) { 51460c66db4SNico Weber flags()->halt_on_error = !keep_going; 51560c66db4SNico Weber } 51660c66db4SNico Weber 51760c66db4SNico Weber void __msan_set_expect_umr(int expect_umr) { 51860c66db4SNico Weber if (expect_umr) { 51960c66db4SNico Weber msan_expected_umr_found = 0; 52060c66db4SNico Weber } else if (!msan_expected_umr_found) { 52139b8a271SFangrui Song GET_CALLER_PC_BP; 52260c66db4SNico Weber GET_FATAL_STACK_TRACE_PC_BP(pc, bp); 52360c66db4SNico Weber ReportExpectedUMRNotFound(&stack); 52460c66db4SNico Weber Die(); 52560c66db4SNico Weber } 52660c66db4SNico Weber msan_expect_umr = expect_umr; 52760c66db4SNico Weber } 52860c66db4SNico Weber 52960c66db4SNico Weber void __msan_print_shadow(const void *x, uptr size) { 53060c66db4SNico Weber if (!MEM_IS_APP(x)) { 53160c66db4SNico Weber Printf("Not a valid application address: %p\n", x); 53260c66db4SNico Weber return; 53360c66db4SNico Weber } 53460c66db4SNico Weber 53560c66db4SNico Weber DescribeMemoryRange(x, size); 53660c66db4SNico Weber } 53760c66db4SNico Weber 53860c66db4SNico Weber void __msan_dump_shadow(const void *x, uptr size) { 53960c66db4SNico Weber if (!MEM_IS_APP(x)) { 54060c66db4SNico Weber Printf("Not a valid application address: %p\n", x); 54160c66db4SNico Weber return; 54260c66db4SNico Weber } 54360c66db4SNico Weber 54460c66db4SNico Weber unsigned char *s = (unsigned char*)MEM_TO_SHADOW(x); 54513a442caSMartin Liska Printf("%p[%p] ", (void *)s, x); 54660c66db4SNico Weber for (uptr i = 0; i < size; i++) 54760c66db4SNico Weber Printf("%x%x ", s[i] >> 4, s[i] & 0xf); 54860c66db4SNico Weber Printf("\n"); 54960c66db4SNico Weber } 55060c66db4SNico Weber 55160c66db4SNico Weber sptr __msan_test_shadow(const void *x, uptr size) { 55260c66db4SNico Weber if (!MEM_IS_APP(x)) return -1; 55360c66db4SNico Weber unsigned char *s = (unsigned char *)MEM_TO_SHADOW((uptr)x); 554c0b5000bSGui Andrade if (__sanitizer::mem_is_zero((const char *)s, size)) 555c0b5000bSGui Andrade return -1; 556c0b5000bSGui Andrade // Slow path: loop through again to find the location. 55760c66db4SNico Weber for (uptr i = 0; i < size; ++i) 55860c66db4SNico Weber if (s[i]) 55960c66db4SNico Weber return i; 56060c66db4SNico Weber return -1; 56160c66db4SNico Weber } 56260c66db4SNico Weber 56360c66db4SNico Weber void __msan_check_mem_is_initialized(const void *x, uptr size) { 56460c66db4SNico Weber if (!__msan::flags()->report_umrs) return; 56560c66db4SNico Weber sptr offset = __msan_test_shadow(x, size); 56660c66db4SNico Weber if (offset < 0) 56760c66db4SNico Weber return; 56860c66db4SNico Weber 56939b8a271SFangrui Song GET_CALLER_PC_BP; 57060c66db4SNico Weber ReportUMRInsideAddressRange(__func__, x, size, offset); 57160c66db4SNico Weber __msan::PrintWarningWithOrigin(pc, bp, 57260c66db4SNico Weber __msan_get_origin(((const char *)x) + offset)); 57360c66db4SNico Weber if (__msan::flags()->halt_on_error) { 57460c66db4SNico Weber Printf("Exiting\n"); 57560c66db4SNico Weber Die(); 57660c66db4SNico Weber } 57760c66db4SNico Weber } 57860c66db4SNico Weber 57960c66db4SNico Weber int __msan_set_poison_in_malloc(int do_poison) { 58060c66db4SNico Weber int old = flags()->poison_in_malloc; 58160c66db4SNico Weber flags()->poison_in_malloc = do_poison; 58260c66db4SNico Weber return old; 58360c66db4SNico Weber } 58460c66db4SNico Weber 58560c66db4SNico Weber int __msan_has_dynamic_component() { return false; } 58660c66db4SNico Weber 58760c66db4SNico Weber NOINLINE 58860c66db4SNico Weber void __msan_clear_on_return() { 58960c66db4SNico Weber __msan_param_tls[0] = 0; 59060c66db4SNico Weber } 59160c66db4SNico Weber 59260c66db4SNico Weber void __msan_partial_poison(const void* data, void* shadow, uptr size) { 59360c66db4SNico Weber internal_memcpy((void*)MEM_TO_SHADOW((uptr)data), shadow, size); 59460c66db4SNico Weber } 59560c66db4SNico Weber 59660c66db4SNico Weber void __msan_load_unpoisoned(const void *src, uptr size, void *dst) { 59760c66db4SNico Weber internal_memcpy(dst, src, size); 59860c66db4SNico Weber __msan_unpoison(dst, size); 59960c66db4SNico Weber } 60060c66db4SNico Weber 60160c66db4SNico Weber void __msan_set_origin(const void *a, uptr size, u32 origin) { 60260c66db4SNico Weber if (__msan_get_track_origins()) SetOrigin(a, size, origin); 60360c66db4SNico Weber } 60460c66db4SNico Weber 60560c66db4SNico Weber void __msan_set_alloca_origin(void *a, uptr size, char *descr) { 606ec277b67SKevin Athey SetAllocaOrigin(a, size, reinterpret_cast<u32 *>(descr), descr + 4, 607ec277b67SKevin Athey GET_CALLER_PC()); 60860c66db4SNico Weber } 60960c66db4SNico Weber 61060c66db4SNico Weber void __msan_set_alloca_origin4(void *a, uptr size, char *descr, uptr pc) { 611af77e5e4SVitaly Buka // Intentionally ignore pc and use return address. This function is here for 612af77e5e4SVitaly Buka // compatibility, in case program is linked with library instrumented by 613af77e5e4SVitaly Buka // older clang. 614ec277b67SKevin Athey SetAllocaOrigin(a, size, reinterpret_cast<u32 *>(descr), descr + 4, 615ec277b67SKevin Athey GET_CALLER_PC()); 616ec277b67SKevin Athey } 617ec277b67SKevin Athey 618ec277b67SKevin Athey void __msan_set_alloca_origin_with_descr(void *a, uptr size, u32 *id_ptr, 619ec277b67SKevin Athey char *descr) { 620ec277b67SKevin Athey SetAllocaOrigin(a, size, id_ptr, descr, GET_CALLER_PC()); 62160c66db4SNico Weber } 62260c66db4SNico Weber 623532564deSKevin Athey void __msan_set_alloca_origin_no_descr(void *a, uptr size, u32 *id_ptr) { 624532564deSKevin Athey SetAllocaOrigin(a, size, id_ptr, nullptr, GET_CALLER_PC()); 625532564deSKevin Athey } 626532564deSKevin Athey 62760c66db4SNico Weber u32 __msan_chain_origin(u32 id) { 62839b8a271SFangrui Song GET_CALLER_PC_BP; 62960c66db4SNico Weber GET_STORE_STACK_TRACE_PC_BP(pc, bp); 63060c66db4SNico Weber return ChainOrigin(id, &stack); 63160c66db4SNico Weber } 63260c66db4SNico Weber 63360c66db4SNico Weber u32 __msan_get_origin(const void *a) { 63460c66db4SNico Weber if (!__msan_get_track_origins()) return 0; 63560c66db4SNico Weber uptr x = (uptr)a; 63660c66db4SNico Weber uptr aligned = x & ~3ULL; 63760c66db4SNico Weber uptr origin_ptr = MEM_TO_ORIGIN(aligned); 63860c66db4SNico Weber return *(u32*)origin_ptr; 63960c66db4SNico Weber } 64060c66db4SNico Weber 64160c66db4SNico Weber int __msan_origin_is_descendant_or_same(u32 this_id, u32 prev_id) { 64260c66db4SNico Weber Origin o = Origin::FromRawId(this_id); 64360c66db4SNico Weber while (o.raw_id() != prev_id && o.isChainedOrigin()) 64460c66db4SNico Weber o = o.getNextChainedOrigin(nullptr); 64560c66db4SNico Weber return o.raw_id() == prev_id; 64660c66db4SNico Weber } 64760c66db4SNico Weber 64860c66db4SNico Weber u32 __msan_get_umr_origin() { 64960c66db4SNico Weber return __msan_origin_tls; 65060c66db4SNico Weber } 65160c66db4SNico Weber 65260c66db4SNico Weber u16 __sanitizer_unaligned_load16(const uu16 *p) { 653af380748Sserge-sans-paille internal_memcpy(&__msan_retval_tls[0], (void *)MEM_TO_SHADOW((uptr)p), 654af380748Sserge-sans-paille sizeof(uu16)); 65560c66db4SNico Weber if (__msan_get_track_origins()) 65660c66db4SNico Weber __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p)); 65760c66db4SNico Weber return *p; 65860c66db4SNico Weber } 65960c66db4SNico Weber u32 __sanitizer_unaligned_load32(const uu32 *p) { 660af380748Sserge-sans-paille internal_memcpy(&__msan_retval_tls[0], (void *)MEM_TO_SHADOW((uptr)p), 661af380748Sserge-sans-paille sizeof(uu32)); 66260c66db4SNico Weber if (__msan_get_track_origins()) 66360c66db4SNico Weber __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p)); 66460c66db4SNico Weber return *p; 66560c66db4SNico Weber } 66660c66db4SNico Weber u64 __sanitizer_unaligned_load64(const uu64 *p) { 667af380748Sserge-sans-paille internal_memcpy(&__msan_retval_tls[0], (void *)MEM_TO_SHADOW((uptr)p), 668af380748Sserge-sans-paille sizeof(uu64)); 66960c66db4SNico Weber if (__msan_get_track_origins()) 67060c66db4SNico Weber __msan_retval_origin_tls = GetOriginIfPoisoned((uptr)p, sizeof(*p)); 67160c66db4SNico Weber return *p; 67260c66db4SNico Weber } 67360c66db4SNico Weber void __sanitizer_unaligned_store16(uu16 *p, u16 x) { 674af380748Sserge-sans-paille static_assert(sizeof(uu16) == sizeof(u16), "incompatible types"); 675af380748Sserge-sans-paille u16 s; 676af380748Sserge-sans-paille internal_memcpy(&s, &__msan_param_tls[1], sizeof(uu16)); 677af380748Sserge-sans-paille internal_memcpy((void *)MEM_TO_SHADOW((uptr)p), &s, sizeof(uu16)); 67860c66db4SNico Weber if (s && __msan_get_track_origins()) 67960c66db4SNico Weber if (uu32 o = __msan_param_origin_tls[2]) 68060c66db4SNico Weber SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o); 68160c66db4SNico Weber *p = x; 68260c66db4SNico Weber } 68360c66db4SNico Weber void __sanitizer_unaligned_store32(uu32 *p, u32 x) { 684af380748Sserge-sans-paille static_assert(sizeof(uu32) == sizeof(u32), "incompatible types"); 685af380748Sserge-sans-paille u32 s; 686af380748Sserge-sans-paille internal_memcpy(&s, &__msan_param_tls[1], sizeof(uu32)); 687af380748Sserge-sans-paille internal_memcpy((void *)MEM_TO_SHADOW((uptr)p), &s, sizeof(uu32)); 68860c66db4SNico Weber if (s && __msan_get_track_origins()) 68960c66db4SNico Weber if (uu32 o = __msan_param_origin_tls[2]) 69060c66db4SNico Weber SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o); 69160c66db4SNico Weber *p = x; 69260c66db4SNico Weber } 69360c66db4SNico Weber void __sanitizer_unaligned_store64(uu64 *p, u64 x) { 69460c66db4SNico Weber u64 s = __msan_param_tls[1]; 69560c66db4SNico Weber *(uu64 *)MEM_TO_SHADOW((uptr)p) = s; 69660c66db4SNico Weber if (s && __msan_get_track_origins()) 69760c66db4SNico Weber if (uu32 o = __msan_param_origin_tls[2]) 69860c66db4SNico Weber SetOriginIfPoisoned((uptr)p, (uptr)&s, sizeof(s), o); 69960c66db4SNico Weber *p = x; 70060c66db4SNico Weber } 70160c66db4SNico Weber 70260c66db4SNico Weber void __msan_set_death_callback(void (*callback)(void)) { 70360c66db4SNico Weber SetUserDieCallback(callback); 70460c66db4SNico Weber } 70560c66db4SNico Weber 7061d3ef5f1SJustin Cady void __msan_start_switch_fiber(const void *bottom, uptr size) { 7071d3ef5f1SJustin Cady MsanThread *t = GetCurrentThread(); 7081d3ef5f1SJustin Cady if (!t) { 7091d3ef5f1SJustin Cady VReport(1, "__msan_start_switch_fiber called from unknown thread\n"); 7101d3ef5f1SJustin Cady return; 7111d3ef5f1SJustin Cady } 7121d3ef5f1SJustin Cady t->StartSwitchFiber((uptr)bottom, size); 7131d3ef5f1SJustin Cady } 7141d3ef5f1SJustin Cady 7151d3ef5f1SJustin Cady void __msan_finish_switch_fiber(const void **bottom_old, uptr *size_old) { 7161d3ef5f1SJustin Cady MsanThread *t = GetCurrentThread(); 7171d3ef5f1SJustin Cady if (!t) { 7181d3ef5f1SJustin Cady VReport(1, "__msan_finish_switch_fiber called from unknown thread\n"); 7191d3ef5f1SJustin Cady return; 7201d3ef5f1SJustin Cady } 7211d3ef5f1SJustin Cady t->FinishSwitchFiber((uptr *)bottom_old, (uptr *)size_old); 7221d3ef5f1SJustin Cady 7231d3ef5f1SJustin Cady internal_memset(__msan_param_tls, 0, sizeof(__msan_param_tls)); 7241d3ef5f1SJustin Cady internal_memset(__msan_retval_tls, 0, sizeof(__msan_retval_tls)); 7251d3ef5f1SJustin Cady internal_memset(__msan_va_arg_tls, 0, sizeof(__msan_va_arg_tls)); 7261d3ef5f1SJustin Cady 7271d3ef5f1SJustin Cady if (__msan_get_track_origins()) { 7281d3ef5f1SJustin Cady internal_memset(__msan_param_origin_tls, 0, 7291d3ef5f1SJustin Cady sizeof(__msan_param_origin_tls)); 7301d3ef5f1SJustin Cady internal_memset(&__msan_retval_origin_tls, 0, 7311d3ef5f1SJustin Cady sizeof(__msan_retval_origin_tls)); 7321d3ef5f1SJustin Cady internal_memset(__msan_va_arg_origin_tls, 0, 7331d3ef5f1SJustin Cady sizeof(__msan_va_arg_origin_tls)); 7341d3ef5f1SJustin Cady } 7351d3ef5f1SJustin Cady } 7361d3ef5f1SJustin Cady 7372d7fd38cSFangrui Song SANITIZER_INTERFACE_WEAK_DEF(const char *, __msan_default_options, void) { 7382d7fd38cSFangrui Song return ""; 7392d7fd38cSFangrui Song } 74060c66db4SNico Weber 74160c66db4SNico Weber extern "C" { 74260c66db4SNico Weber SANITIZER_INTERFACE_ATTRIBUTE 74360c66db4SNico Weber void __sanitizer_print_stack_trace() { 74460c66db4SNico Weber GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME()); 74560c66db4SNico Weber stack.Print(); 74660c66db4SNico Weber } 74760c66db4SNico Weber } // extern "C" 748