[openssh-commits] [openssh] 01/02: upstream: remove assumption that the sshd_config and any configs

git+noreply at mindrot.org git+noreply at mindrot.org
Thu Mar 13 10:45:58 AEDT 2025


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit d47ef958b89c6fa809302d654009d3dfabe11b75
Author: djm at openbsd.org <djm at openbsd.org>
AuthorDate: Wed Mar 12 22:43:44 2025 +0000

    upstream: remove assumption that the sshd_config and any configs
    
    included from it can fit in a (possibly enlarged) socket buffer, by having
    the sshd listener mainloop actively manage sending the configuration to the
    sshd-session subprocess.
    
    work by markus@ w/ a little feedback from me;
    ok me and committing on his behalf
    
    OpenBSD-Commit-ID: 8f54451483f64951853074adb76bc4f838eaf3ae
---
 sshd-session.c |  28 +++---
 sshd.c         | 303 +++++++++++++++++++++++++++++++++++++++------------------
 2 files changed, 222 insertions(+), 109 deletions(-)

diff --git a/sshd-session.c b/sshd-session.c
index 92a27c10..1e2cee10 100644
--- a/sshd-session.c
+++ b/sshd-session.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd-session.c,v 1.11 2025/01/16 06:37:10 dtucker Exp $ */
+/* $OpenBSD: sshd-session.c,v 1.12 2025/03/12 22:43:44 djm Exp $ */
 /*
  * SSH2 implementation:
  * Privilege Separation:
@@ -111,9 +111,8 @@
 
 /* Re-exec fds */
 #define REEXEC_DEVCRYPTO_RESERVED_FD	(STDERR_FILENO + 1)
-#define REEXEC_STARTUP_PIPE_FD		(STDERR_FILENO + 2)
-#define REEXEC_CONFIG_PASS_FD		(STDERR_FILENO + 3)
-#define REEXEC_MIN_FREE_FD		(STDERR_FILENO + 4)
+#define REEXEC_CONFIG_PASS_FD		(STDERR_FILENO + 2)
+#define REEXEC_MIN_FREE_FD		(STDERR_FILENO + 3)
 
 /* Privsep fds */
 #define PRIVSEP_MONITOR_FD		(STDERR_FILENO + 1)
@@ -704,6 +703,8 @@ recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp)
 
 	if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL)
 		fatal_f("sshbuf_new failed");
+
+	/* receive config */
 	if (ssh_msg_recv(fd, m) == -1)
 		fatal_f("ssh_msg_recv failed");
 	if ((r = sshbuf_get_u8(m, &ver)) != 0)
@@ -712,7 +713,6 @@ recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp)
 		fatal_f("rexec version mismatch");
 	if ((r = sshbuf_get_string(m, &cp, &len)) != 0 || /* XXX _direct */
 	    (r = sshbuf_get_u64(m, timing_secretp)) != 0 ||
-	    (r = sshbuf_froms(m, &hostkeys)) != 0 ||
 	    (r = sshbuf_get_stringb(m, inc)) != 0)
 		fatal_fr(r, "parse config");
 
@@ -730,6 +730,13 @@ recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp)
 		TAILQ_INSERT_TAIL(&includes, item, entry);
 	}
 
+	/* receive hostkeys */
+	sshbuf_reset(m);
+	if (ssh_msg_recv(fd, m) == -1)
+		fatal_f("ssh_msg_recv failed");
+	if ((r = sshbuf_get_u8(m, NULL)) != 0 ||
+	    (r = sshbuf_froms(m, &hostkeys)) != 0)
+		fatal_fr(r, "parse config");
 	parse_hostkeys(hostkeys);
 
 	free(cp);
@@ -1031,9 +1038,6 @@ main(int ac, char **av)
 		fatal("sshbuf_new config buf failed");
 	setproctitle("%s", "[rexeced]");
 	recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg, &timing_secret);
-	/* close the fd, but keep the slot reserved */
-	if (dup2(devnull, REEXEC_CONFIG_PASS_FD) == -1)
-		fatal("dup2 devnull->config fd: %s", strerror(errno));
 	parse_server_config(&options, "rexec", cfg, &includes, NULL, 1);
 	/* Fill in default values for those options not explicitly set. */
 	fill_default_server_options(&options);
