summaryrefslogtreecommitdiff
path: root/lib/msan/msan_interceptors.cc
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-08-27 11:34:05 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-08-27 11:34:05 +0000
commite0a871284c7496b91add2956531d1a9e65b7bc88 (patch)
tree47c402ab1c92d86c98c917178c3a80ce6433098e /lib/msan/msan_interceptors.cc
parent47177efc15d2a75c7c85ba31aa61e41e7b47b5a3 (diff)
downloadcompiler-rt-e0a871284c7496b91add2956531d1a9e65b7bc88.tar.gz
compiler-rt-e0a871284c7496b91add2956531d1a9e65b7bc88.tar.bz2
compiler-rt-e0a871284c7496b91add2956531d1a9e65b7bc88.tar.xz
[msan] Fix a data race in signal/sigaction interceptors.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@189342 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/msan/msan_interceptors.cc')
-rw-r--r--lib/msan/msan_interceptors.cc23
1 files changed, 17 insertions, 6 deletions
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc
index 6d511179..5e89ef54 100644
--- a/lib/msan/msan_interceptors.cc
+++ b/lib/msan/msan_interceptors.cc
@@ -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, void *usage) {
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 *si, void *uc) {
__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, const __sanitizer_sigaction *act,
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, const __sanitizer_sigaction *act,
? (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 cb) {
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);