forked from OSchip/llvm-project
[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 llvm-svn: 271626
This commit is contained in:
parent
2388b4610a
commit
a601c2ada2
|
@ -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
|
||||
|
|
|
@ -78,6 +78,8 @@ int real_pthread_join(void *th, void **ret);
|
|||
|
||||
int my_pthread_attr_getstack(void *attr, void **addr, uptr *size);
|
||||
|
||||
// A routine named real_sigaction() must be implemented by each sanitizer in
|
||||
// order for internal_sigaction() to bypass interceptors.
|
||||
int internal_sigaction(int signum, const void *act, void *oldact);
|
||||
void internal_sigfillset(__sanitizer_sigset_t *set);
|
||||
|
||||
|
|
Loading…
Reference in New Issue