summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2003-05-16 01:34:23 +0000
committerobrien <obrien@FreeBSD.org>2003-05-16 01:34:23 +0000
commit384dc4a2a3a4d1bcd5b3d6377775f4d2c81d908c (patch)
treec2610a051a55bf26c72506749237db83903129df /sys
parent49ec42645b698a2d1d13ce453d2f135046098070 (diff)
downloadFreeBSD-src-384dc4a2a3a4d1bcd5b3d6377775f4d2c81d908c.zip
FreeBSD-src-384dc4a2a3a4d1bcd5b3d6377775f4d2c81d908c.tar.gz
Fix long standing bug that prevents the PT_CONTINUE, PT_KILL and
PT_DETACH ptrace(2) requests from functioning as advertised in the manual page. As described in kern/35175, the PT_DETACH request will, under certain circumstances, pass an unwanted signal on to the traced process upan detaching from it. The PT_CONTINUE request will sometimes fail if you make it pass a signal that has "properties" that differ from the properties of the signal that origionally caused the traced process to be stopped. Since PT_KILL is nothing than PT_CONTINUE with SIGKILL, it is broken too. In the PT_KILL case, this leads to an unkillable process. PR: 44011 Submitted by: Mark Kettenis <kettenis@chello.nl> Approved by: re(jhb)
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_sig.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index abe10df..ef4948f 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1917,7 +1917,6 @@ issignal(td)
if (SIGISEMPTY(sigpending)) /* no signal to send */
return (0);
sig = sig_ffs(&sigpending);
- prop = sigprop(sig);
_STOPEVENT(p, S_SIG, sig);
@@ -1953,14 +1952,6 @@ issignal(td)
mtx_lock(&ps->ps_mtx);
/*
- * If the traced bit got turned off, go back up
- * to the top to rescan signals. This ensures
- * that p_sig* and p_sigacts are consistent.
- */
- if ((p->p_flag & P_TRACED) == 0)
- continue;
-
- /*
* If parent wants us to take the signal,
* then it will leave it in p->p_xstat;
* otherwise we just look for signals again.
@@ -1971,6 +1962,14 @@ issignal(td)
continue;
/*
+ * 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.
+ */
+ if ((p->p_flag & P_TRACED) == 0)
+ continue;
+
+ /*
* Put the new signal into td_siglist. If the
* signal is being masked, look for other signals.
*/
@@ -1980,6 +1979,8 @@ issignal(td)
signotify(td);
}
+ prop = sigprop(sig);
+
/*
* Decide whether the signal should be returned.
* Return the signal's number, or fall through
OpenPOWER on IntegriCloud