]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream: wait for the unprivileged sshd-auth process to exit
authordjm@openbsd.org <djm@openbsd.org>
Thu, 25 Sep 2025 06:45:50 +0000 (06:45 +0000)
committerDamien Miller <djm@mindrot.org>
Thu, 25 Sep 2025 07:01:57 +0000 (17:01 +1000)
before closing the fd it uses to report log messages

This avoids a race where the child process notices the
fd was closed before exiting and spams the logs.

ok dtucker@

OpenBSD-Commit-ID: 7cddaa41be3b955e6bed570900db7ab8817b1e76

monitor.c
sshd-session.c

index 563a0f0cb59acd493597f55fe535bfa2f383a6ff..a9e854bec8315b7a4cb153e2135cf3484c8a0584 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: monitor.c,v 1.248 2025/09/15 04:47:49 djm Exp $ */
+/* $OpenBSD: monitor.c,v 1.249 2025/09/25 06:45:50 djm Exp $ */
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -262,7 +262,7 @@ void
 monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor)
 {
        struct mon_table *ent;
-       int authenticated = 0, partial = 0;
+       int status, authenticated = 0, partial = 0;
 
        debug3("preauth child monitor started");
 
@@ -365,11 +365,29 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor)
        while (pmonitor->m_log_recvfd != -1 && monitor_read_log(pmonitor) == 0)
                ;
 
+       /* Wait for the child's exit status */
+       while (waitpid(pmonitor->m_pid, &status, 0) == -1) {
+               if (errno == EINTR)
+                       continue;
+               fatal_f("waitpid: %s", strerror(errno));
+       }
+       if (WIFEXITED(status)) {
+               if (WEXITSTATUS(status) != 0)
+                       fatal_f("preauth child %ld exited with status %d",
+                           (long)pmonitor->m_pid, WEXITSTATUS(status));
+       } else if (WIFSIGNALED(status)) {
+               fatal_f("preauth child %ld terminated by signal %d",
+                   (long)pmonitor->m_pid, WTERMSIG(status));
+       }
+       debug3_f("preauth child %ld terminated successfully",
+           (long)pmonitor->m_pid);
+
        if (pmonitor->m_recvfd >= 0)
                close(pmonitor->m_recvfd);
        if (pmonitor->m_log_sendfd >= 0)
                close(pmonitor->m_log_sendfd);
        pmonitor->m_sendfd = pmonitor->m_log_recvfd = -1;
+       pmonitor->m_pid = -1;
 }
 
 static void
index 7abc2b4a501369d871645d32544fbd450f0700cd..8979f743bfdf9845b126df248001db704cb27c46 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd-session.c,v 1.15 2025/08/29 03:50:38 djm Exp $ */
+/* $OpenBSD: sshd-session.c,v 1.16 2025/09/25 06:45:50 djm Exp $ */
 /*
  * SSH2 implementation:
  * Privilege Separation:
@@ -330,7 +330,7 @@ pack_hostkeys(void)
 static int
 privsep_preauth(struct ssh *ssh)
 {
-       int status, r;
+       int r;
        pid_t pid;
 
        /* Set up unprivileged child process to deal with network data */
@@ -352,23 +352,7 @@ privsep_preauth(struct ssh *ssh)
                        }
                }
                monitor_child_preauth(ssh, pmonitor);
-
-               /* Wait for the child's exit status */
-               while (waitpid(pid, &status, 0) == -1) {
-                       if (errno == EINTR)
-                               continue;
-                       pmonitor->m_pid = -1;
-                       fatal_f("waitpid: %s", strerror(errno));
-               }
                privsep_is_preauth = 0;
-               pmonitor->m_pid = -1;
-               if (WIFEXITED(status)) {
-                       if (WEXITSTATUS(status) != 0)
-                               fatal_f("preauth child exited with status %d",
-                                   WEXITSTATUS(status));
-               } else if (WIFSIGNALED(status))
-                       fatal_f("preauth child terminated by signal %d",
-                           WTERMSIG(status));
                return 1;
        } else {
                /* child */