diff options
author | Derek Bruening <bruening@google.com> | 2016-06-03 04:30:47 +0000 |
---|---|---|
committer | Derek Bruening <bruening@google.com> | 2016-06-03 04:30:47 +0000 |
commit | 009632990e8c5b96eb0973782381fa0e778858ae (patch) | |
tree | f9569f8e7aac71d2b8621e6364da3cabfd57e8f0 /lib/esan | |
parent | 2edd48d650739735a003d0251544ce10efe8896a (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.cpp | 11 |
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 |