summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorVitaly Buka <vitalybuka@google.com>2017-11-13 20:49:14 +0000
committerVitaly Buka <vitalybuka@google.com>2017-11-13 20:49:14 +0000
commit98ddb4f6276ab88c6ce0735490a208d573788389 (patch)
treea3c445ecb7aba8929aec07de0964262763b5c71c /lib
parent82cd00ab016a2197f9fa26d38fbfdad75af76c31 (diff)
[tsan] Fix signal chaining
Summary: Return saved values only if installed sigaction is our wrapper. Reviewers: eugenis, dvyukov Subscribers: llvm-commits, kubamracek Differential Revision: https://reviews.llvm.org/D39935 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@318082 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/tsan/rtl/tsan_interceptors.cc11
1 files changed, 9 insertions, 2 deletions
diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc
index d7b3f5f01..eb51a0a4e 100644
--- a/lib/tsan/rtl/tsan_interceptors.cc
+++ b/lib/tsan/rtl/tsan_interceptors.cc
@@ -2276,7 +2276,8 @@ int sigaction_impl(int sig, const __sanitizer_sigaction *act,
// The handler will run synchronously and corrupt tsan per-thread state.
SCOPED_INTERCEPTOR_RAW(sigaction, sig, act, old);
__sanitizer_sigaction *sigactions = interceptor_ctx()->sigactions;
- if (old) internal_memcpy(old, &sigactions[sig], sizeof(*old));
+ __sanitizer_sigaction old_stored;
+ internal_memcpy(&old_stored, &sigactions[sig], sizeof(old_stored));
if (act == 0) return 0;
// Copy act into sigactions[sig].
// Can't use struct copy, because compiler can emit call to memcpy.
@@ -2302,7 +2303,13 @@ int sigaction_impl(int sig, const __sanitizer_sigaction *act,
newact.handler = rtl_sighandler;
}
ReleaseStore(thr, pc, (uptr)&sigactions[sig]);
- int res = REAL(sigaction)(sig, &newact, 0);
+ int res = REAL(sigaction)(sig, &newact, old);
+ if (res == 0 && old) {
+ uptr cb = (uptr)old->sigaction;
+ if (cb == (uptr)rtl_sigaction || cb == (uptr)rtl_sighandler) {
+ internal_memcpy(old, &old_stored, sizeof(*old));
+ }
+ }
return res;
}