svn commit: r270443 - head/sys/kern
Mateusz Guzik
mjg at FreeBSD.org
Sun Aug 24 09:02:17 UTC 2014
Author: mjg
Date: Sun Aug 24 09:02:16 2014
New Revision: 270443
URL: http://svnweb.freebsd.org/changeset/base/270443
Log:
Properly reparent traced processes when the tracer dies.
Previously they were uncoditionally reparented to init. In effect
it was possible that tracee was never returned to original parent.
Reviewed by: kib
MFC after: 1 week
Modified:
head/sys/kern/kern_exit.c
Modified: head/sys/kern/kern_exit.c
==============================================================================
--- head/sys/kern/kern_exit.c Sun Aug 24 08:03:59 2014 (r270442)
+++ head/sys/kern/kern_exit.c Sun Aug 24 09:02:16 2014 (r270443)
@@ -156,7 +156,8 @@ sys_sys_exit(struct thread *td, struct s
void
exit1(struct thread *td, int rv)
{
- struct proc *p, *nq, *q;
+ struct proc *p, *nq, *q, *t;
+ struct thread *tdt;
struct vnode *ttyvp = NULL;
mtx_assert(&Giant, MA_NOTOWNED);
@@ -437,7 +438,9 @@ exit1(struct thread *td, int rv)
WITNESS_WARN(WARN_PANIC, NULL, "process (pid %d) exiting", p->p_pid);
/*
- * Reparent all of our children to init.
+ * Reparent all children processes:
+ * - traced ones to the original parent (or init if we are that parent)
+ * - the rest to init
*/
sx_xlock(&proctree_lock);
q = LIST_FIRST(&p->p_children);
@@ -446,15 +449,23 @@ exit1(struct thread *td, int rv)
for (; q != NULL; q = nq) {
nq = LIST_NEXT(q, p_sibling);
PROC_LOCK(q);
- proc_reparent(q, initproc);
q->p_sigparent = SIGCHLD;
- /*
- * Traced processes are killed
- * since their existence means someone is screwing up.
- */
- if (q->p_flag & P_TRACED) {
- struct thread *temp;
+ if (!(q->p_flag & P_TRACED)) {
+ proc_reparent(q, initproc);
+ } else {
+ /*
+ * Traced processes are killed since their existence
+ * means someone is screwing up.
+ */
+ t = proc_realparent(q);
+ if (t == p) {
+ proc_reparent(q, initproc);
+ } else {
+ PROC_LOCK(t);
+ proc_reparent(q, t);
+ PROC_UNLOCK(t);
+ }
/*
* Since q was found on our children list, the
* proc_reparent() call moved q to the orphan
@@ -463,8 +474,8 @@ exit1(struct thread *td, int rv)
*/
clear_orphan(q);
q->p_flag &= ~(P_TRACED | P_STOPPED_TRACE);
- FOREACH_THREAD_IN_PROC(q, temp)
- temp->td_dbgflags &= ~TDB_SUSPEND;
+ FOREACH_THREAD_IN_PROC(q, tdt)
+ tdt->td_dbgflags &= ~TDB_SUSPEND;
kern_psignal(q, SIGKILL);
}
PROC_UNLOCK(q);
More information about the svn-src-all
mailing list