diff --git a/compiler-rt/lib/msan/msan_poisoning.cpp b/compiler-rt/lib/msan/msan_poisoning.cpp --- a/compiler-rt/lib/msan/msan_poisoning.cpp +++ b/compiler-rt/lib/msan/msan_poisoning.cpp @@ -14,6 +14,7 @@ #include "interception/interception.h" #include "msan_origin.h" +#include "msan_thread.h" #include "sanitizer_common/sanitizer_common.h" DECLARE_REAL(void *, memset, void *dest, int c, uptr n) @@ -241,6 +242,9 @@ SetShadow(dst, size, (u8)-1); if (__msan_get_track_origins()) { + MsanThread *t = GetCurrentThread(); + if (t && t->InSignalHandler()) + return; Origin o = Origin::CreateHeapOrigin(stack); SetOrigin(dst, size, o.raw_id()); } diff --git a/compiler-rt/test/msan/poison_in_signal.cpp b/compiler-rt/test/msan/poison_in_signal.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/msan/poison_in_signal.cpp @@ -0,0 +1,63 @@ +// Stress test of poisoning from signal handler. + +// RUN: %clangxx_msan -std=c++11 -O2 %s -o %t && %run %t +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -std=c++11 -O2 %s -o %t && %run %t +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -fsanitize-memory-use-after-dtor -std=c++11 -O2 %s -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t + +#include +#include +#include +#include +#include + +#include + +std::atomic n = {1000}; + +struct Tmp { + char buff[1]; + ~Tmp() {} +}; + +__attribute__((noinline, optnone)) void Poison() { + // use-after-dtor. + volatile Tmp t; + // Regular poisoning. + __msan_poison(&t, sizeof(t)); +} + +void *thr(void *p) { + for (; n >= 0;) { + for (int i = 0; i < 1000; i++) { + Poison(); + } + } + return 0; +} + +void handler(int) { + Poison(); + --n; +} + +int main(int argc, char **argv) { + const int kThreads = 10; + pthread_t th[kThreads]; + for (int i = 0; i < kThreads; i++) + pthread_create(&th[i], 0, thr, 0); + + struct sigaction sa = {}; + sa.sa_handler = handler; + assert(!sigaction(SIGPROF, &sa, 0)); + + itimerval t; + t.it_value.tv_sec = 0; + t.it_value.tv_usec = 10; + t.it_interval = t.it_value; + assert(!setitimer(ITIMER_PROF, &t, 0)); + + for (int i = 0; i < kThreads; i++) + pthread_join(th[i], 0); + + return 0; +}