summaryrefslogtreecommitdiff
path: root/lib/msan/msan.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/msan/msan.cc')
-rw-r--r--lib/msan/msan.cc89
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
+