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
This commit is contained in:
parent
79d2bf4036
commit
eda187d10a
@ -156,7 +156,8 @@ sys_sys_exit(struct thread *td, struct sys_exit_args *uap)
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user