mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 17:18:32 +00:00
Trapsignal() and postsig() call kern_sigprocmask() with both process
lock and curproc->p_sigacts->ps_mtx. Reschedule_signals may need to have ps_mtx locked to decide and wakeup a thread, causing recursion on the mutex. Inform kern_sigprocmask() and reschedule_signals() about lock state of the ps_mtx by new flag SIGPROCMASK_PS_LOCKED to avoid recursion. Reported and tested by: keramida MFC after: 1 month
This commit is contained in:
parent
6bd41d5bc2
commit
80a8b0f3bf
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=198670
|
@ -220,7 +220,7 @@ static int sigproptbl[NSIG] = {
|
|||
SA_KILL|SA_PROC, /* SIGUSR2 */
|
||||
};
|
||||
|
||||
static void reschedule_signals(struct proc *p, sigset_t block);
|
||||
static void reschedule_signals(struct proc *p, sigset_t block, int flags);
|
||||
|
||||
static void
|
||||
sigqueue_start(void)
|
||||
|
@ -1024,7 +1024,7 @@ kern_sigprocmask(struct thread *td, int how, sigset_t *set, sigset_t *oset,
|
|||
* possibly waking it up.
|
||||
*/
|
||||
if (p->p_numthreads != 1)
|
||||
reschedule_signals(p, new_block);
|
||||
reschedule_signals(p, new_block, flags);
|
||||
|
||||
if (!(flags & SIGPROCMASK_PROC_LOCKED))
|
||||
PROC_UNLOCK(p);
|
||||
|
@ -1859,13 +1859,11 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
|
|||
#endif
|
||||
(*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)],
|
||||
ksi, &td->td_sigmask);
|
||||
SIGSETOR(td->td_sigmask, ps->ps_catchmask[_SIG_IDX(sig)]);
|
||||
if (!SIGISMEMBER(ps->ps_signodefer, sig)) {
|
||||
SIGEMPTYSET(mask);
|
||||
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);
|
||||
}
|
||||
kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
|
||||
SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED);
|
||||
if (SIGISMEMBER(ps->ps_sigreset, sig)) {
|
||||
/*
|
||||
* See kern_sigaction() for origin of this code.
|
||||
|
@ -2401,7 +2399,7 @@ ptracestop(struct thread *td, int sig)
|
|||
}
|
||||
|
||||
static void
|
||||
reschedule_signals(struct proc *p, sigset_t block)
|
||||
reschedule_signals(struct proc *p, sigset_t block, int flags)
|
||||
{
|
||||
struct sigacts *ps;
|
||||
struct thread *td;
|
||||
|
@ -2419,12 +2417,14 @@ reschedule_signals(struct proc *p, sigset_t block)
|
|||
|
||||
td = sigtd(p, i, 0);
|
||||
signotify(td);
|
||||
mtx_lock(&ps->ps_mtx);
|
||||
if (!(flags & SIGPROCMASK_PS_LOCKED))
|
||||
mtx_lock(&ps->ps_mtx);
|
||||
if (p->p_flag & P_TRACED || SIGISMEMBER(ps->ps_sigcatch, i))
|
||||
tdsigwakeup(td, i, SIG_CATCH,
|
||||
(SIGISMEMBER(ps->ps_sigintr, i) ? EINTR :
|
||||
ERESTART));
|
||||
mtx_unlock(&ps->ps_mtx);
|
||||
if (!(flags & SIGPROCMASK_PS_LOCKED))
|
||||
mtx_unlock(&ps->ps_mtx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2452,7 +2452,7 @@ tdsigcleanup(struct thread *td)
|
|||
SIGFILLSET(unblocked);
|
||||
SIGSETNAND(unblocked, td->td_sigmask);
|
||||
SIGFILLSET(td->td_sigmask);
|
||||
reschedule_signals(p, unblocked);
|
||||
reschedule_signals(p, unblocked, 0);
|
||||
|
||||
}
|
||||
|
||||
|
@ -2734,15 +2734,11 @@ postsig(sig)
|
|||
} else
|
||||
returnmask = td->td_sigmask;
|
||||
|
||||
kern_sigprocmask(td, SIG_BLOCK,
|
||||
&ps->ps_catchmask[_SIG_IDX(sig)], NULL,
|
||||
SIGPROCMASK_PROC_LOCKED);
|
||||
if (!SIGISMEMBER(ps->ps_signodefer, sig)) {
|
||||
SIGEMPTYSET(mask);
|
||||
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);
|
||||
}
|
||||
kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
|
||||
SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED);
|
||||
|
||||
if (SIGISMEMBER(ps->ps_sigreset, sig)) {
|
||||
/*
|
||||
|
|
|
@ -319,6 +319,7 @@ extern int kern_logsigexit; /* Sysctl variable kern.logsigexit */
|
|||
/* flags for kern_sigprocmask */
|
||||
#define SIGPROCMASK_OLD 0x0001
|
||||
#define SIGPROCMASK_PROC_LOCKED 0x0002
|
||||
#define SIGPROCMASK_PS_LOCKED 0x0004
|
||||
|
||||
/*
|
||||
* Machine-independent functions:
|
||||
|
|
Loading…
Reference in a new issue