Telnetd should close stray descriptors in its children

Doug Graham dgraham at nortel.com
Tue Jun 9 06:24:58 UTC 2009


Hello,

Telnetd does not close its socket or master PTY descriptors in its 
children.  This means that if the
login shell that it invokes (configurable via the -l option) does not 
close stray descriptors, those
descriptors remain open for as long as all sessions that inherited them 
remain alive.

For example, suppose session-1 is created.  Child processes in that 
session will inherit sock-1 and
ptym-1.  If session-2 is created before session-1 exits, session-2 will 
inherit sock-2 and ptym-2, but
also sock-1 and ptym-1.  If session-1 is then exited, telnetd closes its 
copy of sock-1 and ptym-1,
but those are still both open in session-2.  The result is that 
session-1 appears to hang, because the
actual network connection to the client is not closed because of the 
still-open sock-1 descriptor.
The telnet client does not see EOF on its socket.

This is easily reproducible by starting telnetd like so:

   telnetd -l /bin/sh -p 1234

then telnetting to port 1234 from one client, and the same again from a 
different client, then typing
"exit" in the first session.  That session will hang until the second 
session is also exited.
 
Here's one possible patch; another approach might be to set the 
FD_CLOEXEC flag on those
descriptors which should not be inherited by telnetd's children.

--- busybox-1.13.2/networking/telnetd.c 2009/01/21 20:02:39     1.1
+++ busybox-1.13.2/networking/telnetd.c 2009/06/09 05:53:08
@@ -248,6 +248,8 @@
        xopen(tty_name, O_RDWR); /* becomes our ctty */
        xdup2(0, 1);
        xdup2(0, 2);
+       for (fd = getdtablesize(); --fd >= 3; )
+               close(fd);
        tcsetpgrp(0, getpid()); /* switch this tty's process group to us */
 
        /* The pseudo-terminal allocated to the client is configured to 
operate in

--Doug





More information about the busybox mailing list