diff options
author | obrien <obrien@FreeBSD.org> | 2003-05-16 01:34:23 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2003-05-16 01:34:23 +0000 |
commit | 384dc4a2a3a4d1bcd5b3d6377775f4d2c81d908c (patch) | |
tree | c2610a051a55bf26c72506749237db83903129df | |
parent | 49ec42645b698a2d1d13ce453d2f135046098070 (diff) | |
download | FreeBSD-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)
-rw-r--r-- | sys/kern/kern_sig.c | 19 |
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 |