SSH connection hanging on logout

John Bowman bowman at math.ualberta.ca
Wed May 9 09:52:24 EST 2001


As is well known, current versions of openssh hang upon exit when
background processes exist. 

If these processes do not produce output to stdout or stderr they should be
allowed to continue to run silently.  (If they do try to produce output,
they will be killed by the shell.)  This would be consistent with the
behaviour of rsh, ssh, rlogin, telnet, csh, and bash.  In no case should
openssh wait around for them indefinitely.

Ssh is supposed to be a secure implementation of rsh and openssh is
supposed to be a open source version of ssh, so despite a few suggestions
to the contrary, this *really* is a bug.

The following patch to openssh-2.9p1 fixes the problem. This patch has now
been thoroughly tested and is believed not to break ssh or scp, unlike
previous related attempts.

I hope this patch is helpful,

-- John Bowman
University of Alberta
http://www.math.ualberta.ca/~bowman

diff -ur openssh-2.9p1/clientloop.c openssh-2.9p1J/clientloop.c
--- openssh-2.9p1/clientloop.c	Fri Apr 20 06:50:51 2001
+++ openssh-2.9p1J/clientloop.c	Wed May  2 16:21:16 2001
@@ -440,9 +440,13 @@
 		len = read(connection_in, buf, sizeof(buf));
 		if (len == 0) {
 			/* Received EOF.  The remote host has closed the connection. */
-			snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n",
-				 host);
-			buffer_append(&stderr_buffer, buf, strlen(buf));
+/* 
+ * This message duplicates the one already in client_loop().
+ *
+ *			snprintf(buf, sizeof buf, "Connection to %.300s closed by remote host.\r\n",
+ *				 host);
+ *			buffer_append(&stderr_buffer, buf, strlen(buf));
+ */			
 			quit_pending = 1;
 			return;
 		}
diff -ur openssh-2.9p1/nchan.c openssh-2.9p1J/nchan.c
--- openssh-2.9p1/nchan.c	Tue Apr  3 07:02:48 2001
+++ openssh-2.9p1J/nchan.c	Wed May  2 16:19:11 2001
@@ -56,7 +56,7 @@
 
 /* helper */
 static void	chan_shutdown_write(Channel *c);
-static void	chan_shutdown_read(Channel *c);
+void		chan_shutdown_read(Channel *c);
 
 /*
  * SSH1 specific implementation of event functions
@@ -479,7 +479,7 @@
 		c->wfd = -1;
 	}
 }
-static void
+void
 chan_shutdown_read(Channel *c)
 {
 	if (compat20 && c->type == SSH_CHANNEL_LARVAL)
diff -ur openssh-2.9p1/nchan.h openssh-2.9p1J/nchan.h
--- openssh-2.9p1/nchan.h	Sun Mar  4 23:16:12 2001
+++ openssh-2.9p1J/nchan.h	Wed May  2 16:19:11 2001
@@ -88,4 +88,5 @@
 
 void    chan_init_iostates(Channel * c);
 void	chan_init(void);
+void	chan_shutdown_read(Channel *c);
 #endif
diff -ur openssh-2.9p1/session.c openssh-2.9p1J/session.c
--- openssh-2.9p1/session.c	Wed Apr 18 09:29:34 2001
+++ openssh-2.9p1J/session.c	Wed May  2 16:20:04 2001
@@ -1960,6 +1960,8 @@
 	 */
 	if (c->ostate != CHAN_OUTPUT_CLOSED)
 		chan_write_failed(c);
+	if (c->istate != CHAN_INPUT_CLOSED)
+		chan_shutdown_read(c);
 	s->chanid = -1;
 }
 



More information about the openssh-unix-dev mailing list