From: djm@openbsd.org Date: Thu, 25 Sep 2025 06:45:50 +0000 (+0000) Subject: upstream: wait for the unprivileged sshd-auth process to exit X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a071af0682d686de85cf471f5e04deaee4d90adb;p=thirdparty%2Fopenssh-portable.git upstream: wait for the unprivileged sshd-auth process to exit 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 --- diff --git a/monitor.c b/monitor.c index 563a0f0cb..a9e854bec 100644 --- 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 * Copyright 2002 Markus Friedl @@ -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 diff --git a/sshd-session.c b/sshd-session.c index 7abc2b4a5..8979f743b 100644 --- a/sshd-session.c +++ b/sshd-session.c @@ -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 */