sshd fails to close open file descriptors when forking
Ed Phillips
ed at UDel.Edu
Tue Oct 23 03:04:52 EST 2001
On Mon, 22 Oct 2001, Lutz Jaenicke wrote:
> Date: Mon, 22 Oct 2001 17:22:46 +0200
> From: Lutz Jaenicke <Lutz.Jaenicke at aet.TU-Cottbus.DE>
> To: openssh-unix-dev at mindrot.org
> Subject: Re: sshd fails to close open file descriptors when forking
>
> On Mon, Oct 22, 2001 at 11:03:26AM -0400, Ed Phillips wrote:
> > But the child processes don't have the _same_ file descriptors open, do
> > they? I thought they had a pipe(s) back to the sshd for protocol
> > encoding/decoding. Regardless, all the children need to exit _before_
> > sshd exits, and when they do, all of the file descriptors will be closed.
> > When sshd exits, there should be no open file descriptors, right? (And if
> > sshd exits when there is a process that has a file descriptor open that is
> > a "connection" back to the ssh client, then that's a bug, right?) Am I
> > missing some key point here? It seems simple... ;-)
>
> We are talking different issues here.
> * sshd daemonizes on startup. In this case it forks and the child process
> (to become the actual server) closes its fds for stdin, stdout, stderr.
> * When a new connection comes in, a sshd child process is created, that
> itself will fork()/exec() the user process, normally a shell.
> There are file descriptors for the network connection (channel) and for the
> user process. Typically the 3 default file descriptors for stdin, stdout,
> stderr are open between sshd and user process, but there may be more
> open files when X11 connections or port forwarding is used.
> * When the user process dies, it closes all of its file descriptors.
> sshd notes this closure and also closes all file descriptors. On the
> network side the connection is however not simply closed, but a
> handshake specified in the SSH protocol is performed to have the
> encrypted _channel_ closed down before the underlying network
> connection is closed. Then sshd can exit().
Okay... that makes sense.
> The often experienced "hang on exit()" problem is caused by processes
> started from the main user process. If at shell level a process is
> started with, say "sleep 20000 &", the sleep process may not close
> its file descriptors (stdin, stdout, stderr), which are identical to
> the shell's descriptors. Even when the shell now exits, sleep keeps the
> file descriptors open and therefore the handling sshd process thinks,
> that data may still be exchanged and does not shut down.
> (Of course, sleep won't exchange data, but there may be other more important
> processes be backgrounded.)
The problem I see is that there _are_ no background processes and no file
descriptors left open (there aren't even any processes running on the sshd
side)... but still, ssh hangs on the client side - even though there are
no sockets left on the server side. Maybe this is a problem with the
protocol implementation in v2.9p2, or maybe it's a problem where ssh
doesn't "know" that the file descriptors are gone (TCP sockets without
keep-alive, client doesn't realize that the count of valid file
descriptors is < 1, etc.).
Hopefully, I'll be able to tell if this is fixed in v2.9.9p2... sometime
today...
Thanks,
Ed
Ed Phillips <ed at udel.edu> University of Delaware (302) 831-6082
Systems Programmer III, Network and Systems Services
finger -l ed at polycut.nss.udel.edu for PGP public key
More information about the openssh-unix-dev
mailing list