summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Smith <mgsmith@netgate.com>2015-11-18 10:33:11 -0600
committerMatt Smith <mgsmith@netgate.com>2015-11-18 10:33:11 -0600
commitf30917567e3eaa326944f678f1355bf733deba3d (patch)
tree7f4ec912a072bdd06c4abc33d6086df6d63e1459
parent49b146ba33ce96cb15eb34e14292aeceb43e422c (diff)
downloadFreeBSD-src-f30917567e3eaa326944f678f1355bf733deba3d.zip
FreeBSD-src-f30917567e3eaa326944f678f1355bf733deba3d.tar.gz
Importing pfSense patch redmine_4592.diff
-rw-r--r--sys/kern/kern_sig.c56
1 files changed, 35 insertions, 21 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 45e12c4..10406e0 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1003,8 +1003,12 @@ kern_sigprocmask(struct thread *td, int how, sigset_t *set, sigset_t *oset,
int error;
p = td->td_proc;
- if (!(flags & SIGPROCMASK_PROC_LOCKED))
+ if ((flags & SIGPROCMASK_PROC_LOCKED) != 0)
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ else
PROC_LOCK(p);
+ mtx_assert(&p->p_sigacts->ps_mtx, (flags & SIGPROCMASK_PS_LOCKED) != 0
+ ? MA_OWNED : MA_NOTOWNED);
if (oset != NULL)
*oset = td->td_sigmask;
@@ -1891,6 +1895,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
@@ -1900,7 +1928,6 @@ void
trapsignal(struct thread *td, ksiginfo_t *ksi)
{
struct sigacts *ps;
- sigset_t mask;
struct proc *p;
int sig;
int code;
@@ -1915,7 +1942,6 @@ 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)],
@@ -1923,13 +1949,7 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
#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 {
/*
@@ -2503,9 +2523,11 @@ reschedule_signals(struct proc *p, sigset_t block, int flags)
int sig;
PROC_LOCK_ASSERT(p, MA_OWNED);
+ ps = p->p_sigacts;
+ mtx_assert(&ps->ps_mtx, (flags & SIGPROCMASK_PS_LOCKED) != 0 ?
+ MA_OWNED : MA_NOTOWNED);
if (SIGISEMPTY(p->p_siglist))
return;
- ps = p->p_sigacts;
SIGSETAND(block, p->p_siglist);
while ((sig = sig_ffs(&block)) != 0) {
SIGDELSET(block, sig);
@@ -2811,7 +2833,7 @@ postsig(sig)
struct sigacts *ps;
sig_t action;
ksiginfo_t ksi;
- sigset_t returnmask, mask;
+ sigset_t returnmask;
KASSERT(sig != 0, ("postsig"));
@@ -2866,20 +2888,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);
}
OpenPOWER on IntegriCloud