aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_sig.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2017-10-16 20:21:51 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2017-10-16 20:21:51 +0000
commite9445808a8409448264642dc078dc37033593be1 (patch)
treef89129cb6ff253f4d5558421da5c4432b76a4145 /sys/kern/kern_sig.c
parentcd735d8f5a7c1f56d99f9d5e6535696d1e8484c3 (diff)
downloadsrc-e9445808a8409448264642dc078dc37033593be1.tar.gz
src-e9445808a8409448264642dc078dc37033593be1.zip
Re-evaluate thread' signal mask after ptracestop().
The stop drops process lock, which allows the signal mask to be changed and our selected signal might become blocked, i.e. should be returned to the process queue instead of delivery. Also, for the existing check of the process no longer having an attached debugger, we should not loose the signal, but requeue it. Reported and tested by: bdrewery Reviewed by: jhb Sponsored by: The FreeBSD Foundation MFC after: 1 week
Notes
Notes: svn path=/head/; revision=324671
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r--sys/kern/kern_sig.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index e0bc937b6e81..ea3b68e370c6 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -2855,15 +2855,32 @@ issignal(struct thread *td)
mtx_lock(&ps->ps_mtx);
/*
- * Keep looking if the debugger discarded the signal
- * or replaced it with a masked signal.
- *
- * If the traced bit got turned off, go back up
- * to the top to rescan signals. This ensures
- * that p_sig* and p_sigact are consistent.
+ * Keep looking if the debugger discarded or
+ * replaced the signal.
*/
- if (sig == 0 || (p->p_flag & P_TRACED) == 0)
+ if (sig == 0)
continue;
+
+ /*
+ * If the signal became masked, re-queue it.
+ */
+ if (SIGISMEMBER(td->td_sigmask, sig)) {
+ ksi.ksi_flags |= KSI_HEAD;
+ sigqueue_add(&p->p_sigqueue, sig, &ksi);
+ continue;
+ }
+
+ /*
+ * If the traced bit got turned off, requeue
+ * the signal and go back up to the top to
+ * rescan signals. This ensures that p_sig*
+ * and p_sigact are consistent.
+ */
+ if ((p->p_flag & P_TRACED) == 0) {
+ ksi.ksi_flags |= KSI_HEAD;
+ sigqueue_add(queue, sig, &ksi);
+ continue;
+ }
}
prop = sigprop(sig);