Skip to content

Commit

Permalink
Fix SA_SIGINFO | SA_RESETHAND handling. The sysent' sv_sendsig()
Browse files Browse the repository at this point in the history
method needs pre-reset state of the ps_siginfo to correctly construct
signal frame.

Move sigdflt() call after the sv_sendsig() invocation in postsig().
Simultaneously extract common code from trapsignal() and postsig()
into new helper postsig_done().

Submitted by:	rea
MFC after:	1 week
  • Loading branch information
kostikbel committed Nov 26, 2014
1 parent 7af8a12 commit 4501dad
Showing 1 changed file with 27 additions and 19 deletions.
46 changes: 27 additions & 19 deletions sys/kern/kern_sig.c
Original file line number Diff line number Diff line change
Expand Up @@ -1882,6 +1882,30 @@ pgsignal(struct pgrp *pgrp, int sig, int checkctty, ksiginfo_t *ksi)
}
}


/*
* Recalculate the signal mask and reset the signal disposition after
* usermode frame for delivery is formed. Should be called after
* mach-specific routine, because sysent->sv_sendsig() needs correct
* ps_siginfo and signal mask.
*/
static void
postsig_done(int sig, struct thread *td, struct sigacts *ps)
{
sigset_t mask;

mtx_assert(&ps->ps_mtx, MA_OWNED);
td->td_ru.ru_nsignals++;
mask = ps->ps_catchmask[_SIG_IDX(sig)];
if (!SIGISMEMBER(ps->ps_signodefer, sig))
SIGADDSET(mask, sig);
kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED);
if (SIGISMEMBER(ps->ps_sigreset, sig))
sigdflt(ps, sig);
}


/*
* Send a signal caused by a trap to the current thread. If it will be
* caught immediately, deliver it with correct code. Otherwise, post it
Expand All @@ -1891,7 +1915,6 @@ void
trapsignal(struct thread *td, ksiginfo_t *ksi)
{
struct sigacts *ps;
sigset_t mask;
struct proc *p;
int sig;
int code;
Expand All @@ -1906,21 +1929,14 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
mtx_lock(&ps->ps_mtx);
if ((p->p_flag & P_TRACED) == 0 && SIGISMEMBER(ps->ps_sigcatch, sig) &&
!SIGISMEMBER(td->td_sigmask, sig)) {
td->td_ru.ru_nsignals++;
#ifdef KTRACE
if (KTRPOINT(curthread, KTR_PSIG))
ktrpsig(sig, ps->ps_sigact[_SIG_IDX(sig)],
&td->td_sigmask, code);
#endif
(*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)],
ksi, &td->td_sigmask);
mask = ps->ps_catchmask[_SIG_IDX(sig)];
if (!SIGISMEMBER(ps->ps_signodefer, sig))
SIGADDSET(mask, sig);
kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED);
if (SIGISMEMBER(ps->ps_sigreset, sig))
sigdflt(ps, sig);
postsig_done(sig, td, ps);
mtx_unlock(&ps->ps_mtx);
} else {
/*
Expand Down Expand Up @@ -2802,7 +2818,7 @@ postsig(sig)
struct sigacts *ps;
sig_t action;
ksiginfo_t ksi;
sigset_t returnmask, mask;
sigset_t returnmask;

KASSERT(sig != 0, ("postsig"));

Expand Down Expand Up @@ -2857,20 +2873,12 @@ postsig(sig)
} else
returnmask = td->td_sigmask;

mask = ps->ps_catchmask[_SIG_IDX(sig)];
if (!SIGISMEMBER(ps->ps_signodefer, sig))
SIGADDSET(mask, sig);
kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED);

if (SIGISMEMBER(ps->ps_sigreset, sig))
sigdflt(ps, sig);
td->td_ru.ru_nsignals++;
if (p->p_sig == sig) {
p->p_code = 0;
p->p_sig = 0;
}
(*p->p_sysent->sv_sendsig)(action, &ksi, &returnmask);
postsig_done(sig, td, ps);
}
return (1);
}
Expand Down

0 comments on commit 4501dad

Please sign in to comment.