[compiler-rt] r189342 - [msan] Fix a data race in signal/sigaction interceptors.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Tue Aug 27 04:34:05 PDT 2013


Author: eugenis
Date: Tue Aug 27 06:34:05 2013
New Revision: 189342

URL: http://llvm.org/viewvc/llvm-project?rev=189342&view=rev
Log:
[msan] Fix a data race in signal/sigaction interceptors.

Modified:
    compiler-rt/trunk/lib/msan/msan_interceptors.cc

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=189342&r1=189341&r2=189342&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Tue Aug 27 06:34:05 2013
@@ -19,6 +19,7 @@
 #include "msan.h"
 #include "sanitizer_common/sanitizer_platform_limits_posix.h"
 #include "sanitizer_common/sanitizer_allocator.h"
+#include "sanitizer_common/sanitizer_atomic.h"
 #include "sanitizer_common/sanitizer_common.h"
 #include "sanitizer_common/sanitizer_stackdepot.h"
 #include "sanitizer_common/sanitizer_libc.h"
@@ -30,6 +31,11 @@
 
 using namespace __msan;
 
+using __sanitizer::memory_order;
+using __sanitizer::atomic_load;
+using __sanitizer::atomic_store;
+using __sanitizer::atomic_uintptr_t;
+
 // True if this is a nested interceptor.
 static THREADLOCAL int in_interceptor_scope;
 
@@ -897,13 +903,17 @@ INTERCEPTOR(int, getrusage, int who, voi
   return res;
 }
 
+// sigactions_mu guarantees atomicity of sigaction() and signal() calls.
+// Access to sigactions[] is gone with relaxed atomics to avoid data race with
+// the signal handler.
 const int kMaxSignals = 1024;
-static uptr sigactions[kMaxSignals];
+static atomic_uintptr_t sigactions[kMaxSignals];
 static StaticSpinMutex sigactions_mu;
 
 static void SignalHandler(int signo) {
   typedef void (*signal_cb)(int x);
-  signal_cb cb = (signal_cb)sigactions[signo];
+  signal_cb cb =
+      (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
   cb(signo);
 }
 
@@ -913,7 +923,8 @@ static void SignalAction(int signo, void
   __msan_unpoison(uc, __sanitizer::ucontext_t_sz);
 
   typedef void (*sigaction_cb)(int, void *, void *);
-  sigaction_cb cb = (sigaction_cb)sigactions[signo];
+  sigaction_cb cb =
+      (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
   cb(signo, si, uc);
 }
 
@@ -926,7 +937,7 @@ INTERCEPTOR(int, sigaction, int signo, c
   if (flags()->wrap_signals) {
     SpinMutexLock lock(&sigactions_mu);
     CHECK_LT(signo, kMaxSignals);
-    uptr old_cb = sigactions[signo];
+    uptr old_cb = atomic_load(&sigactions[signo], memory_order_relaxed);
     __sanitizer_sigaction new_act;
     __sanitizer_sigaction *pnew_act = act ? &new_act : 0;
     if (act) {
@@ -936,7 +947,7 @@ INTERCEPTOR(int, sigaction, int signo, c
                         ? (uptr)SignalAction
                         : (uptr)SignalHandler;
       if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
-        sigactions[signo] = cb;
+        atomic_store(&sigactions[signo], cb, memory_order_relaxed);
         pnew_act->sa_sigaction = (void (*)(int, void *, void *))new_cb;
       }
     }
@@ -963,7 +974,7 @@ INTERCEPTOR(int, signal, int signo, uptr
     CHECK_LT(signo, kMaxSignals);
     SpinMutexLock lock(&sigactions_mu);
     if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
-      sigactions[signo] = cb;
+      atomic_store(&sigactions[signo], cb, memory_order_relaxed);
       cb = (uptr) SignalHandler;
     }
     return REAL(signal)(signo, cb);





More information about the llvm-commits mailing list