forked from OSchip/llvm-project
[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:
parent
bf58a6a892
commit
5a7c364343
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue