diff options
Diffstat (limited to 'lib/msan/msan.cc')
-rw-r--r-- | lib/msan/msan.cc | 89 |
1 files changed, 68 insertions, 21 deletions
diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc index 670213f011c70..aa79b31be2e0e 100644 --- a/lib/msan/msan.cc +++ b/lib/msan/msan.cc @@ -58,7 +58,10 @@ static THREADLOCAL struct { uptr stack_top, stack_bottom; } __msan_stack_bounds; -extern const int __msan_track_origins; +static THREADLOCAL bool is_in_symbolizer; +static THREADLOCAL bool is_in_loader; + +extern "C" const int __msan_track_origins; int __msan_get_track_origins() { return __msan_track_origins; } @@ -67,11 +70,11 @@ namespace __msan { static bool IsRunningUnderDr() { bool result = false; - MemoryMappingLayout proc_maps; + MemoryMappingLayout proc_maps(/*cache_enabled*/true); const sptr kBufSize = 4095; char *filename = (char*)MmapOrDie(kBufSize, __FUNCTION__); while (proc_maps.Next(/* start */0, /* end */0, /* file_offset */0, - filename, kBufSize)) { + filename, kBufSize, /* protection */0)) { if (internal_strstr(filename, "libdynamorio") != 0) { result = true; break; @@ -81,6 +84,18 @@ static bool IsRunningUnderDr() { return result; } +void EnterSymbolizer() { is_in_symbolizer = true; } +void ExitSymbolizer() { is_in_symbolizer = false; } +bool IsInSymbolizer() { return is_in_symbolizer; } + +void EnterLoader() { is_in_loader = true; } +void ExitLoader() { is_in_loader = false; } + +extern "C" { +SANITIZER_INTERFACE_ATTRIBUTE +bool __msan_is_in_loader() { return is_in_loader; } +} + static Flags msan_flags; Flags *flags() { @@ -99,6 +114,7 @@ static const char *StackOriginDescr[kNumStackOriginDescrs]; static atomic_uint32_t NumStackOriginDescrs; static void ParseFlagsFromString(Flags *f, const char *str) { + ParseCommonFlagsFromString(str); ParseFlag(str, &f->poison_heap_with_zeroes, "poison_heap_with_zeroes"); ParseFlag(str, &f->poison_stack_with_zeroes, "poison_stack_with_zeroes"); ParseFlag(str, &f->poison_in_malloc, "poison_in_malloc"); @@ -108,22 +124,31 @@ static void ParseFlagsFromString(Flags *f, const char *str) { f->exit_code = 1; Die(); } - ParseFlag(str, &f->num_callers, "num_callers"); ParseFlag(str, &f->report_umrs, "report_umrs"); ParseFlag(str, &f->verbosity, "verbosity"); + ParseFlag(str, &f->wrap_signals, "wrap_signals"); } static void InitializeFlags(Flags *f, const char *options) { - internal_memset(f, 0, sizeof(*f)); + CommonFlags *cf = common_flags(); + cf->external_symbolizer_path = GetEnv("MSAN_SYMBOLIZER_PATH"); + cf->strip_path_prefix = ""; + cf->fast_unwind_on_fatal = false; + cf->fast_unwind_on_malloc = true; + cf->malloc_context_size = 20; + internal_memset(f, 0, sizeof(*f)); f->poison_heap_with_zeroes = false; f->poison_stack_with_zeroes = false; f->poison_in_malloc = true; f->exit_code = 77; - f->num_callers = 20; f->report_umrs = true; f->verbosity = 0; + f->wrap_signals = true; + // Override from user-specified string. + if (__msan_default_options) + ParseFlagsFromString(f, __msan_default_options()); ParseFlagsFromString(f, options); } @@ -140,7 +165,14 @@ static void GetCurrentStackBounds(uptr *stack_top, uptr *stack_bottom) { *stack_bottom = __msan_stack_bounds.stack_bottom; } -void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp) { +void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, + bool fast) { + if (!fast) { + // Block reports from our interceptors during _Unwind_Backtrace. + SymbolizerScope sym_scope; + return stack->SlowUnwindStack(pc, max_s); + } + uptr stack_top, stack_bottom; GetCurrentStackBounds(&stack_top, &stack_bottom); stack->size = 0; @@ -168,7 +200,8 @@ void PrintWarningWithOrigin(uptr pc, uptr bp, u32 origin) { ++msan_report_count; StackTrace stack; - GetStackTrace(&stack, kStackTraceMax, pc, bp); + GetStackTrace(&stack, kStackTraceMax, pc, bp, + common_flags()->fast_unwind_on_fatal); u32 report_origin = (__msan_track_origins && OriginIsValid(origin)) ? origin : 0; @@ -204,12 +237,17 @@ void __msan_warning_noreturn() { void __msan_init() { if (msan_inited) return; msan_init_is_running = 1; + SanitizerToolName = "MemorySanitizer"; InstallAtExitHandler(); SetDieCallback(MsanDie); + InitTlsSize(); InitializeInterceptors(); - ReplaceOperatorsNewAndDelete(); + if (MSAN_REPLACE_OPERATORS_NEW_AND_DELETE) + ReplaceOperatorsNewAndDelete(); + const char *msan_options = GetEnv("MSAN_OPTIONS"); + InitializeFlags(&msan_flags, msan_options); if (StackSizeIsUnlimited()) { if (flags()->verbosity) Printf("Unlimited stack, doing reexec\n"); @@ -218,10 +256,10 @@ void __msan_init() { SetStackSizeLimitInBytes(32 * 1024 * 1024); ReExec(); } - const char *msan_options = GetEnv("MSAN_OPTIONS"); - InitializeFlags(&msan_flags, msan_options); + if (flags()->verbosity) Printf("MSAN_OPTIONS: %s\n", msan_options ? msan_options : "<empty>"); + msan_running_under_dr = IsRunningUnderDr(); __msan_clear_on_return(); if (__msan_track_origins && flags()->verbosity > 0) @@ -238,9 +276,7 @@ void __msan_init() { Die(); } - InstallTrapHandler(); - - const char *external_symbolizer = GetEnv("MSAN_SYMBOLIZER_PATH"); + const char *external_symbolizer = common_flags()->external_symbolizer_path; if (external_symbolizer && external_symbolizer[0]) { CHECK(InitializeExternalSymbolizer(external_symbolizer)); } @@ -265,7 +301,8 @@ void __msan_set_expect_umr(int expect_umr) { GET_CALLER_PC_BP_SP; (void)sp; StackTrace stack; - GetStackTrace(&stack, kStackTraceMax, pc, bp); + GetStackTrace(&stack, kStackTraceMax, pc, bp, + common_flags()->fast_unwind_on_fatal); ReportExpectedUMRNotFound(&stack); Die(); } @@ -294,6 +331,10 @@ void __msan_print_param_shadow() { Printf("\n"); } +void __msan_unpoison_param(uptr n) { + internal_memset(__msan_param_tls, 0, n * sizeof(*__msan_param_tls)); +} + sptr __msan_test_shadow(const void *x, uptr size) { unsigned char *s = (unsigned char*)MEM_TO_SHADOW((uptr)x); for (uptr i = 0; i < size; ++i) @@ -308,8 +349,6 @@ int __msan_set_poison_in_malloc(int do_poison) { return old; } -void __msan_break_optimization(void *x) { } - int __msan_has_dynamic_component() { return msan_running_under_dr; } @@ -344,7 +383,7 @@ int __msan_get_param_tls_offset() { return param_tls_p - tls_base_p; } -void __msan_partial_poison(void* data, void* shadow, uptr size) { +void __msan_partial_poison(const void* data, void* shadow, uptr size) { internal_memcpy((void*)MEM_TO_SHADOW((uptr)data), shadow, size); } @@ -353,7 +392,7 @@ void __msan_load_unpoisoned(void *src, uptr size, void *dst) { __msan_unpoison(dst, size); } -void __msan_set_origin(void *a, uptr size, u32 origin) { +void __msan_set_origin(const void *a, uptr size, u32 origin) { // Origin mapping is 4 bytes per 4 bytes of application memory. // Here we extend the range such that its left and right bounds are both // 4 byte aligned. @@ -407,7 +446,7 @@ const char *__msan_get_origin_descr_if_stack(u32 id) { } -u32 __msan_get_origin(void *a) { +u32 __msan_get_origin(const void *a) { if (!__msan_track_origins) return 0; uptr x = (uptr)a; uptr aligned = x & ~3ULL; @@ -415,6 +454,14 @@ u32 __msan_get_origin(void *a) { return *(u32*)origin_ptr; } -u32 __msan_get_origin_tls() { +u32 __msan_get_umr_origin() { return __msan_origin_tls; } + +#if !SANITIZER_SUPPORTS_WEAK_HOOKS +extern "C" { +SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE +const char* __msan_default_options() { return ""; } +} // extern "C" +#endif + |