]> andersk Git - openssh.git/commitdiff
- djm@cvs.openbsd.org 2007/06/14 22:48:05
authordtucker <dtucker>
Mon, 25 Jun 2007 08:59:17 +0000 (08:59 +0000)
committerdtucker <dtucker>
Mon, 25 Jun 2007 08:59:17 +0000 (08:59 +0000)
     [ssh.c]
     when waiting for the multiplex exit status, read until the master end
     writes an entire int of data *and* closes the client_fd; fixes mux
     regression spotted by dtucker, ok dtucker@

ChangeLog
ssh.c

index e198f66417ba4720f687ea8c3ece08d7566283d8..619bd8d091a226021c3931a200029321d4ea25d4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,11 @@
    - djm@cvs.openbsd.org 2007/06/14 21:43:25
      [ssh.c]
      handle EINTR when waiting for mux exit status properly
+   - djm@cvs.openbsd.org 2007/06/14 22:48:05
+     [ssh.c]
+     when waiting for the multiplex exit status, read until the master end
+     writes an entire int of data *and* closes the client_fd; fixes mux
+     regression spotted by dtucker, ok dtucker@
 
 20070614
  - (dtucker) [cipher-ctr.c umac.c openbsd-compat/openssl-compat.h] Move the
diff --git a/ssh.c b/ssh.c
index ab9da1e974c12770537b51cd665c731f2cfdd29e..449ec256e0a35a410198232f9bf02e9a2739243c 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.c,v 1.299 2007/06/14 21:43:25 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.300 2007/06/14 22:48:05 djm Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1311,7 +1311,7 @@ static void
 control_client(const char *path)
 {
        struct sockaddr_un addr;
-       int i, r, fd, sock, exitval, num_env, addr_len;
+       int i, r, fd, sock, exitval[2], num_env, addr_len;
        Buffer m;
        char *term;
        extern char **environ;
@@ -1460,10 +1460,16 @@ control_client(const char *path)
        if (tty_flag)
                enter_raw_mode();
 
-       /* Stick around until the controlee closes the client_fd */
-       exitval = 0;
+       /*
+        * Stick around until the controlee closes the client_fd.
+        * Before it does, it is expected to write this process' exit
+        * value (one int). This process must read the value and wait for
+        * the closure of the client_fd; if this one closes early, the 
+        * multiplex master will terminate early too (possibly losing data).
+        */
+       exitval[0] = 0;
        for (i = 0; !control_client_terminate && i < (int)sizeof(exitval);) {
-               r = read(sock, (char *)&exitval + i, sizeof(exitval) - i);
+               r = read(sock, (char *)exitval + i, sizeof(exitval) - i);
                if (r == 0) {
                        debug2("Received EOF from master");
                        break;
@@ -1475,21 +1481,23 @@ control_client(const char *path)
                }
                i += r;
        }
+
        close(sock);
        leave_raw_mode();
-
+       if (i > (int)sizeof(int))
+               fatal("%s: master returned too much data (%d > %lu)",
+                   __func__, i, sizeof(int));
        if (control_client_terminate) {
                debug2("Exiting on signal %d", control_client_terminate);
-               exitval = 255;
-       } else if (i < (int)sizeof(exitval)) {
+               exitval[0] = 255;
+       } else if (i < (int)sizeof(int)) {
                debug2("Control master terminated unexpectedly");
-               exitval = 255;
+               exitval[0] = 255;
        } else
-               debug2("Received exit status from master %d", exitval);
+               debug2("Received exit status from master %d", exitval[0]);
 
        if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET)
-               fprintf(stderr, "Shared connection to %s closed.\r\n",
-                   host);
+               fprintf(stderr, "Shared connection to %s closed.\r\n", host);
 
-       exit(exitval);
+       exit(exitval[0]);
 }
This page took 0.057671 seconds and 5 git commands to generate.