@@ -1059,11 +1063,8 @@ main(int ac, char **av)
 	endpwent();
 
 	if (!debug_flag && !inetd_flag) {
-		if ((startup_pipe = dup(REEXEC_STARTUP_PIPE_FD)) == -1)
+		if ((startup_pipe = dup(REEXEC_CONFIG_PASS_FD)) == -1)
 			fatal("internal error: no startup pipe");
-		/* close the fd, but keep the slot reserved */
-		if (dup2(devnull, REEXEC_STARTUP_PIPE_FD) == -1)
-			fatal("dup2 devnull->startup fd: %s", strerror(errno));
 
 		/*
 		 * Signal parent that this child is at a point where
@@ -1071,6 +1072,9 @@ main(int ac, char **av)
 		 */
 		(void)atomicio(vwrite, startup_pipe, "\0", 1);
 	}
+	/* close the fd, but keep the slot reserved */
+	if (dup2(devnull, REEXEC_CONFIG_PASS_FD) == -1)
+		fatal("dup2 devnull->config fd: %s", strerror(errno));
 
 	/* Check that options are sensible */
 	if (options.authorized_keys_command_user == NULL &&
diff --git a/sshd.c b/sshd.c
index 862023e2..f77e1205 100644
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.615 2025/02/10 23:19:26 djm Exp $ */
+/* $OpenBSD: sshd.c,v 1.616 2025/03/12 22:43:44 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001, 2002 Markus Friedl.  All rights reserved.
  * Copyright (c) 2002 Niels Provos.  All rights reserved.
@@ -92,12 +92,12 @@
 #include "sk-api.h"
 #include "addr.h"
 #include "srclimit.h"
+#include "atomicio.h"
 
 /* Re-exec fds */
 #define REEXEC_DEVCRYPTO_RESERVED_FD	(STDERR_FILENO + 1)
-#define REEXEC_STARTUP_PIPE_FD		(STDERR_FILENO + 2)
-#define REEXEC_CONFIG_PASS_FD		(STDERR_FILENO + 3)
-#define REEXEC_MIN_FREE_FD		(STDERR_FILENO + 4)
+#define REEXEC_CONFIG_PASS_FD		(STDERR_FILENO + 2)
+#define REEXEC_MIN_FREE_FD		(STDERR_FILENO + 3)
 
 extern char *__progname;
 
@@ -182,13 +182,15 @@ struct early_child {
 	struct xaddr addr;
 	int have_addr;
 	int status, have_status;
+	struct sshbuf *config;
+	struct sshbuf *keys;
 };
 static struct early_child *children;
 static int children_active;
-static int startup_pipe = -1;		/* in child */
 
 /* sshd_config buffer */
 struct sshbuf *cfg;
+struct sshbuf *config;	/* packed */
 
 /* Included files from the configuration file */
 struct include_list includes = TAILQ_HEAD_INITIALIZER(includes);
@@ -239,7 +241,10 @@ child_register(int pipefd, int sockfd)
 	struct sockaddr *sa = (struct sockaddr *)&addr;
 
 	for (i = 0; i < options.max_startups; i++) {
-		if (children[i].pipefd != -1 || children[i].pid > 0)
+		if (children[i].pipefd != -1 ||
+		    children[i].config != NULL ||
+		    children[i].keys != NULL ||
+		    children[i].pid > 0)
 			continue;
 		child = &(children[i]);
 		break;
@@ -250,6 +255,8 @@ child_register(int pipefd, int sockfd)
 	}
 	child->pipefd = pipefd;
 	child->early = 1;
+	if ((child->config = sshbuf_fromb(config)) == NULL)
+		fatal_f("sshbuf_fromb failed");
 	/* record peer address, if available */
 	if (getpeername(sockfd, sa, &addrlen) == 0 &&
 	   addr_sa_to_xaddr(sa, addrlen, &child->addr) == 0)
@@ -283,6 +290,8 @@ child_finish(struct early_child *child)
 		fatal_f("internal error: children_active underflow");
 	if (child->pipefd != -1)
 		close(child->pipefd);
+	sshbuf_free(child->config);
+	sshbuf_free(child->keys);
 	free(child->id);
 	memset(child, '\0', sizeof(*child));
 	child->pipefd = -1;
@@ -336,6 +345,16 @@ child_reap(struct early_child *child)
 {
 	LogLevel level = SYSLOG_LEVEL_DEBUG1;
 	int was_crash, penalty_type = SRCLIMIT_PENALTY_NONE;
+	const char *child_status;
+
+	if (child->config)
+		child_status = " (sending config)";
+	else if (child->keys)
+		child_status = " (sending keys)";
+	else if (child->early)
+		child_status = " (early)";
+	else
+		child_status = "";
 
 	/* Log exit information */
 	if (WIFSIGNALED(child->status)) {
@@ -347,54 +366,50 @@ child_reap(struct early_child *child)
 			level = SYSLOG_LEVEL_ERROR;
 		do_log2(level, "session process %ld for %s killed by "
 		    "signal %d%s", (long)child->pid, child->id,
-		    WTERMSIG(child->status), child->early ? " (early)" : "");
+		    WTERMSIG(child->status), child_status);
 		if (was_crash)
 			penalty_type = SRCLIMIT_PENALTY_CRASH;
 	} else if (!WIFEXITED(child->status)) {
 		penalty_type = SRCLIMIT_PENALTY_CRASH;
 		error("session process %ld for %s terminated abnormally, "
 		    "status=0x%x%s", (long)child->pid, child->id, child->status,
-		    child->early ? " (early)" : "");
+		    child_status);
 	} else {
 		/* Normal exit. We care about the status */
 		switch (WEXITSTATUS(child->status)) {
 		case 0:
 			debug3_f("preauth child %ld for %s completed "
-			    "normally %s", (long)child->pid, child->id,
-			    child->early ? " (early)" : "");
+			    "normally%s", (long)child->pid, child->id,
+			    child_status);
 			break;
 		case EXIT_LOGIN_GRACE:
 			penalty_type = SRCLIMIT_PENALTY_GRACE_EXCEEDED;
 			logit("Timeout before authentication for %s, "
 			    "pid = %ld%s", child->id, (long)child->pid,
-			    child->early ? " (early)" : "");
+			    child_status);
 			break;
 		case EXIT_CHILD_CRASH:
 			penalty_type = SRCLIMIT_PENALTY_CRASH;
 			logit("Session process %ld unpriv child crash for %s%s",
-			    (long)child->pid, child->id,
-			    child->early ? " (early)" : "");
+			    (long)child->pid, child->id, child_status);
 			break;
 		case EXIT_AUTH_ATTEMPTED:
 			penalty_type = SRCLIMIT_PENALTY_AUTHFAIL;
 			debug_f("preauth child %ld for %s exited "
-			    "after unsuccessful auth attempt %s",
-			    (long)child->pid, child->id,
-			    child->early ? " (early)" : "");
+			    "after unsuccessful auth attempt%s",
+			    (long)child->pid, child->id, child_status);
 			break;
 		case EXIT_CONFIG_REFUSED:
 			penalty_type = SRCLIMIT_PENALTY_REFUSECONNECTION;
 			debug_f("preauth child %ld for %s prohibited by"
-			    "RefuseConnection %s",
-			    (long)child->pid, child->id,
-			    child->early ? " (early)" : "");
+			    "RefuseConnection%s",
+			    (long)child->pid, child->id, child_status);
 			break;
 		default:
 			penalty_type = SRCLIMIT_PENALTY_NOAUTH;
 			debug_f("preauth child %ld for %s exited "
 			    "with status %d%s", (long)child->pid, child->id,
-			    WEXITSTATUS(child->status),
-			    child->early ? " (early)" : "");
+			    WEXITSTATUS(child->status), child_status);
 			break;
 		}
 	}
