diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | ssh.c | 34 |
2 files changed, 27 insertions, 14 deletions
@@ -7,6 +7,11 @@ | |||
7 | - djm@cvs.openbsd.org 2007/06/14 21:43:25 | 7 | - djm@cvs.openbsd.org 2007/06/14 21:43:25 |
8 | [ssh.c] | 8 | [ssh.c] |
9 | handle EINTR when waiting for mux exit status properly | 9 | handle EINTR when waiting for mux exit status properly |
10 | - djm@cvs.openbsd.org 2007/06/14 22:48:05 | ||
11 | [ssh.c] | ||
12 | when waiting for the multiplex exit status, read until the master end | ||
13 | writes an entire int of data *and* closes the client_fd; fixes mux | ||
14 | regression spotted by dtucker, ok dtucker@ | ||
10 | 15 | ||
11 | 20070614 | 16 | 20070614 |
12 | - (dtucker) [cipher-ctr.c umac.c openbsd-compat/openssl-compat.h] Move the | 17 | - (dtucker) [cipher-ctr.c umac.c openbsd-compat/openssl-compat.h] Move the |
@@ -3082,4 +3087,4 @@ | |||
3082 | OpenServer 6 and add osr5bigcrypt support so when someone migrates | 3087 | OpenServer 6 and add osr5bigcrypt support so when someone migrates |
3083 | passwords between UnixWare and OpenServer they will still work. OK dtucker@ | 3088 | passwords between UnixWare and OpenServer they will still work. OK dtucker@ |
3084 | 3089 | ||
3085 | $Id: ChangeLog,v 1.4704 2007/06/25 08:34:43 dtucker Exp $ | 3090 | $Id: ChangeLog,v 1.4705 2007/06/25 08:59:17 dtucker Exp $ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.299 2007/06/14 21:43:25 djm Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.300 2007/06/14 22:48:05 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -1311,7 +1311,7 @@ static void | |||
1311 | control_client(const char *path) | 1311 | control_client(const char *path) |
1312 | { | 1312 | { |
1313 | struct sockaddr_un addr; | 1313 | struct sockaddr_un addr; |
1314 | int i, r, fd, sock, exitval, num_env, addr_len; | 1314 | int i, r, fd, sock, exitval[2], num_env, addr_len; |
1315 | Buffer m; | 1315 | Buffer m; |
1316 | char *term; | 1316 | char *term; |
1317 | extern char **environ; | 1317 | extern char **environ; |
@@ -1460,10 +1460,16 @@ control_client(const char *path) | |||
1460 | if (tty_flag) | 1460 | if (tty_flag) |
1461 | enter_raw_mode(); | 1461 | enter_raw_mode(); |
1462 | 1462 | ||
1463 | /* Stick around until the controlee closes the client_fd */ | 1463 | /* |
1464 | exitval = 0; | 1464 | * Stick around until the controlee closes the client_fd. |
1465 | * Before it does, it is expected to write this process' exit | ||
1466 | * value (one int). This process must read the value and wait for | ||
1467 | * the closure of the client_fd; if this one closes early, the | ||
1468 | * multiplex master will terminate early too (possibly losing data). | ||
1469 | */ | ||
1470 | exitval[0] = 0; | ||
1465 | for (i = 0; !control_client_terminate && i < (int)sizeof(exitval);) { | 1471 | for (i = 0; !control_client_terminate && i < (int)sizeof(exitval);) { |
1466 | r = read(sock, (char *)&exitval + i, sizeof(exitval) - i); | 1472 | r = read(sock, (char *)exitval + i, sizeof(exitval) - i); |
1467 | if (r == 0) { | 1473 | if (r == 0) { |
1468 | debug2("Received EOF from master"); | 1474 | debug2("Received EOF from master"); |
1469 | break; | 1475 | break; |
@@ -1475,21 +1481,23 @@ control_client(const char *path) | |||
1475 | } | 1481 | } |
1476 | i += r; | 1482 | i += r; |
1477 | } | 1483 | } |
1484 | |||
1478 | close(sock); | 1485 | close(sock); |
1479 | leave_raw_mode(); | 1486 | leave_raw_mode(); |
1480 | 1487 | if (i > (int)sizeof(int)) | |
1488 | fatal("%s: master returned too much data (%d > %lu)", | ||
1489 | __func__, i, sizeof(int)); | ||
1481 | if (control_client_terminate) { | 1490 | if (control_client_terminate) { |
1482 | debug2("Exiting on signal %d", control_client_terminate); | 1491 | debug2("Exiting on signal %d", control_client_terminate); |
1483 | exitval = 255; | 1492 | exitval[0] = 255; |
1484 | } else if (i < (int)sizeof(exitval)) { | 1493 | } else if (i < (int)sizeof(int)) { |
1485 | debug2("Control master terminated unexpectedly"); | 1494 | debug2("Control master terminated unexpectedly"); |
1486 | exitval = 255; | 1495 | exitval[0] = 255; |
1487 | } else | 1496 | } else |
1488 | debug2("Received exit status from master %d", exitval); | 1497 | debug2("Received exit status from master %d", exitval[0]); |
1489 | 1498 | ||
1490 | if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET) | 1499 | if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET) |
1491 | fprintf(stderr, "Shared connection to %s closed.\r\n", | 1500 | fprintf(stderr, "Shared connection to %s closed.\r\n", host); |
1492 | host); | ||
1493 | 1501 | ||
1494 | exit(exitval); | 1502 | exit(exitval[0]); |
1495 | } | 1503 | } |