[openssh-commits] [openssh] 02/04: upstream: Switch scp from using pipes to a socketpair for

git+noreply at mindrot.org git+noreply at mindrot.org
Wed Jan 11 11:48:44 AEDT 2023


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

djm pushed a commit to branch master
in repository openssh.

commit eec737b59cf13841de46134967a206607000acd4
Author: millert at openbsd.org <millert at openbsd.org>
Date:   Tue Jan 10 23:22:15 2023 +0000

    upstream: Switch scp from using pipes to a socketpair for
    
    communication with it's ssh sub-processes.  We no longer need to reserve two
    descriptors to ensure that we don't end up using fd 0-2 unexpectedly, that is
    handled by sanitise_stdfd() in main(). Based on an original diff from djm at .
    OK deraadt@ djm@
    
    OpenBSD-Commit-ID: b80c372faac462471e955ddeab9480d668a2e48d
---
 scp.c | 62 +++++++++++++++++++++++++-------------------------------------
 1 file changed, 25 insertions(+), 37 deletions(-)

diff --git a/scp.c b/scp.c
index 93ac8ed7..42cd034b 100644
--- a/scp.c
+++ b/scp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scp.c,v 1.251 2022/12/16 06:52:48 jmc Exp $ */
+/* $OpenBSD: scp.c,v 1.252 2023/01/10 23:22:15 millert Exp $ */
 /*
  * scp - secure remote copy.  This is basically patched BSD rcp which
  * uses ssh to do the data transfer (instead of using rcmd).
@@ -279,7 +279,7 @@ int
 do_cmd(char *program, char *host, char *remuser, int port, int subsystem,
     char *cmd, int *fdin, int *fdout, pid_t *pid)
 {
-	int pin[2], pout[2], reserved[2];
+	int sv[2];
 
 	if (verbose_mode)
 		fmprintf(stderr,
@@ -290,22 +290,9 @@ do_cmd(char *program, char *host, char *remuser, int port, int subsystem,
 	if (port == -1)
 		port = sshport;
 
-	/*
-	 * Reserve two descriptors so that the real pipes won't get
-	 * descriptors 0 and 1 because that will screw up dup2 below.
-	 */
-	if (pipe(reserved) == -1)
-		fatal("pipe: %s", strerror(errno));
-
 	/* Create a socket pair for communicating with ssh. */
-	if (pipe(pin) == -1)
-		fatal("pipe: %s", strerror(errno));
-	if (pipe(pout) == -1)
-		fatal("pipe: %s", strerror(errno));
-
-	/* Free the reserved descriptors. */
-	close(reserved[0]);
-	close(reserved[1]);
+	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1)
+		fatal("socketpair: %s", strerror(errno));
 
 	ssh_signal(SIGTSTP, suspchild);
 	ssh_signal(SIGTTIN, suspchild);
@@ -313,15 +300,18 @@ do_cmd(char *program, char *host, char *remuser, int port, int subsystem,
 
 	/* Fork a child to execute the command on the remote host using ssh. */
 	*pid = fork();
-	if (*pid == 0) {
+	switch (*pid) {
+	case -1:
+		fatal("fork: %s", strerror(errno));
+	case 0:
 		/* Child. */
-		close(pin[1]);
-		close(pout[0]);
-		dup2(pin[0], 0);
-		dup2(pout[1], 1);
-		close(pin[0]);
-		close(pout[1]);
-
+		if (dup2(sv[0], STDIN_FILENO) == -1 ||
+		    dup2(sv[0], STDOUT_FILENO) == -1) {
+			perror("dup2");
+			_exit(1);
+		}
+		close(sv[0]);
+		close(sv[1]);
 		replacearg(&args, 0, "%s", program);
 		if (port != -1) {
 			addargs(&args, "-p");
@@ -339,19 +329,17 @@ do_cmd(char *program, char *host, char *remuser, int port, int subsystem,
 
 		execvp(program, args.list);
 		perror(program);
-		exit(1);
-	} else if (*pid == -1) {
-		fatal("fork: %s", strerror(errno));
+		_exit(1);
+	default:
+		/* Parent.  Close the other side, and return the local side. */
+		close(sv[0]);
+		*fdin = sv[1];
+		*fdout = sv[1];
+		ssh_signal(SIGTERM, killchild);
+		ssh_signal(SIGINT, killchild);
+		ssh_signal(SIGHUP, killchild);
+		return 0;
 	}
-	/* Parent.  Close the other side, and return the local side. */
-	close(pin[0]);
-	*fdout = pin[1];
-	close(pout[1]);
-	*fdin = pout[0];
-	ssh_signal(SIGTERM, killchild);
-	ssh_signal(SIGINT, killchild);
-	ssh_signal(SIGHUP, killchild);
-	return 0;
 }
 
 /*

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


More information about the openssh-commits mailing list