@@ -457,6 +472,7 @@ static void
 show_info(void)
 {
 	int i;
+	const char *child_status;
 
 	/* XXX print listening sockets here too */
 	if (children == NULL)
@@ -465,9 +481,16 @@ show_info(void)
 	for (i = 0; i < options.max_startups; i++) {
 		if (children[i].pipefd == -1 && children[i].pid <= 0)
 			continue;
+		if (children[i].config)
+			child_status = " (sending config)";
+		else if (children[i].keys)
+			child_status = " (sending keys)";
+		else if (children[i].early)
+			child_status = " (early)";
+		else
+			child_status = "";
 		logit("child %d: fd=%d pid=%ld %s%s", i, children[i].pipefd,
-		    (long)children[i].pid, children[i].id,
-		    children[i].early ? " (early)" : "");
+		    (long)children[i].pid, children[i].id, child_status);
 	}
 	srclimit_penalty_info();
 }
@@ -630,11 +653,13 @@ usage(void)
 static struct sshbuf *
 pack_hostkeys(void)
 {
-	struct sshbuf *keybuf = NULL, *hostkeys = NULL;
+	struct sshbuf *m = NULL, *keybuf = NULL, *hostkeys = NULL;
 	int r;
 	u_int i;
+	size_t len;
 
-	if ((keybuf = sshbuf_new()) == NULL ||
+	if ((m = sshbuf_new()) == NULL ||
+	    (keybuf = sshbuf_new()) == NULL ||
 	    (hostkeys = sshbuf_new()) == NULL)
 		fatal_f("sshbuf_new failed");
 
@@ -669,19 +694,28 @@ pack_hostkeys(void)
 		}
 	}
 
