From 5ca98eb8b8791e514a98c1b22803a93a9735dd6c Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Fri, 13 Dec 2013 13:13:46 +0000 Subject: [msan] Wrap indirect calls from sanitizer rtl when running under DR. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@197226 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc | 39 ++++++++++++++++++++++++ lib/msan/msan.cc | 5 +++ lib/msan/msan_flags.h | 1 + lib/msan/msan_interceptors.cc | 10 +++--- 4 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc (limited to 'lib/msan') diff --git a/lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc b/lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc new file mode 100644 index 000000000..18de9d705 --- /dev/null +++ b/lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc @@ -0,0 +1,39 @@ +// Test indirect call wrapping in MemorySanitizer runtime. + +// RUN: %clangxx_msan -O0 -g -rdynamic %s -o %t +// RUN: MSAN_OPTIONS=wrap_indirect_calls=zzzwrapper %t + +#include +#include +#include +#include + +bool done; + +void *ThreadFn(void *) { + printf("bad threadfn\n"); + return 0; +} + +void *ThreadFn2(void *) { + printf("good threadfn\n"); + done = true; + return 0; +} + +// 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) { + if (f == (uintptr_t)ThreadFn) + return (uintptr_t)&ThreadFn2; + return f; +} + +int main(void) { + pthread_t t; + pthread_create(&t, 0, ThreadFn, 0); + pthread_join(t, 0); + assert(done); + return 0; +} diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc index 737e120a0..ae1011314 100644 --- a/lib/msan/msan.cc +++ b/lib/msan/msan.cc @@ -134,6 +134,7 @@ 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. @@ -158,6 +159,7 @@ 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. @@ -331,8 +333,11 @@ void __msan_init() { &msan_stack_bounds.tls_addr, &msan_stack_bounds.tls_size); VPrintf(1, "MemorySanitizer init done\n"); + msan_init_is_running = 0; msan_inited = 1; + + InitializeIndirectCallWrapping(flags()->wrap_indirect_calls); } void __msan_set_exit_code(int exit_code) { diff --git a/lib/msan/msan_flags.h b/lib/msan/msan_flags.h index 93fa8a60d..9cf48e604 100644 --- a/lib/msan/msan_flags.h +++ b/lib/msan/msan_flags.h @@ -26,6 +26,7 @@ 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_interceptors.cc b/lib/msan/msan_interceptors.cc index 118964409..13c922841 100644 --- a/lib/msan/msan_interceptors.cc +++ b/lib/msan/msan_interceptors.cc @@ -948,7 +948,7 @@ static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size, } dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data; UnpoisonParam(3); - return cbdata->callback(info, size, cbdata->data); + return IndirectExternCall(cbdata->callback)(info, size, cbdata->data); } INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) { @@ -985,7 +985,7 @@ static void SignalHandler(int signo) { typedef void (*signal_cb)(int x); signal_cb cb = (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed); - cb(signo); + IndirectExternCall(cb)(signo); } static void SignalAction(int signo, void *si, void *uc) { @@ -997,7 +997,7 @@ static void SignalAction(int signo, void *si, void *uc) { typedef void (*sigaction_cb)(int, void *, void *); sigaction_cb cb = (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed); - cb(signo, si, uc); + IndirectExternCall(cb)(signo, si, uc); } INTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act, @@ -1098,7 +1098,7 @@ static void *MsanThreadStartFunc(void *arg) { &msan_stack_bounds.stack_size, &msan_stack_bounds.tls_addr, &msan_stack_bounds.tls_size); - return callback(param); + return IndirectExternCall(callback)(param); } INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), @@ -1168,7 +1168,7 @@ struct MSanAtExitRecord { void MSanAtExitWrapper(void *arg) { UnpoisonParam(1); MSanAtExitRecord *r = (MSanAtExitRecord *)arg; - r->func(r->arg); + IndirectExternCall(r->func)(r->arg); InternalFree(r); } -- cgit v1.2.3