From: Alexander Bluhm Subject: Re: Traverse list of children safely To: Christian Ludwig Cc: tech@openbsd.org Date: Sat, 2 Aug 2025 13:12:52 +0200 On Sat, Aug 02, 2025 at 11:56:13AM +0200, Christian Ludwig wrote: > Zombie processes get taken off the list in proc_finish_wait(), either > by reparenting or to zap them. So we need to obtain the next list > element before that. > > ok? proc_finish_wait() is followed by a return(0). As we do not use variable pr after that, LIST_FOREACH() should be safe enough. > --- > sys/kern/kern_exit.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c > index cd37a0d29aa3..aca87688a28e 100644 > --- a/sys/kern/kern_exit.c > +++ b/sys/kern/kern_exit.c > @@ -530,7 +530,7 @@ dowait6(struct proc *q, idtype_t idtype, id_t id, int *statusp, int options, > struct rusage *rusage, siginfo_t *info, register_t *retval) > { > int nfound; > - struct process *pr; > + struct process *pr, *npr; > int error; > > if (info != NULL) > @@ -539,7 +539,7 @@ dowait6(struct proc *q, idtype_t idtype, id_t id, int *statusp, int options, > loop: > atomic_clearbits_int(&q->p_p->ps_flags, PS_WAITEVENT); > nfound = 0; > - LIST_FOREACH(pr, &q->p_p->ps_children, ps_sibling) { > + LIST_FOREACH_SAFE(pr, &q->p_p->ps_children, ps_sibling, npr) { > mtx_enter(&pr->ps_mtx); > if ((pr->ps_flags & PS_NOZOMBIE) || > (idtype == P_PID && id != pr->ps_pid) || > -- > 2.34.1 >