[msan] Disable chained origins in signal handlers.

StackDepot is not async-signal-safe; storing a new origin to it can deadlock.

llvm-svn: 206983
This commit is contained in:
Evgeniy Stepanov 2014-04-23 14:01:57 +00:00
parent bf58a6a892
commit 5a7c364343
4 changed files with 48 additions and 0 deletions

View File

@ -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);

View File

@ -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));

View File

@ -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_;
};

View File

@ -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