summaryrefslogtreecommitdiff
path: root/lib/msan
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-12-13 13:13:46 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-12-13 13:13:46 +0000
commit5ca98eb8b8791e514a98c1b22803a93a9735dd6c (patch)
treefac6b8002fe9a3542155615c1f41d02e4b8a3a14 /lib/msan
parent464a26f94e2f24a7708867b93fc2d9c92c399e6a (diff)
[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
Diffstat (limited to 'lib/msan')
-rw-r--r--lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc39
-rw-r--r--lib/msan/msan.cc5
-rw-r--r--lib/msan/msan_flags.h1
-rw-r--r--lib/msan/msan_interceptors.cc10
4 files changed, 50 insertions, 5 deletions
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 <assert.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdint.h>
+
+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);
}