[compiler-rt] r197226 - [msan] Wrap indirect calls from sanitizer rtl when running under DR.
Evgeniy Stepanov
eugeni.stepanov at gmail.com
Fri Dec 13 05:13:48 PST 2013
Author: eugenis
Date: Fri Dec 13 07:13:46 2013
New Revision: 197226
URL: http://llvm.org/viewvc/llvm-project?rev=197226&view=rev
Log:
[msan] Wrap indirect calls from sanitizer rtl when running under DR.
Added:
compiler-rt/trunk/lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc (with props)
Modified:
compiler-rt/trunk/lib/msan/msan.cc
compiler-rt/trunk/lib/msan/msan_flags.h
compiler-rt/trunk/lib/msan/msan_interceptors.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc
Added: compiler-rt/trunk/lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc?rev=197226&view=auto
==============================================================================
--- compiler-rt/trunk/lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc (added)
+++ compiler-rt/trunk/lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc Fri Dec 13 07:13:46 2013
@@ -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;
+}
Propchange: compiler-rt/trunk/lib/msan/lit_tests/wrap_indirect_calls_in_rtl.cc
------------------------------------------------------------------------------
svn:eol-style = LF
Modified: compiler-rt/trunk/lib/msan/msan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.cc?rev=197226&r1=197225&r2=197226&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.cc (original)
+++ compiler-rt/trunk/lib/msan/msan.cc Fri Dec 13 07:13:46 2013
@@ -134,6 +134,7 @@ static void ParseFlagsFromString(Flags *
}
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, co
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) {
Modified: compiler-rt/trunk/lib/msan/msan_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_flags.h?rev=197226&r1=197225&r2=197226&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_flags.h (original)
+++ compiler-rt/trunk/lib/msan/msan_flags.h Fri Dec 13 07:13:46 2013
@@ -26,6 +26,7 @@ struct Flags {
bool report_umrs;
bool wrap_signals;
bool halt_on_error;
+ const char *wrap_indirect_calls;
};
Flags *flags();
Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=197226&r1=197225&r2=197226&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Fri Dec 13 07:13:46 2013
@@ -948,7 +948,7 @@ static int msan_dl_iterate_phdr_cb(__san
}
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
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 *a
&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);
}
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=197226&r1=197225&r2=197226&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Fri Dec 13 07:13:46 2013
@@ -483,6 +483,23 @@ const uptr kPthreadDestructorIterations
// Callback type for iterating over a set of memory ranges.
typedef void (*RangeIteratorCallback)(uptr begin, uptr end, void *arg);
+
+#if SANITIZER_LINUX
+extern uptr indirect_call_wrapper;
+void InitializeIndirectCallWrapping(const char *wrapper_name);
+
+template <typename F>
+F IndirectExternCall(F f) {
+ typedef F (*WrapF)(F);
+ return indirect_call_wrapper ? ((WrapF)indirect_call_wrapper)(f) : f;
+}
+#else
+inline void InitializeIndirectCallWrapping(const char *wrapper_name) {}
+template <typename F>
+F IndirectExternCall(F f) {
+ return f;
+}
+#endif
} // namespace __sanitizer
inline void *operator new(__sanitizer::operator_new_size_type size,
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=197226&r1=197225&r2=197226&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Fri Dec 13 07:13:46 2013
@@ -867,30 +867,30 @@ static THREADLOCAL void *glob_ctx;
static void wrapped_gl_closedir(void *dir) {
COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1);
- pglob_copy->gl_closedir(dir);
+ IndirectExternCall(pglob_copy->gl_closedir)(dir);
}
static void *wrapped_gl_readdir(void *dir) {
COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1);
- return pglob_copy->gl_readdir(dir);
+ return IndirectExternCall(pglob_copy->gl_readdir)(dir);
}
static void *wrapped_gl_opendir(const char *s) {
COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1);
COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1);
- return pglob_copy->gl_opendir(s);
+ return IndirectExternCall(pglob_copy->gl_opendir)(s);
}
static int wrapped_gl_lstat(const char *s, void *st) {
COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2);
COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1);
- return pglob_copy->gl_lstat(s, st);
+ return IndirectExternCall(pglob_copy->gl_lstat)(s, st);
}
static int wrapped_gl_stat(const char *s, void *st) {
COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2);
COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1);
- return pglob_copy->gl_stat(s, st);
+ return IndirectExternCall(pglob_copy->gl_stat)(s, st);
}
INTERCEPTOR(int, glob, const char *pattern, int flags,
@@ -1899,7 +1899,7 @@ static THREADLOCAL scandir_compar_f scan
static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 1);
COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, dir, dir->d_reclen);
- return scandir_filter(dir);
+ return IndirectExternCall(scandir_filter)(dir);
}
static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
@@ -1909,7 +1909,7 @@ static int wrapped_scandir_compar(const
COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *a, (*a)->d_reclen);
COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, b, sizeof(*b));
COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *b, (*b)->d_reclen);
- return scandir_compar(a, b);
+ return IndirectExternCall(scandir_compar)(a, b);
}
INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
@@ -1952,7 +1952,7 @@ static THREADLOCAL scandir64_compar_f sc
static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 1);
COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, dir, dir->d_reclen);
- return scandir64_filter(dir);
+ return IndirectExternCall(scandir64_filter)(dir);
}
static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
@@ -1962,7 +1962,7 @@ static int wrapped_scandir64_compar(cons
COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *a, (*a)->d_reclen);
COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, b, sizeof(*b));
COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *b, (*b)->d_reclen);
- return scandir64_compar(a, b);
+ return IndirectExternCall(scandir64_compar)(a, b);
}
INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc?rev=197226&r1=197225&r2=197226&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux_libcdep.cc Fri Dec 13 07:13:46 2013
@@ -98,7 +98,7 @@ bool SetEnv(const char *name, const char
setenv_ft setenv_f;
CHECK_EQ(sizeof(setenv_f), sizeof(f));
internal_memcpy(&setenv_f, &f, sizeof(f));
- return setenv_f(name, value, 1) == 0;
+ return IndirectExternCall(setenv_f)(name, value, 1) == 0;
}
#endif
@@ -196,7 +196,7 @@ void InitTlsSize() {
CHECK_NE(get_tls, 0);
size_t tls_size = 0;
size_t tls_align = 0;
- get_tls(&tls_size, &tls_align);
+ IndirectExternCall(get_tls)(&tls_size, &tls_align);
g_tls_size = tls_size;
#endif
}
@@ -353,6 +353,13 @@ uptr GetListOfModules(LoadedModule *modu
}
#endif // SANITIZER_ANDROID
+uptr indirect_call_wrapper;
+
+void InitializeIndirectCallWrapping(const char *wrapper_name) {
+ CHECK(wrapper_name && *wrapper_name);
+ indirect_call_wrapper = (uptr)dlsym(RTLD_DEFAULT, wrapper_name);
+}
+
} // namespace __sanitizer
#endif // SANITIZER_LINUX
More information about the llvm-commits
mailing list