From 2cbec749d76e73be167bc600ba4c5886b607eab2 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 12 Jun 2007 23:41:33 +1000 Subject: [PATCH] - djm@cvs.openbsd.org 2007/06/12 11:11:08 [ssh.c] fix slave exit value when a control master goes away without passing the full exit status by ensuring that the slave reads a full int. bz#1261 reported by frekko AT gmail.com; ok markus@ dtucker@ --- ChangeLog | 7 ++++++- ssh.c | 23 +++++++++++++---------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index b25d87490..41c47d2ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,11 @@ depends on the platform supporting sane O_NONBLOCK semantics for open on FIFOs (apparently POSIX does not mandate this), which OpenBSD does. bz #856; report by cjwatson AT debian.org; ok markus@ + - djm@cvs.openbsd.org 2007/06/12 11:11:08 + [ssh.c] + fix slave exit value when a control master goes away without passing the + full exit status by ensuring that the slave reads a full int. bz#1261 + reported by frekko AT gmail.com; ok markus@ dtucker@ 20070611 - (djm) Bugzilla #1306: silence spurious error messages from hang-on-exit @@ -3032,4 +3037,4 @@ OpenServer 6 and add osr5bigcrypt support so when someone migrates passwords between UnixWare and OpenServer they will still work. OK dtucker@ -$Id: ChangeLog,v 1.4692 2007/06/12 13:41:06 dtucker Exp $ +$Id: ChangeLog,v 1.4693 2007/06/12 13:41:33 dtucker Exp $ diff --git a/ssh.c b/ssh.c index cfaa1ff22..74c9a091b 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.295 2007/01/03 03:01:40 stevesk Exp $ */ +/* $OpenBSD: ssh.c,v 1.296 2007/06/12 11:11:08 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1458,25 +1458,28 @@ control_client(const char *path) /* Stick around until the controlee closes the client_fd */ exitval = 0; - for (;!control_client_terminate;) { - r = read(sock, &exitval, sizeof(exitval)); + for (i = 0; !control_client_terminate && i < (int)sizeof(exitval);) { + r = read(sock, (char *)&exitval + i, sizeof(exitval) - i); if (r == 0) { debug2("Received EOF from master"); break; } - if (r > 0) - debug2("Received exit status from master %d", exitval); if (r == -1 && errno != EINTR) fatal("%s: read %s", __func__, strerror(errno)); + i += r; } - - if (control_client_terminate) - debug2("Exiting on signal %d", control_client_terminate); - close(sock); - leave_raw_mode(); + if (control_client_terminate) { + debug2("Exiting on signal %d", control_client_terminate); + exitval = 255; + } else if (i < (int)sizeof(exitval)) { + debug2("Control master terminated unexpectedly"); + exitval = 255; + } else + debug2("Received exit status from master %d", exitval); + if (tty_flag && options.log_level != SYSLOG_LEVEL_QUIET) fprintf(stderr, "Connection to master closed.\r\n");