summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/msan/msan.cc2
-rw-r--r--compiler-rt/lib/msan/msan_interceptors.cc8
-rw-r--r--compiler-rt/lib/msan/msan_thread.h6
-rw-r--r--compiler-rt/test/msan/chained_origin_with_signals.cc32
4 files changed, 48 insertions, 0 deletions
diff --git a/compiler-rt/lib/msan/msan.cc b/compiler-rt/lib/msan/msan.cc
index db92a5f3cf8..8bf7c48acc7 100644
--- a/compiler-rt/lib/msan/msan.cc
+++ b/compiler-rt/lib/msan/msan.cc
@@ -237,6 +237,8 @@ const char *GetOriginDescrIfStack(u32 id, uptr *pc) {
}
u32 ChainOrigin(u32 id, StackTrace *stack) {
+ if (GetCurrentThread()->InSignalHandler())
+ return id;
uptr idx = Min(stack->size, kStackTraceMax - 1);
stack->trace[idx] = TRACE_MAKE_CHAINED(id);
u32 new_id = StackDepotPut(stack->trace, idx + 1);
diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc
index 5205094fb97..2062f7f4b06 100644
--- a/compiler-rt/lib/msan/msan_interceptors.cc
+++ b/compiler-rt/lib/msan/msan_interceptors.cc
@@ -981,6 +981,12 @@ INTERCEPTOR(int, getrusage, int who, void *usage) {
return res;
}
+class SignalHandlerScope {
+ public:
+ SignalHandlerScope() { GetCurrentThread()->EnterSignalHandler(); }
+ ~SignalHandlerScope() { GetCurrentThread()->LeaveSignalHandler(); }
+};
+
// 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.
@@ -989,6 +995,7 @@ static atomic_uintptr_t sigactions[kMaxSignals];
static StaticSpinMutex sigactions_mu;
static void SignalHandler(int signo) {
+ SignalHandlerScope signal_handler_scope;
ScopedThreadLocalStateBackup stlsb;
UnpoisonParam(1);
@@ -999,6 +1006,7 @@ static void SignalHandler(int signo) {
}
static void SignalAction(int signo, void *si, void *uc) {
+ SignalHandlerScope signal_handler_scope;
ScopedThreadLocalStateBackup stlsb;
UnpoisonParam(3);
__msan_unpoison(si, sizeof(__sanitizer_sigaction));
diff --git a/compiler-rt/lib/msan/msan_thread.h b/compiler-rt/lib/msan/msan_thread.h
index 82ed96c0a66..bc605b89a50 100644
--- a/compiler-rt/lib/msan/msan_thread.h
+++ b/compiler-rt/lib/msan/msan_thread.h
@@ -38,6 +38,10 @@ class MsanThread {
return addr >= stack_bottom_ && addr < stack_top_;
}
+ bool InSignalHandler() { return in_signal_handler_; }
+ void EnterSignalHandler() { in_signal_handler_++; }
+ void LeaveSignalHandler() { in_signal_handler_--; }
+
MsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
int destructor_iterations_;
@@ -54,6 +58,8 @@ class MsanThread {
uptr tls_begin_;
uptr tls_end_;
+ unsigned in_signal_handler_;
+
MsanThreadLocalMallocStorage malloc_storage_;
};
diff --git a/compiler-rt/test/msan/chained_origin_with_signals.cc b/compiler-rt/test/msan/chained_origin_with_signals.cc
new file mode 100644
index 00000000000..7141d41e028
--- /dev/null
+++ b/compiler-rt/test/msan/chained_origin_with_signals.cc
@@ -0,0 +1,32 @@
+// Check that stores in signal handlers are not recorded in origin history.
+// This is, in fact, undesired behavior caused by our chained origins
+// implementation being not async-signal-safe.
+
+// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -O3 %s -o %t && \
+// RUN: not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+
+#include <signal.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+volatile int x, y;
+
+void SignalHandler(int signo) {
+ y = x;
+}
+
+int main(int argc, char *argv[]) {
+ int volatile z;
+ x = z;
+
+ signal(SIGUSR1, SignalHandler);
+ kill(getpid(), SIGUSR1);
+ signal(SIGUSR1, SIG_DFL);
+
+ return y;
+}
+
+// CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
+// CHECK-NOT: in SignalHandler
OpenPOWER on IntegriCloud