+	if ((r = sshbuf_put_u32(m, 0)) != 0 ||
+	    (r = sshbuf_put_u8(m, 0)) != 0 ||
+	    (r = sshbuf_put_stringb(m, hostkeys)) != 0)
+		fatal_fr(r, "compose message");
+	if ((len = sshbuf_len(m)) < 5 || len > 0xffffffff)
+		fatal_f("bad length %zu", len);
+	POKE_U32(sshbuf_mutable_ptr(m), len - 4);
+
 	sshbuf_free(keybuf);
-	return hostkeys;
+	sshbuf_free(hostkeys);
+	return m;
 }
 
-static void
-send_rexec_state(int fd, struct sshbuf *conf)
+static struct sshbuf *
+pack_config(struct sshbuf *conf)
 {
-	struct sshbuf *m = NULL, *inc = NULL, *hostkeys = NULL;
+	struct sshbuf *m = NULL, *inc = NULL;
 	struct include_item *item = NULL;
-	int r, sz;
+	size_t len;
+	int r;
 
-	debug3_f("entering fd = %d config len %zu", fd,
-	    sshbuf_len(conf));
+	debug3_f("d config len %zu", sshbuf_len(conf));
 
 	if ((m = sshbuf_new()) == NULL ||
 	    (inc = sshbuf_new()) == NULL)
@@ -695,42 +729,76 @@ send_rexec_state(int fd, struct sshbuf *conf)
 			fatal_fr(r, "compose includes");
 	}
 
-	hostkeys = pack_hostkeys();
-
-	/*
-	 * Protocol from reexec master to child:
-	 *	string	configuration
-	 *	uint64	timing_secret
-	 *	string	host_keys[] {
-	 *		string private_key
-	 *		string public_key
-	 *		string certificate
-	 *	}
-	 *	string	included_files[] {
-	 *		string	selector
-	 *		string	filename
-	 *		string	contents
-	 *	}
-	 */
-	if ((r = sshbuf_put_stringb(m, conf)) != 0 ||
+	if ((r = sshbuf_put_u32(m, 0)) != 0 ||
+	    (r = sshbuf_put_u8(m, 0)) != 0 ||
+	    (r = sshbuf_put_stringb(m, conf)) != 0 ||
 	    (r = sshbuf_put_u64(m, options.timing_secret)) != 0 ||
-	    (r = sshbuf_put_stringb(m, hostkeys)) != 0 ||
 	    (r = sshbuf_put_stringb(m, inc)) != 0)
 		fatal_fr(r, "compose config");
 
-	/* We need to fit the entire message inside the socket send buffer */
-	sz = ROUNDUP(sshbuf_len(m) + 5, 16*1024);
-	if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sz, sizeof sz) == -1)
-		fatal_f("setsockopt SO_SNDBUF: %s", strerror(errno));
+	if ((len = sshbuf_len(m)) < 5 || len > 0xffffffff)
+		fatal_f("bad length %zu", len);
+	POKE_U32(sshbuf_mutable_ptr(m), len - 4);
 
-	if (ssh_msg_send(fd, 0, m) == -1)
-		error_f("ssh_msg_send failed");
-
-	sshbuf_free(m);
 	sshbuf_free(inc);
-	sshbuf_free(hostkeys);
 
 	debug3_f("done");
