[compiler-rt] r189343 - [msan] Unpoison all TLS shadow when leaving a signal handler.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Tue Aug 27 05:59:39 PDT 2013


Author: eugenis
Date: Tue Aug 27 07:59:39 2013
New Revision: 189343

URL: http://llvm.org/viewvc/llvm-project?rev=189343&view=rev
Log:
[msan] Unpoison all TLS shadow when leaving a signal handler.

Added:
    compiler-rt/trunk/lib/msan/lit_tests/signal_stress_test.cc   (with props)
Modified:
    compiler-rt/trunk/lib/msan/msan.cc
    compiler-rt/trunk/lib/msan/msan.h
    compiler-rt/trunk/lib/msan/msan_interceptors.cc

Added: compiler-rt/trunk/lib/msan/lit_tests/signal_stress_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/lit_tests/signal_stress_test.cc?rev=189343&view=auto
==============================================================================
--- compiler-rt/trunk/lib/msan/lit_tests/signal_stress_test.cc (added)
+++ compiler-rt/trunk/lib/msan/lit_tests/signal_stress_test.cc Tue Aug 27 07:59:39 2013
@@ -0,0 +1,71 @@
+// RUN: %clangxx_msan -O0 %s -o %t && %t
+
+// Test that va_arg shadow from a signal handler does not leak outside.
+
+#include <signal.h>
+#include <stdarg.h>
+#include <sanitizer/msan_interface.h>
+#include <assert.h>
+#include <sys/time.h>
+#include <stdio.h>
+
+const int kArgCnt = 20;
+const int kSigCnt = 100;
+
+volatile int z;
+
+void f(bool poisoned, ...) {
+  va_list vl;
+  va_start(vl, poisoned);
+  for (int i = 0; i < kArgCnt; ++i) {
+    void *p = va_arg(vl, void *);
+    if (poisoned)
+      assert(__msan_test_shadow(&p, sizeof(p)) == 0);
+    else 
+      assert(__msan_test_shadow(&p, sizeof(p)) == -1);
+  }
+  va_end(vl);
+}
+
+int sigcnt;
+
+void SignalHandler(int signo) {
+  assert(signo == SIGPROF);
+  void *p;
+  void ** volatile q = &p;
+  f(true,
+      *q, *q, *q, *q, *q,
+      *q, *q, *q, *q, *q,
+      *q, *q, *q, *q, *q,
+      *q, *q, *q, *q, *q,
+      *q, *q, *q, *q, *q);
+  ++sigcnt;
+}
+
+int main() {
+  signal(SIGPROF, SignalHandler);
+
+  itimerval itv;
+  itv.it_interval.tv_sec = 0;
+  itv.it_interval.tv_usec = 100;
+  itv.it_value.tv_sec = 0;
+  itv.it_value.tv_usec = 100;
+  setitimer(ITIMER_PROF, &itv, NULL);
+
+  do {
+    f(false,
+        0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0);
+  } while (sigcnt < kSigCnt);
+
+  itv.it_interval.tv_sec = 0;
+  itv.it_interval.tv_usec = 0;
+  itv.it_value.tv_sec = 0;
+  itv.it_value.tv_usec = 0;
+  setitimer(ITIMER_PROF, &itv, NULL);
+
+  signal(SIGPROF, SIG_DFL);
+  return 0;
+}

Propchange: compiler-rt/trunk/lib/msan/lit_tests/signal_stress_test.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=189343&r1=189342&r2=189343&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.cc (original)
+++ compiler-rt/trunk/lib/msan/msan.cc Tue Aug 27 07:59:39 2013
@@ -230,6 +230,13 @@ void UnpoisonParam(uptr n) {
   internal_memset(__msan_param_tls, 0, n * sizeof(*__msan_param_tls));
 }
 
+void UnpoisonThreadLocalState() {
+  internal_memset(__msan_param_tls, 0, sizeof(__msan_param_tls));
+  internal_memset(__msan_retval_tls, 0, sizeof(__msan_retval_tls));
+  internal_memset(__msan_va_arg_tls, 0, sizeof(__msan_va_arg_tls));
+  __msan_va_arg_overflow_size_tls = 0;
+}
+
 }  // namespace __msan
 
 // Interface.

Modified: compiler-rt/trunk/lib/msan/msan.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.h?rev=189343&r1=189342&r2=189343&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.h (original)
+++ compiler-rt/trunk/lib/msan/msan.h Tue Aug 27 07:59:39 2013
@@ -76,6 +76,7 @@ void ReportAtExitStatistics();
 
 // Unpoison first n function arguments.
 void UnpoisonParam(uptr n);
+void UnpoisonThreadLocalState();
 
 #define GET_MALLOC_STACK_TRACE                                     \
   StackTrace stack;                                                \

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=189343&r1=189342&r2=189343&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Tue Aug 27 07:59:39 2013
@@ -911,10 +911,14 @@ static atomic_uintptr_t sigactions[kMaxS
 static StaticSpinMutex sigactions_mu;
 
 static void SignalHandler(int signo) {
+  UnpoisonParam(1);
+
   typedef void (*signal_cb)(int x);
   signal_cb cb =
       (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
   cb(signo);
+
+  UnpoisonThreadLocalState();
 }
 
 static void SignalAction(int signo, void *si, void *uc) {
@@ -926,6 +930,8 @@ static void SignalAction(int signo, void
   sigaction_cb cb =
       (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
   cb(signo, si, uc);
+
+  UnpoisonThreadLocalState();
 }
 
 INTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act,





More information about the llvm-commits mailing list