forked from OSchip/llvm-project
[sanitizer] Simplify sigaction and sigset_t handling.
llvm-svn: 189338
This commit is contained in:
parent
b27c4b7cb5
commit
a40a058ff1
|
@ -909,7 +909,7 @@ static void SignalHandler(int signo) {
|
|||
|
||||
static void SignalAction(int signo, void *si, void *uc) {
|
||||
UnpoisonParam(3);
|
||||
__msan_unpoison(si, __sanitizer::struct_sigaction_sz);
|
||||
__msan_unpoison(si, sizeof(__sanitizer_sigaction));
|
||||
__msan_unpoison(uc, __sanitizer::ucontext_t_sz);
|
||||
|
||||
typedef void (*sigaction_cb)(int, void *, void *);
|
||||
|
@ -930,21 +930,21 @@ INTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act,
|
|||
__sanitizer_sigaction new_act;
|
||||
__sanitizer_sigaction *pnew_act = act ? &new_act : 0;
|
||||
if (act) {
|
||||
internal_memcpy(pnew_act, act, __sanitizer::struct_sigaction_sz);
|
||||
uptr cb = __sanitizer::__sanitizer_get_sigaction_sa_sigaction(pnew_act);
|
||||
uptr new_cb =
|
||||
__sanitizer::__sanitizer_get_sigaction_sa_siginfo(pnew_act) ?
|
||||
(uptr)SignalAction : (uptr)SignalHandler;
|
||||
internal_memcpy(pnew_act, act, sizeof(__sanitizer_sigaction));
|
||||
uptr cb = (uptr)pnew_act->sa_sigaction;
|
||||
uptr new_cb = (pnew_act->sa_flags & __sanitizer::sa_siginfo)
|
||||
? (uptr)SignalAction
|
||||
: (uptr)SignalHandler;
|
||||
if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
|
||||
sigactions[signo] = cb;
|
||||
__sanitizer::__sanitizer_set_sigaction_sa_sigaction(pnew_act, new_cb);
|
||||
pnew_act->sa_sigaction = (void (*)(int, void *, void *))new_cb;
|
||||
}
|
||||
}
|
||||
res = REAL(sigaction)(signo, pnew_act, oldact);
|
||||
if (res == 0 && oldact) {
|
||||
uptr cb = __sanitizer::__sanitizer_get_sigaction_sa_sigaction(oldact);
|
||||
uptr cb = (uptr)oldact->sa_sigaction;
|
||||
if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
|
||||
__sanitizer::__sanitizer_set_sigaction_sa_sigaction(oldact, old_cb);
|
||||
oldact->sa_sigaction = (void (*)(int, void *, void *))old_cb;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -952,7 +952,7 @@ INTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act,
|
|||
}
|
||||
|
||||
if (res == 0 && oldact) {
|
||||
__msan_unpoison(oldact, __sanitizer::struct_sigaction_sz);
|
||||
__msan_unpoison(oldact, sizeof(__sanitizer_sigaction));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -1976,13 +1976,13 @@ INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
|
|||
|
||||
#if SANITIZER_INTERCEPT_PPOLL
|
||||
INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
|
||||
void *timeout_ts, void *sigmask) {
|
||||
void *timeout_ts, __sanitizer_sigset_t *sigmask) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
|
||||
if (fds && nfds) read_pollfd(ctx, fds, nfds);
|
||||
if (timeout_ts)
|
||||
COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
|
||||
if (sigmask) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, sigset_t_sz);
|
||||
// FIXME: read sigmask when all of sigemptyset, etc are intercepted.
|
||||
int res =
|
||||
COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
|
||||
if (fds && nfds) write_pollfd(ctx, fds, nfds);
|
||||
|
|
|
@ -136,26 +136,12 @@ namespace __sanitizer {
|
|||
|
||||
uptr sig_ign = (uptr)SIG_IGN;
|
||||
uptr sig_dfl = (uptr)SIG_DFL;
|
||||
uptr sa_siginfo = (uptr)SA_SIGINFO;
|
||||
|
||||
#if SANITIZER_LINUX
|
||||
int e_tabsz = (int)E_TABSZ;
|
||||
#endif
|
||||
|
||||
uptr __sanitizer_get_sigaction_sa_sigaction(void *act) {
|
||||
struct sigaction *a = (struct sigaction *)act;
|
||||
// Check that sa_sigaction and sa_handler are the same.
|
||||
CHECK((void *)&(a->sa_sigaction) == (void *)&(a->sa_handler));
|
||||
return (uptr) a->sa_sigaction;
|
||||
}
|
||||
void __sanitizer_set_sigaction_sa_sigaction(void *act, uptr cb) {
|
||||
struct sigaction *a = (struct sigaction *)act;
|
||||
a->sa_sigaction = (void (*)(int, siginfo_t *, void *))cb;
|
||||
}
|
||||
bool __sanitizer_get_sigaction_sa_siginfo(void *act) {
|
||||
struct sigaction *a = (struct sigaction *)act;
|
||||
return a->sa_flags & SA_SIGINFO;
|
||||
}
|
||||
|
||||
int af_inet = (int)AF_INET;
|
||||
int af_inet6 = (int)AF_INET6;
|
||||
|
||||
|
@ -730,9 +716,15 @@ namespace __sanitizer {
|
|||
COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) == \
|
||||
offsetof(CLASS, MEMBER))
|
||||
|
||||
// For sigaction, which is a function and struct at the same time,
|
||||
// and thus requires explicit "struct" in sizeof() expression.
|
||||
#define CHECK_STRUCT_SIZE_AND_OFFSET(CLASS, MEMBER) \
|
||||
COMPILER_CHECK(sizeof(((struct __sanitizer_##CLASS *) NULL)->MEMBER) == \
|
||||
sizeof(((struct CLASS *) NULL)->MEMBER)); \
|
||||
COMPILER_CHECK(offsetof(struct __sanitizer_##CLASS, MEMBER) == \
|
||||
offsetof(struct CLASS, MEMBER))
|
||||
|
||||
COMPILER_CHECK(sizeof(__sanitizer_pthread_attr_t) >= sizeof(pthread_attr_t));
|
||||
COMPILER_CHECK(sizeof(__sanitizer::struct_sigaction_max_sz) >=
|
||||
sizeof(__sanitizer::struct_sigaction_sz));
|
||||
|
||||
COMPILER_CHECK(sizeof(socklen_t) == sizeof(unsigned));
|
||||
CHECK_TYPE_SIZE(pthread_key_t);
|
||||
|
@ -821,7 +813,19 @@ CHECK_TYPE_SIZE(pollfd);
|
|||
CHECK_SIZE_AND_OFFSET(pollfd, fd);
|
||||
CHECK_SIZE_AND_OFFSET(pollfd, events);
|
||||
CHECK_SIZE_AND_OFFSET(pollfd, revents);
|
||||
|
||||
CHECK_TYPE_SIZE(nfds_t);
|
||||
|
||||
CHECK_TYPE_SIZE(sigset_t);
|
||||
|
||||
COMPILER_CHECK(sizeof(__sanitizer_sigaction) == sizeof(struct sigaction));
|
||||
// Can't write checks for sa_handler and sa_sigaction due to them being
|
||||
// preprocessor macros.
|
||||
CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask);
|
||||
CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_flags);
|
||||
#if SANITIZER_LINUX
|
||||
CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_restorer);
|
||||
#endif
|
||||
|
||||
#endif // SANITIZER_LINUX || SANITIZER_MAC
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ namespace __sanitizer {
|
|||
extern unsigned struct_tm_sz;
|
||||
extern unsigned struct_passwd_sz;
|
||||
extern unsigned struct_group_sz;
|
||||
extern unsigned struct_sigaction_sz;
|
||||
extern unsigned siginfo_t_sz;
|
||||
extern unsigned struct_itimerval_sz;
|
||||
extern unsigned pthread_t_sz;
|
||||
|
@ -33,7 +32,6 @@ namespace __sanitizer {
|
|||
extern unsigned timeval_sz;
|
||||
extern unsigned uid_t_sz;
|
||||
extern unsigned mbstate_t_sz;
|
||||
extern unsigned sigset_t_sz;
|
||||
|
||||
#if !SANITIZER_ANDROID
|
||||
extern unsigned ucontext_t_sz;
|
||||
|
@ -135,17 +133,32 @@ namespace __sanitizer {
|
|||
void *align;
|
||||
};
|
||||
|
||||
uptr __sanitizer_get_sigaction_sa_sigaction(void *act);
|
||||
void __sanitizer_set_sigaction_sa_sigaction(void *act, uptr cb);
|
||||
bool __sanitizer_get_sigaction_sa_siginfo(void *act);
|
||||
#if SANITIZER_ANDROID
|
||||
typedef unsigned long __sanitizer_sigset_t;
|
||||
#elif SANITIZER_MAC
|
||||
typedef unsigned __sanitizer_sigset_t;
|
||||
#elif SANITIZER_LINUX
|
||||
struct __sanitizer_sigset_t {
|
||||
// The size is determined by looking at sizeof of real sigset_t on linux.
|
||||
uptr val[128 / sizeof(uptr)];
|
||||
};
|
||||
#endif
|
||||
|
||||
const unsigned struct_sigaction_max_sz = 256;
|
||||
union __sanitizer_sigaction {
|
||||
char size[struct_sigaction_max_sz]; // NOLINT
|
||||
struct __sanitizer_sigaction {
|
||||
union {
|
||||
void (*sa_handler)(int sig);
|
||||
void (*sa_sigaction)(int sig, void *siginfo, void *uctx);
|
||||
};
|
||||
__sanitizer_sigset_t sa_mask;
|
||||
int sa_flags;
|
||||
#if SANITIZER_LINUX
|
||||
void (*sa_restorer)();
|
||||
#endif
|
||||
};
|
||||
|
||||
extern uptr sig_ign;
|
||||
extern uptr sig_dfl;
|
||||
extern uptr sa_siginfo;
|
||||
|
||||
#if SANITIZER_LINUX
|
||||
extern int e_tabsz;
|
||||
|
|
Loading…
Reference in New Issue