Move knote_processexit() call from exit1() to the reaper().
authormillert <millert@openbsd.org>
Thu, 31 Mar 2022 01:41:22 +0000 (01:41 +0000)
committermillert <millert@openbsd.org>
Thu, 31 Mar 2022 01:41:22 +0000 (01:41 +0000)
This fixes a problem where NOTE_EXIT could be received before
the process was officially a zombie and thus not immediately
waitable.  OK deraadt@ visa@

sys/kern/kern_event.c
sys/kern/kern_exit.c
sys/sys/event.h

index 785a8d5..1e10295 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_event.c,v 1.185 2022/03/16 16:17:46 visa Exp $   */
+/*     $OpenBSD: kern_event.c,v 1.186 2022/03/31 01:41:22 millert Exp $        */
 
 /*-
  * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -1885,12 +1885,9 @@ knote_fdclose(struct proc *p, int fd)
  * XXX this could be more efficient, doing a single pass down the klist
  */
 void
-knote_processexit(struct proc *p)
+knote_processexit(struct process *pr)
 {
-       struct process *pr = p->p_p;
-
        KERNEL_ASSERT_LOCKED();
-       KASSERT(p == curproc);
 
        KNOTE(&pr->ps_klist, NOTE_EXIT);
 
index 4886a55..85ec2d5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_exit.c,v 1.202 2022/02/14 11:26:05 claudio Exp $ */
+/*     $OpenBSD: kern_exit.c,v 1.203 2022/03/31 01:41:22 millert Exp $ */
 /*     $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $  */
 
 /*
@@ -318,9 +318,6 @@ exit1(struct proc *p, int xexit, int xsig, int flags)
                calcru(&pr->ps_tu, &rup->ru_utime, &rup->ru_stime, NULL);
                ruadd(rup, &pr->ps_cru);
 
-               /* notify interested parties of our demise and clean up */
-               knote_processexit(p);
-
                /*
                 * Notify parent that we're gone.  If we're not going to
                 * become a zombie, reparent to process 1 (init) so that
@@ -457,12 +454,17 @@ reaper(void *arg)
                        if ((pr->ps_flags & PS_NOZOMBIE) == 0) {
                                /* Process is now a true zombie. */
                                atomic_setbits_int(&pr->ps_flags, PS_ZOMBIE);
-                               prsignal(pr->ps_pptr, SIGCHLD);
+                       }
 
-                               /* Wake up the parent so it can get exit status. */
+                       /* Notify listeners of our demise and clean up. */
+                       knote_processexit(pr);
+
+                       if (pr->ps_flags & PS_ZOMBIE) {
+                               /* Post SIGCHLD and wake up parent. */
+                               prsignal(pr->ps_pptr, SIGCHLD);
                                wakeup(pr->ps_pptr);
                        } else {
-                               /* No one will wait for us. Just zap the process now */
+                               /* No one will wait for us, just zap it. */
                                process_zap(pr);
                        }
                }
index 6aa3461..d5dd8d8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: event.h,v 1.66 2022/02/13 13:03:02 visa Exp $ */
+/*     $OpenBSD: event.h,v 1.67 2022/03/31 01:41:22 millert Exp $      */
 
 /*-
  * Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -293,7 +293,7 @@ extern void kqpoll_done(unsigned int);
 extern void    kqpoll_exit(void);
 extern void    knote(struct klist *list, long hint);
 extern void    knote_fdclose(struct proc *p, int fd);
-extern void    knote_processexit(struct proc *);
+extern void    knote_processexit(struct process *);
 extern void    knote_assign(const struct kevent *, struct knote *);
 extern void    knote_submit(struct knote *, struct kevent *);
 extern void    kqueue_init(void);