summaryrefslogtreecommitdiff
path: root/lib/esan
diff options
context:
space:
mode:
authorDerek Bruening <bruening@google.com>2016-06-03 04:30:47 +0000
committerDerek Bruening <bruening@google.com>2016-06-03 04:30:47 +0000
commit009632990e8c5b96eb0973782381fa0e778858ae (patch)
treef9569f8e7aac71d2b8621e6364da3cabfd57e8f0 /lib/esan
parent2edd48d650739735a003d0251544ce10efe8896a (diff)
[esan] Ensure internal_sigaction() bypasses interceptors
Summary: Implements real_sigaction() which it turns out is required for internal_sigaction() to bypass the libc interceptors. Without real_sigaction(), our internal_sigaction() calls during init happen to work due to the EsanDuringInit check in COMMON_INTERCEPTOR_ENTER (though even here it does not feel right for an "internal_" call to go through the interceptor). The real problem is when we call internal_sigaction() after we're initialized, which only happens on an unhandled SIGSEGV for which the app has no handler: then we'll spin in an infinite loop as our attempts to remove our own handler repeatedly fail. It's not easy to add a test for that, unfortunately. Reviewers: aizatsky Subscribers: vitalybuka, zhaoqin, kcc, eugenis, llvm-commits, kubabrecka Differential Revision: http://reviews.llvm.org/D20832 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@271626 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/esan')
-rw-r--r--lib/esan/esan_interceptors.cpp11
1 files changed, 11 insertions, 0 deletions
diff --git a/lib/esan/esan_interceptors.cpp b/lib/esan/esan_interceptors.cpp
index 8ed870984..35217f58f 100644
--- a/lib/esan/esan_interceptors.cpp
+++ b/lib/esan/esan_interceptors.cpp
@@ -373,6 +373,8 @@ INTERCEPTOR(signal_handler_t, signal, int signum, signal_handler_t handler) {
#endif
#if SANITIZER_LINUX
+DECLARE_REAL(int, sigaction, int signum, const struct sigaction *act,
+ struct sigaction *oldact)
INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
struct sigaction *oldact) {
void *ctx;
@@ -382,6 +384,15 @@ INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
else
return REAL(sigaction)(signum, act, oldact);
}
+
+// This is required to properly use internal_sigaction.
+namespace __sanitizer {
+int real_sigaction(int signum, const void *act, void *oldact) {
+ return REAL(sigaction)(signum, (const struct sigaction *)act,
+ (struct sigaction *)oldact);
+}
+} // namespace __sanitizer
+
#define ESAN_MAYBE_INTERCEPT_SIGACTION INTERCEPT_FUNCTION(sigaction)
#else
#error Platform not supported