[PATCH] telnetd: fix skipping of telnet options with parameters

Andreas Oberritter obi at opendreambox.org
Fri Mar 23 15:01:22 UTC 2012


* telnetd assumed 3 bytes width for all commands, but
  SB commands have variable length, ending with IAC SE.

Signed-off-by: Andreas Oberritter <obi at opendreambox.org>
---
 networking/telnetd.c |   54 ++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/networking/telnetd.c b/networking/telnetd.c
index 33020f1..d42cffb 100644
--- a/networking/telnetd.c
+++ b/networking/telnetd.c
@@ -153,24 +153,48 @@ remove_iacs(struct tsession *ts, int *pnum_totty)
 			break;
 		}
 		/*
-		 * IAC -> SB -> TELOPT_NAWS -> 4-byte -> IAC -> SE
+		 * IAC -> SB -> ABC -> <parameters> -> IAC -> SE,
+		 * at least 5 bytes
 		 */
-		if (ptr[1] == SB && ptr[2] == TELOPT_NAWS) {
-			struct winsize ws;
-			if ((ptr+8) >= end)
-				break;  /* incomplete, can't process */
-			ws.ws_col = (ptr[3] << 8) | ptr[4];
-			ws.ws_row = (ptr[5] << 8) | ptr[6];
-			ioctl(ts->ptyfd, TIOCSWINSZ, (char *)&ws);
-			ptr += 9;
-			continue;
-		}
-		/* skip 3-byte IAC non-SB cmd */
+		if (ptr[1] == SB) {
+			const unsigned char *sbend;
+			unsigned int plen;
+
+			if ((ptr + 5) > end)
+				break;
+			for (sbend = ptr + 4; sbend < end - 1; sbend++)
+				if (sbend[0] == IAC && sbend[1] == SE)
+					break;
+			if (sbend == end - 1)
+				break;
+
+			plen = sbend - (ptr + 3);
+
+			if (ptr[2] == TELOPT_NAWS) {
+				/*
+				 * IAC -> SB -> TELOPT_NAWS -> 4-byte -> IAC -> SE
+				 */
+				struct winsize ws;
+				if (plen != 4)
+					break;  /* incomplete, can't process */
+				ws.ws_col = (ptr[3] << 8) | ptr[4];
+				ws.ws_row = (ptr[5] << 8) | ptr[6];
+				ioctl(ts->ptyfd, TIOCSWINSZ, (char *)&ws);
+			} else {
+#if DEBUG
+				fprintf(stderr, "Ignoring IAC SB %s,%s\r\n",
+					TELCMD(ptr[1]), TELOPT(ptr[2]));
+#endif
+			}
+			ptr += plen + 5;
+		} else {
+			/* skip 3-byte IAC non-SB cmd */
 #if DEBUG
-		fprintf(stderr, "Ignoring IAC %s,%s\n",
-				TELCMD(ptr[1]), TELOPT(ptr[2]));
+			fprintf(stderr, "Ignoring IAC %s,%s\r\n",
+					TELCMD(ptr[1]), TELOPT(ptr[2]));
 #endif
-		ptr += 3;
+			ptr += 3;
+		}
 	}
 
 	num_totty = totty - ptr0;
-- 
1.7.7



More information about the busybox mailing list