[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