diff options
-rw-r--r-- | lib/msan/lit_tests/wrap_indirect_calls2.cc | 42 | ||||
-rw-r--r-- | lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc | 8 | ||||
-rw-r--r-- | lib/msan/msan.cc | 24 | ||||
-rw-r--r-- | lib/msan/msan_flags.h | 1 | ||||
-rw-r--r-- | lib/msan/msan_interface_internal.h | 9 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common.h | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_linux_libcdep.cc | 5 |
7 files changed, 73 insertions, 20 deletions
diff --git a/lib/msan/lit_tests/wrap_indirect_calls2.cc b/lib/msan/lit_tests/wrap_indirect_calls2.cc new file mode 100644 index 000000000..c188047ce --- /dev/null +++ b/lib/msan/lit_tests/wrap_indirect_calls2.cc @@ -0,0 +1,42 @@ +// Test __msan_set_indirect_call_wrapper. + +// RUN: %clangxx_msan -mllvm -msan-wrap-indirect-calls=__msan_wrap_indirect_call \ +// RUN: -mllvm -msan-wrap-indirect-calls-fast=0 \ +// RUN: -O0 -g -rdynamic -Wl,--defsym=__executable_start=0 %s -o %t && %t + +// This test disables -msan-wrap-indirect-calls-fast, otherwise indirect calls +// inside the same module are short-circuited and are never seen by the wrapper. + +#include <assert.h> +#include <pthread.h> +#include <stdio.h> +#include <stdint.h> + +extern "C" void __msan_set_indirect_call_wrapper(uintptr_t); + +bool done_f, done_g; + +void f(void) { + assert(!done_g); + done_f = true; +} + +void g(void) { + assert(done_f); + done_g = true; +} + +typedef void (*Fn)(void); +extern "C" Fn my_wrapper(Fn target) { + if (target == f) return g; + return target; +} + +int main(void) { + volatile Fn fp; + fp = &f; + fp(); + __msan_set_indirect_call_wrapper((uintptr_t)my_wrapper); + fp(); + return !(done_f && done_g); +} diff --git a/lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc b/lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc index 18de9d705..b13caee33 100644 --- a/lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc +++ b/lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc @@ -1,13 +1,14 @@ // Test indirect call wrapping in MemorySanitizer runtime. -// RUN: %clangxx_msan -O0 -g -rdynamic %s -o %t -// RUN: MSAN_OPTIONS=wrap_indirect_calls=zzzwrapper %t +// RUN: %clangxx_msan -O0 -g -rdynamic %s -o %t && %t #include <assert.h> #include <pthread.h> #include <stdio.h> #include <stdint.h> +extern "C" void __msan_set_indirect_call_wrapper(uintptr_t); + bool done; void *ThreadFn(void *) { @@ -24,13 +25,14 @@ void *ThreadFn2(void *) { // ThreadFn is called indirectly from a wrapper function in MSan rtl and // is subject to indirect call wrapping (it could be an native-to-translated // edge). -extern "C" uintptr_t zzzwrapper(uintptr_t f) { +extern "C" uintptr_t my_wrapper(uintptr_t f) { if (f == (uintptr_t)ThreadFn) return (uintptr_t)&ThreadFn2; return f; } int main(void) { + __msan_set_indirect_call_wrapper((uintptr_t)my_wrapper); pthread_t t; pthread_create(&t, 0, ThreadFn, 0); pthread_join(t, 0); diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc index cee62c520..c9c3b8acf 100644 --- a/lib/msan/msan.cc +++ b/lib/msan/msan.cc @@ -31,7 +31,7 @@ using namespace __sanitizer; static THREADLOCAL int msan_expect_umr = 0; static THREADLOCAL int msan_expected_umr_found = 0; -static int msan_running_under_dr = 0; +static bool msan_running_under_dr; // Function argument shadow. Each argument starts at the next available 8-byte // aligned address. @@ -74,10 +74,6 @@ extern "C" SANITIZER_WEAK_ATTRIBUTE const int __msan_keep_going; namespace __msan { -static bool IsRunningUnderDr() { - return false; -} - void EnterSymbolizer() { ++is_in_symbolizer; } void ExitSymbolizer() { --is_in_symbolizer; } bool IsInSymbolizer() { return is_in_symbolizer; } @@ -122,7 +118,6 @@ static void ParseFlagsFromString(Flags *f, const char *str) { } ParseFlag(str, &f->report_umrs, "report_umrs"); ParseFlag(str, &f->wrap_signals, "wrap_signals"); - ParseFlag(str, &f->wrap_indirect_calls, "wrap_indirect_calls"); // keep_going is an old name for halt_on_error, // and it has inverse meaning. @@ -147,7 +142,6 @@ static void InitializeFlags(Flags *f, const char *options) { f->exit_code = 77; f->report_umrs = true; f->wrap_signals = true; - f->wrap_indirect_calls = "dr_app_handle_mbr_target"; f->halt_on_error = !&__msan_keep_going; // Override from user-specified string. @@ -292,7 +286,6 @@ void __msan_init() { VPrintf(1, "MSAN_OPTIONS: %s\n", msan_options ? msan_options : "<empty>"); - msan_running_under_dr = IsRunningUnderDr(); __msan_clear_on_return(); if (__msan_get_track_origins()) VPrintf(1, "msan_track_origins\n"); @@ -324,8 +317,6 @@ void __msan_init() { msan_init_is_running = 0; msan_inited = 1; - - InitializeIndirectCallWrapping(flags()->wrap_indirect_calls); } void __msan_set_exit_code(int exit_code) { @@ -542,10 +533,21 @@ void __sanitizer_unaligned_store64(uu64 *p, u64 x) { *p = x; } +void *__msan_wrap_indirect_call(void *target) { + return IndirectExternCall(target); +} + +void __msan_dr_is_initialized() { + msan_running_under_dr = true; +} + +void __msan_set_indirect_call_wrapper(uptr wrapper) { + SetIndirectCallWrapper(wrapper); +} + #if !SANITIZER_SUPPORTS_WEAK_HOOKS extern "C" { SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE const char* __msan_default_options() { return ""; } } // extern "C" #endif - diff --git a/lib/msan/msan_flags.h b/lib/msan/msan_flags.h index 9cf48e604..93fa8a60d 100644 --- a/lib/msan/msan_flags.h +++ b/lib/msan/msan_flags.h @@ -26,7 +26,6 @@ struct Flags { bool report_umrs; bool wrap_signals; bool halt_on_error; - const char *wrap_indirect_calls; }; Flags *flags(); diff --git a/lib/msan/msan_interface_internal.h b/lib/msan/msan_interface_internal.h index 794b3540f..c87b2bad2 100644 --- a/lib/msan/msan_interface_internal.h +++ b/lib/msan/msan_interface_internal.h @@ -170,6 +170,15 @@ SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE /* OPTIONAL */ void __msan_free_hook(void *ptr); + +SANITIZER_INTERFACE_ATTRIBUTE +void __msan_dr_is_initialized(); + +SANITIZER_INTERFACE_ATTRIBUTE +void *__msan_wrap_indirect_call(void *target); + +SANITIZER_INTERFACE_ATTRIBUTE +void __msan_set_indirect_call_wrapper(uptr wrapper); } // extern "C" #endif // MSAN_INTERFACE_INTERNAL_H diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h index b61e9a0f6..f9fc254e5 100644 --- a/lib/sanitizer_common/sanitizer_common.h +++ b/lib/sanitizer_common/sanitizer_common.h @@ -487,7 +487,7 @@ typedef void (*RangeIteratorCallback)(uptr begin, uptr end, void *arg); #if SANITIZER_LINUX && !defined(SANITIZER_GO) extern uptr indirect_call_wrapper; -void InitializeIndirectCallWrapping(const char *wrapper_name); +void SetIndirectCallWrapper(uptr wrapper); template <typename F> F IndirectExternCall(F f) { @@ -495,7 +495,7 @@ F IndirectExternCall(F f) { return indirect_call_wrapper ? ((WrapF)indirect_call_wrapper)(f) : f; } #else -inline void InitializeIndirectCallWrapping(const char *wrapper_name) {} +inline void SetIndirectCallWrapper(uptr wrapper) {} template <typename F> F IndirectExternCall(F f) { return f; diff --git a/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_linux_libcdep.cc index 890dd8f99..ec8125dbc 100644 --- a/lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -356,9 +356,8 @@ uptr GetListOfModules(LoadedModule *modules, uptr max_modules, #ifndef SANITIZER_GO uptr indirect_call_wrapper; -void InitializeIndirectCallWrapping(const char *wrapper_name) { - CHECK(wrapper_name && *wrapper_name); - indirect_call_wrapper = (uptr)dlsym(RTLD_DEFAULT, wrapper_name); +void SetIndirectCallWrapper(uptr wrapper) { + indirect_call_wrapper = wrapper; } #endif |