On Tue, Jun 9, 2009 at 8:24 AM, Doug Graham<[email protected]> wrote:
> 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


Does the attached patch help?
--
vda
diff -d -urpN busybox.6/networking/telnetd.c busybox.7/networking/telnetd.c
--- busybox.6/networking/telnetd.c	2009-06-03 12:50:48.000000000 +0200
+++ busybox.7/networking/telnetd.c	2009-06-09 21:08:35.000000000 +0200
@@ -199,6 +199,14 @@ static size_t iac_safe_write(int fd, con
 	return total + rc;
 }
 
+/* Must match getopt32 string */
+enum {
+	OPT_WATCHCHILD = (1 << 2), /* -K */
+	OPT_INETD      = (1 << 3) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -i */
+	OPT_PORT       = (1 << 4) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -p */
+	OPT_FOREGROUND = (1 << 6) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -F */
+};
+
 static struct tsession *
 make_new_session(
 		IF_FEATURE_TELNETD_STANDALONE(int sock)
@@ -288,6 +296,19 @@ make_new_session(
 	/* Restore default signal handling ASAP */
 	bb_signals((1 << SIGCHLD) + (1 << SIGPIPE), SIG_DFL);
 
+#if ENABLE_FEATURE_TELNETD_STANDALONE
+	if (!(option_mask32 & OPT_INETD)) {
+		struct tsession *tp = sessions;
+		while (tp) {
+			close(tp->ptyfd);
+			close(tp->sockfd_read);
+			/* sockfd_write == sockfd_read for standalone telnetd */
+			/*close(tp->sockfd_write);*/
+			tp = tp->next;
+		}
+	}
+#endif
+
 	/* Make new session and process group */
 	setsid();
 
@@ -329,14 +350,6 @@ make_new_session(
 	_exit(EXIT_FAILURE); /*bb_perror_msg_and_die("execv %s", loginpath);*/
 }
 
-/* Must match getopt32 string */
-enum {
-	OPT_WATCHCHILD = (1 << 2), /* -K */
-	OPT_INETD      = (1 << 3) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -i */
-	OPT_PORT       = (1 << 4) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -p */
-	OPT_FOREGROUND = (1 << 6) * ENABLE_FEATURE_TELNETD_STANDALONE, /* -F */
-};
-
 #if ENABLE_FEATURE_TELNETD_STANDALONE
 
 static void
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to