Skip to content

Commit 4501dad

Browse files
committed
Fix SA_SIGINFO | SA_RESETHAND handling. The sysent' sv_sendsig()
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
1 parent 7af8a12 commit 4501dad

1 file changed

Lines changed: 27 additions & 19 deletions

File tree

sys/kern/kern_sig.c

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,30 @@ pgsignal(struct pgrp *pgrp, int sig, int checkctty, ksiginfo_t *ksi)
18821882
}
18831883
}
18841884

1885+
1886+
/*
1887+
* Recalculate the signal mask and reset the signal disposition after
1888+
* usermode frame for delivery is formed. Should be called after
1889+
* mach-specific routine, because sysent->sv_sendsig() needs correct
1890+
* ps_siginfo and signal mask.
1891+
*/
1892+
static void
1893+
postsig_done(int sig, struct thread *td, struct sigacts *ps)
1894+
{
1895+
sigset_t mask;
1896+
1897+
mtx_assert(&ps->ps_mtx, MA_OWNED);
1898+
td->td_ru.ru_nsignals++;
1899+
mask = ps->ps_catchmask[_SIG_IDX(sig)];
1900+
if (!SIGISMEMBER(ps->ps_signodefer, sig))
1901+
SIGADDSET(mask, sig);
1902+
kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
1903+
SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED);
1904+
if (SIGISMEMBER(ps->ps_sigreset, sig))
1905+
sigdflt(ps, sig);
1906+
}
1907+
1908+
18851909
/*
18861910
* Send a signal caused by a trap to the current thread. If it will be
18871911
* caught immediately, deliver it with correct code. Otherwise, post it
@@ -1891,7 +1915,6 @@ void
18911915
trapsignal(struct thread *td, ksiginfo_t *ksi)
18921916
{
18931917
struct sigacts *ps;
1894-
sigset_t mask;
18951918
struct proc *p;
18961919
int sig;
18971920
int code;
@@ -1906,21 +1929,14 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
19061929
mtx_lock(&ps->ps_mtx);
19071930
if ((p->p_flag & P_TRACED) == 0 && SIGISMEMBER(ps->ps_sigcatch, sig) &&
19081931
!SIGISMEMBER(td->td_sigmask, sig)) {
1909-
td->td_ru.ru_nsignals++;
19101932
#ifdef KTRACE
19111933
if (KTRPOINT(curthread, KTR_PSIG))
19121934
ktrpsig(sig, ps->ps_sigact[_SIG_IDX(sig)],
19131935
&td->td_sigmask, code);
19141936
#endif
19151937
(*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)],
19161938
ksi, &td->td_sigmask);
1917-
mask = ps->ps_catchmask[_SIG_IDX(sig)];
1918-
if (!SIGISMEMBER(ps->ps_signodefer, sig))
1919-
SIGADDSET(mask, sig);
1920-
kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
1921-
SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED);
1922-
if (SIGISMEMBER(ps->ps_sigreset, sig))
1923-
sigdflt(ps, sig);
1939+
postsig_done(sig, td, ps);
19241940
mtx_unlock(&ps->ps_mtx);
19251941
} else {
19261942
/*
@@ -2802,7 +2818,7 @@ postsig(sig)
28022818
struct sigacts *ps;
28032819
sig_t action;
28042820
ksiginfo_t ksi;
2805-
sigset_t returnmask, mask;
2821+
sigset_t returnmask;
28062822

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

@@ -2857,20 +2873,12 @@ postsig(sig)
28572873
} else
28582874
returnmask = td->td_sigmask;
28592875

2860-
mask = ps->ps_catchmask[_SIG_IDX(sig)];
2861-
if (!SIGISMEMBER(ps->ps_signodefer, sig))
2862-
SIGADDSET(mask, sig);
2863-
kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
2864-
SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED);
2865-
2866-
if (SIGISMEMBER(ps->ps_sigreset, sig))
2867-
sigdflt(ps, sig);
2868-
td->td_ru.ru_nsignals++;
28692876
if (p->p_sig == sig) {
28702877
p->p_code = 0;
28712878
p->p_sig = 0;
28722879
}
28732880
(*p->p_sysent->sv_sendsig)(action, &ksi, &returnmask);
2881+
postsig_done(sig, td, ps);
28742882
}
28752883
return (1);
28762884
}

0 commit comments

Comments
 (0)