1- /* $OpenBSD: sshd-session.c,v 1.11 2025/01/16 06:37:10 dtucker Exp $ */
1+ /* $OpenBSD: sshd-session.c,v 1.12 2025/03/12 22:43:44 djm Exp $ */
22/*
33 * SSH2 implementation:
44 * Privilege Separation:
111111
112112/* Re-exec fds */
113113#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1)
114- #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2)
115- #define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3)
116- #define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4)
114+ #define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 2)
115+ #define REEXEC_MIN_FREE_FD (STDERR_FILENO + 3)
117116
118117/* Privsep fds */
119118#define PRIVSEP_MONITOR_FD (STDERR_FILENO + 1)
@@ -704,6 +703,8 @@ recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp)
704703
705704 if ((m = sshbuf_new ()) == NULL || (inc = sshbuf_new ()) == NULL )
706705 fatal_f ("sshbuf_new failed" );
706+
707+ /* receive config */
707708 if (ssh_msg_recv (fd , m ) == -1 )
708709 fatal_f ("ssh_msg_recv failed" );
709710 if ((r = sshbuf_get_u8 (m , & ver )) != 0 )
@@ -712,7 +713,6 @@ recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp)
712713 fatal_f ("rexec version mismatch" );
713714 if ((r = sshbuf_get_string (m , & cp , & len )) != 0 || /* XXX _direct */
714715 (r = sshbuf_get_u64 (m , timing_secretp )) != 0 ||
715- (r = sshbuf_froms (m , & hostkeys )) != 0 ||
716716 (r = sshbuf_get_stringb (m , inc )) != 0 )
717717 fatal_fr (r , "parse config" );
718718
@@ -730,6 +730,13 @@ recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp)
730730 TAILQ_INSERT_TAIL (& includes , item , entry );
731731 }
732732
733+ /* receive hostkeys */
734+ sshbuf_reset (m );
735+ if (ssh_msg_recv (fd , m ) == -1 )
736+ fatal_f ("ssh_msg_recv failed" );
737+ if ((r = sshbuf_get_u8 (m , NULL )) != 0 ||
738+ (r = sshbuf_froms (m , & hostkeys )) != 0 )
739+ fatal_fr (r , "parse config" );
733740 parse_hostkeys (hostkeys );
734741
735742 free (cp );
@@ -1031,9 +1038,6 @@ main(int ac, char **av)
10311038 fatal ("sshbuf_new config buf failed" );
10321039 setproctitle ("%s" , "[rexeced]" );
10331040 recv_rexec_state (REEXEC_CONFIG_PASS_FD , cfg , & timing_secret );
1034- /* close the fd, but keep the slot reserved */
1035- if (dup2 (devnull , REEXEC_CONFIG_PASS_FD ) == -1 )
1036- fatal ("dup2 devnull->config fd: %s" , strerror (errno ));
10371041 parse_server_config (& options , "rexec" , cfg , & includes , NULL , 1 );
10381042 /* Fill in default values for those options not explicitly set. */
10391043 fill_default_server_options (& options );
@@ -1059,18 +1063,18 @@ main(int ac, char **av)
10591063 endpwent ();
10601064
10611065 if (!debug_flag && !inetd_flag ) {
1062- if ((startup_pipe = dup (REEXEC_STARTUP_PIPE_FD )) == -1 )
1066+ if ((startup_pipe = dup (REEXEC_CONFIG_PASS_FD )) == -1 )
10631067 fatal ("internal error: no startup pipe" );
1064- /* close the fd, but keep the slot reserved */
1065- if (dup2 (devnull , REEXEC_STARTUP_PIPE_FD ) == -1 )
1066- fatal ("dup2 devnull->startup fd: %s" , strerror (errno ));
10671068
10681069 /*
10691070 * Signal parent that this child is at a point where
10701071 * they can go away if they have a SIGHUP pending.
10711072 */
10721073 (void )atomicio (vwrite , startup_pipe , "\0" , 1 );
10731074 }
1075+ /* close the fd, but keep the slot reserved */
1076+ if (dup2 (devnull , REEXEC_CONFIG_PASS_FD ) == -1 )
1077+ fatal ("dup2 devnull->config fd: %s" , strerror (errno ));
10741078
10751079 /* Check that options are sensible */
10761080 if (options .authorized_keys_command_user == NULL &&
0 commit comments