Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
Re: Traverse list of children safely
To:
Christian Ludwig <cludwig@genua.de>
Cc:
tech@openbsd.org
Date:
Sat, 2 Aug 2025 13:12:52 +0200

Download raw body.

Thread
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
>