diff options
author | Vitaly Buka <vitalybuka@google.com> | 2017-11-13 20:49:14 +0000 |
---|---|---|
committer | Vitaly Buka <vitalybuka@google.com> | 2017-11-13 20:49:14 +0000 |
commit | 98ddb4f6276ab88c6ce0735490a208d573788389 (patch) | |
tree | a3c445ecb7aba8929aec07de0964262763b5c71c /lib | |
parent | 82cd00ab016a2197f9fa26d38fbfdad75af76c31 (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.cc | 11 |
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; } |