Tru64 Unix vs. OpenSSH 2.9p2

Conrad Huang conrad at cgl.ucsf.EDU
Fri Jul 27 04:26:22 EST 2001


Hi,

We installed OpenSSH 2.9p2 with OpenSSL 0.9.6b on our Compaq Alpha ES40
running Tru64 Unix 5.0a.  We've been having problems where one of our
users appears in the output of "w" and is associated with a pseudoterminal
even though he has no processes attached to that pty.

The problem can be reproduced by connecting to the localhost host
via ssh using protocol version 2, and then killing the ssh client
with a SIGKILL.  The sshd server notices the connection closing and
exits, but does not update /etc/utmp.

I believe the problem is in server_loop2() in serverloop.c.  When
the ssh connection is terminated abruptly, one falls out of the
input processing loop and tries to clean up.  There is a loop that
"wait"s for child processes to die, and terminates the associated
sessions.  Unfortuately, the "wait" uses the WNOHANG flag, so any
session associated with a child that has not exited is just ignored.
Since the logout bookkeeping code is invoked through session_close(),
that means /etc/utmp is not updated.  (The child process, in this case
a login shell, exits after sshd dies because its standard input closes.)

Below are some diffs that seem to fix the problem.  Can one of the
OpenSSH developers please take a look and let me know if the analysis
and the fix are correct?  Thanks,

Conrad

===================================================================
RCS file: RCS/serverloop.c,v
retrieving revision 1.1
diff -c -r1.1 serverloop.c
*** serverloop.c	2001/07/26 16:50:27	1.1
--- serverloop.c	2001/07/26 18:09:04
***************
*** 697,702 ****
--- 697,703 ----
  	fd_set *readset = NULL, *writeset = NULL;
  	int rekeying = 0, max_fd, status;
  	pid_t pid;
+ 	int fd;
  
  	debug("Entering interactive session for SSH2.");
  
***************
*** 736,742 ****
  		xfree(writeset);
  
  	signal(SIGCHLD, SIG_DFL);
! 	while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
  		session_close_by_pid(pid, status);
  	channel_stop_listening();
  }
--- 737,745 ----
  		xfree(writeset);
  
  	signal(SIGCHLD, SIG_DFL);
! 	while ((fd = channel_find_open()) >= 0)
! 		channel_free(fd);
! 	while ((pid = waitpid(-1, &status, 0)) > 0)
  		session_close_by_pid(pid, status);
  	channel_stop_listening();
  }



More information about the openssh-unix-dev mailing list