+	return m;
+}
+
+/*
+ * Protocol from reexec master to child:
+ *	uint32  size
+ *	uint8   type (ignored)
+ *	string	configuration
+ *	uint64	timing_secret
+ *	string	included_files[] {
+ *		string	selector
+ *		string	filename
+ *		string	contents
+ *	}
+ * Second message
+ *	uint32  size
+ *	uint8   type (ignored)
+ *	string	host_keys[] {
+ *		string private_key
+ *		string public_key
+ *		string certificate
+ *	}
+ */
+/*
+ * This function is used only if inet_flag or debug_flag is set,
+ * otherwise the data is sent from the main poll loop.
+ * It sends the config from a child process back to the parent.
+ * The parent will read the config after exec.
+ */
+static void
+send_rexec_state(int fd)
+{
+	struct sshbuf *keys;
+	u_int mlen;
+	pid_t pid;
+
+	if ((pid = fork()) == -1)
+		fatal_f("fork failed: %s", strerror(errno));
+	if (pid != 0)
+		return;
+
+	debug3_f("entering fd = %d config len %zu", fd,
+	    sshbuf_len(config));
+
+	mlen = sshbuf_len(config);
+	if (atomicio(vwrite, fd, sshbuf_mutable_ptr(config), mlen) != mlen)
+		error_f("write: %s", strerror(errno));
+
+	keys = pack_hostkeys();
+	mlen = sshbuf_len(keys);
+	if (atomicio(vwrite, fd, sshbuf_mutable_ptr(keys), mlen) != mlen)
+		error_f("write: %s", strerror(errno));
+
+	sshbuf_free(keys);
+	debug3_f("done");
+	exit(0);
 }
 
 /*
@@ -845,12 +913,15 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
     int log_stderr)
 {
 	struct pollfd *pfd = NULL;
-	int i, ret, npfd;
+	int i, ret, npfd, r;
 	int oactive = -1, listening = 0, lameduck = 0;
-	int startup_p[2] = { -1 , -1 }, *startup_pollfd;
+	int *startup_pollfd;
+	ssize_t len;
+	const u_char *ptr;
 	char c = 0;
 	struct sockaddr_storage from;
 	struct early_child *child;
+	struct sshbuf *buf;
 	socklen_t fromlen;
 	u_char rnd[256];
 	sigset_t nsigset, osigset;
@@ -928,6 +999,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
 			if (children[i].pipefd != -1) {
 				pfd[npfd].fd = children[i].pipefd;
 				pfd[npfd].events = POLLIN;
+				if (children[i].config != NULL ||
+				    children[i].keys != NULL)
+					pfd[npfd].events |= POLLOUT;
 				startup_pollfd[i] = npfd++;
 			}
 		}
@@ -943,6 +1017,50 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
 		if (ret == -1)
 			continue;
 
+		for (i = 0; i < options.max_startups; i++) {
+			if (children[i].pipefd == -1 ||
+			    startup_pollfd[i] == -1 ||
+			    !(pfd[startup_pollfd[i]].revents & POLLOUT))
+				continue;
+			if (children[i].config)
+				buf = children[i].config;
+			else if (children[i].keys)
+				buf = children[i].keys;
+			else {
+				error_f("no buffer to send");
+				continue;
+			}
+			ptr = sshbuf_ptr(buf);
+			len = sshbuf_len(buf);
+			ret = write(children[i].pipefd, ptr, len);
+			if (ret == -1 && (errno == EINTR || errno == EAGAIN))
+				continue;
+			if (ret <= 0) {
+				if (children[i].early)
+					listening--;
+				srclimit_done(children[i].pipefd);
+				child_close(&(children[i]), 0, 0);
+				continue;
+			}
+			if (ret == len) {
+				/* finished sending buffer */
+				sshbuf_free(buf);
+				if (children[i].config == buf) {
+					/* sent config, now send keys */
+					children[i].config = NULL;
+					children[i].keys = pack_hostkeys();
+				} else if (children[i].keys == buf) {
+					/* sent both config and keys */
+					children[i].keys = NULL;
+				} else {
+					fatal("config buf not set");
+				}
+
+			} else {
+				if ((r = sshbuf_consume(buf, ret)) != 0)
+					fatal_fr(r, "config buf inconsistent");
+			}
+		}
 		for (i = 0; i < options.max_startups; i++) {
 			if (children[i].pipefd == -1 ||
 			    startup_pollfd[i] == -1 ||
@@ -966,6 +1084,17 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
 				child_close(&(children[i]), 0, 0);
 				break;
 			case 1:
+				if (children[i].config) {
+					error_f("startup pipe %d (fd=%d)"
+					    " early read", i, children[i].pipefd);
+					if (children[i].early)
+						listening--;
+					if (children[i].pid > 0)
+						kill(children[i].pid, SIGTERM);
+					srclimit_done(children[i].pipefd);
+					child_close(&(children[i]), 0, 0);
+					break;
+				}
 				if (children[i].early && c == '\0') {
 					/* child has finished preliminaries */
 					listening--;
@@ -1007,26 +1136,18 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
 				close(*newsock);
 				continue;
 			}
-			if (pipe(startup_p) == -1) {
-				error_f("pipe(startup_p): %s", strerror(errno));
-				close(*newsock);
-				continue;
-			}
-			if (drop_connection(*newsock,
-			    children_active, startup_p[0])) {
-				close(*newsock);
-				close(startup_p[0]);
-				close(startup_p[1]);
-				continue;
-			}
-
 			if (socketpair(AF_UNIX,
 			    SOCK_STREAM, 0, config_s) == -1) {
 				error("reexec socketpair: %s",
 				    strerror(errno));
 				close(*newsock);
-				close(startup_p[0]);
-				close(startup_p[1]);
+				continue;
+			}
+			if (drop_connection(*newsock,
+			    children_active, config_s[0])) {
+				close(*newsock);
+				close(config_s[0]);
+				close(config_s[1]);
 				continue;
 			}
 
@@ -1044,10 +1165,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
 				close_listen_socks();
 				*sock_in = *newsock;
 				*sock_out = *newsock;
-				close(startup_p[0]);
-				close(startup_p[1]);
-				startup_pipe = -1;
-				send_rexec_state(config_s[0], cfg);
+				send_rexec_state(config_s[0]);
 				close(config_s[0]);
 				free(pfd);
 				return;
@@ -1059,8 +1177,9 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
 			 * parent continues listening.
 			 */
 			platform_pre_fork();
+			set_nonblock(config_s[0]);
 			listening++;
-			child = child_register(startup_p[0], *newsock);
+			child = child_register(config_s[0], *newsock);
 			if ((child->pid = fork()) == 0) {
 				/*
 				 * Child.  Close the listening and
@@ -1071,7 +1190,6 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
 				 * the connection.
 				 */
 				platform_post_fork_child();
-				startup_pipe = startup_p[1];
 				close_startup_pipes();
 				close_listen_socks();
 				*sock_in = *newsock;
@@ -1092,11 +1210,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
 			else
 				debug("Forked child %ld.", (long)child->pid);
 
-			close(startup_p[1]);
-
 			close(config_s[1]);
-			send_rexec_state(config_s[0], cfg);
-			close(config_s[0]);
 			close(*newsock);
 
 			/*
@@ -1714,12 +1828,14 @@ main(int ac, char **av)
 	/* ignore SIGPIPE */
 	ssh_signal(SIGPIPE, SIG_IGN);
 
+	config = pack_config(cfg);
+
 	/* Get a connection, either from inetd or a listening TCP socket */
 	if (inetd_flag) {
 		/* Send configuration to ancestor sshd-session process */
 		if (socketpair(AF_UNIX, SOCK_STREAM, 0, config_s) == -1)
 			fatal("socketpair: %s", strerror(errno));
-		send_rexec_state(config_s[0], cfg);
+		send_rexec_state(config_s[0]);
 		close(config_s[0]);
 	} else {
 		platform_pre_listen();
@@ -1767,8 +1883,8 @@ main(int ac, char **av)
 	if (!debug_flag && !inetd_flag && setsid() == -1)
 		error("setsid: %.100s", strerror(errno));
 
-	debug("rexec start in %d out %d newsock %d pipe %d sock %d/%d",
-	    sock_in, sock_out, newsock, startup_pipe, config_s[0], config_s[1]);
+	debug("rexec start in %d out %d newsock %d config_s %d/%d",
+	    sock_in, sock_out, newsock, config_s[0], config_s[1]);
 	if (!inetd_flag) {
 		if (dup2(newsock, STDIN_FILENO) == -1)
 			fatal("dup2 stdin: %s", strerror(errno));
@@ -1782,13 +1898,6 @@ main(int ac, char **av)
 			fatal("dup2 config_s: %s", strerror(errno));
 		close(config_s[1]);
 	}
-	if (startup_pipe == -1)
-		close(REEXEC_STARTUP_PIPE_FD);
-	else if (startup_pipe != REEXEC_STARTUP_PIPE_FD) {
-		if (dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD) == -1)
-			fatal("dup2 startup_p: %s", strerror(errno));
-		close(startup_pipe);
-	}
 	log_redirect_stderr_to(NULL);
 	closefrom(REEXEC_MIN_FREE_FD);
 

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list