DF-3225 / fix.diff
--- a/sys/vfs/procfs/procfs_ctl.c +++ b/sys/vfs/procfs/procfs_ctl.c @@ -141,6 +141,22 @@ return (EINVAL); /* + * Refuse to create a tracer cycle (mirrors the + * PT_ATTACH ancestor check in kern/sys_process.c). + * Without this two cooperating processes can attach + * each other and build a p_pptr cycle; the unbounded + * ancestor walk in sys_process.c then livelocks the + * kernel forever while holding the target's p_token. + */ + if (curp->p_flags & P_TRACED) { + struct proc *pp; + + for (pp = curp->p_pptr; pp != NULL; pp = pp->p_pptr) + if (pp == p) + return (EINVAL); + } + + /* * Go ahead and set the trace flag. * Save the old parent (it's reset in * _DETACH, and also in kern_exit.c:wait4() |