Skip to content

Commit

Permalink
[esan] Ensure internal_sigaction() bypasses interceptors
Browse files Browse the repository at this point in the history
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
  • Loading branch information
derekbruening committed Jun 3, 2016
1 parent 2388b46 commit a601c2a
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 0 deletions.
11 changes: 11 additions & 0 deletions compiler-rt/lib/esan/esan_interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_posix.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit a601c2a

Please sign in to comment.