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