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
|
void
|
||||||
exit1(struct thread *td, int rv)
|
exit1(struct thread *td, int rv)
|
||||||
{
|
{
|
||||||
struct proc *p, *nq, *q;
|
struct proc *p, *nq, *q, *t;
|
||||||
|
struct thread *tdt;
|
||||||
struct vnode *ttyvp = NULL;
|
struct vnode *ttyvp = NULL;
|
||||||
|
|
||||||
mtx_assert(&Giant, MA_NOTOWNED);
|
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);
|
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);
|
sx_xlock(&proctree_lock);
|
||||||
q = LIST_FIRST(&p->p_children);
|
q = LIST_FIRST(&p->p_children);
|
||||||
@ -446,15 +449,23 @@ exit1(struct thread *td, int rv)
|
|||||||
for (; q != NULL; q = nq) {
|
for (; q != NULL; q = nq) {
|
||||||
nq = LIST_NEXT(q, p_sibling);
|
nq = LIST_NEXT(q, p_sibling);
|
||||||
PROC_LOCK(q);
|
PROC_LOCK(q);
|
||||||
proc_reparent(q, initproc);
|
|
||||||
q->p_sigparent = SIGCHLD;
|
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
|
* Since q was found on our children list, the
|
||||||
* proc_reparent() call moved q to the orphan
|
* proc_reparent() call moved q to the orphan
|
||||||
@ -463,8 +474,8 @@ exit1(struct thread *td, int rv)
|
|||||||
*/
|
*/
|
||||||
clear_orphan(q);
|
clear_orphan(q);
|
||||||
q->p_flag &= ~(P_TRACED | P_STOPPED_TRACE);
|
q->p_flag &= ~(P_TRACED | P_STOPPED_TRACE);
|
||||||
FOREACH_THREAD_IN_PROC(q, temp)
|
FOREACH_THREAD_IN_PROC(q, tdt)
|
||||||
temp->td_dbgflags &= ~TDB_SUSPEND;
|
tdt->td_dbgflags &= ~TDB_SUSPEND;
|
||||||
kern_psignal(q, SIGKILL);
|
kern_psignal(q, SIGKILL);
|
||||||
}
|
}
|
||||||
PROC_UNLOCK(q);
|
PROC_UNLOCK(q);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user