Index: usr.bin/telnet/telnet.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/telnet/Attic/telnet.c,v
retrieving revision 1.8.2.3
diff -u -r1.8.2.3 telnet.c
--- usr.bin/telnet/telnet.c	13 Apr 2002 11:07:13 -0000	1.8.2.3
+++ usr.bin/telnet/telnet.c	27 Mar 2005 18:33:43 -0000
@@ -1193,6 +1193,7 @@
 }
 
 unsigned char slc_reply[128];
+unsigned char const * const slc_reply_eom = &slc_reply[sizeof(slc_reply)];
 unsigned char *slc_replyp;
 
 void
@@ -1208,6 +1209,14 @@
 void
 slc_add_reply(unsigned char func, unsigned char flags, cc_t value)
 {
+	/* A sequence of up to 6 bytes my be written for this member of the SLC
+	 * suboption list by this function.  The end of negotiation command,
+	 * which is written by slc_end_reply(), will require 2 additional
+	 * bytes.  Do not proceed unless there is sufficient space for these
+	 * items.
+	 */
+	if (&slc_replyp[6+2] > slc_reply_eom)
+		return;
 	if ((*slc_replyp++ = func) == IAC)
 		*slc_replyp++ = IAC;
 	if ((*slc_replyp++ = flags) == IAC)
@@ -1221,6 +1230,9 @@
 {
     int len;
 
+    /* The end of negotiation command requires 2 bytes. */
+    if (&slc_replyp[2] > slc_reply_eom)
+            return;
     *slc_replyp++ = IAC;
     *slc_replyp++ = SE;
     len = slc_replyp - slc_reply;
@@ -1338,8 +1350,8 @@
 	}
 }
 
-#define	OPT_REPLY_SIZE	256
-unsigned char *opt_reply;
+#define	OPT_REPLY_SIZE	(2 * SUBBUFSIZE)
+unsigned char *opt_reply = NULL;
 unsigned char *opt_replyp;
 unsigned char *opt_replyend;
 
@@ -1392,9 +1404,9 @@
 		return;
 	}
 	vp = env_getvalue(ep);
-	if (opt_replyp + (vp ? strlen((char *)vp) : 0) +
-				strlen((char *)ep) + 6 > opt_replyend)
-	{
+        if (opt_replyp + (vp ? 2 * strlen((char *)vp) : 0) +
+                                2 * strlen((char *)ep) + 6 > opt_replyend)
+        {
 		int len;
 		opt_replyend += OPT_REPLY_SIZE;
 		len = opt_replyend - opt_reply;
@@ -1418,6 +1430,8 @@
 		*opt_replyp++ = ENV_USERVAR;
 	for (;;) {
 		while ((c = *ep++)) {
+			if (opt_replyp + (2 + 2) > opt_replyend)
+				return;
 			switch(c&0xff) {
 			case IAC:
 				*opt_replyp++ = IAC;
@@ -1432,6 +1446,8 @@
 			*opt_replyp++ = c;
 		}
 		if ((ep = vp)) {
+			if (opt_replyp + (1 + 2 + 2) > opt_replyend)
+				return;
 #ifdef	OLD_ENVIRON
 			if (telopt_environ == TELOPT_OLD_ENVIRON)
 				*opt_replyp++ = old_env_value;
@@ -1462,7 +1478,9 @@
 {
 	int len;
 
-	len = opt_replyp - opt_reply + 2;
+	if (opt_replyp + 2 > opt_replyend)
+		return;
+	len = opt_replyp + 2 - opt_reply;
 	if (emptyok || len > 6) {
 		*opt_replyp++ = IAC;
 		*opt_replyp++ = SE;
Index: crypto/telnet/telnet/telnet.c
===================================================================
RCS file: /home/ncvs/src/crypto/telnet/telnet/Attic/telnet.c,v
retrieving revision 1.4.2.5
diff -u -r1.4.2.5 telnet.c
--- crypto/telnet/telnet/telnet.c	13 Apr 2002 10:59:08 -0000	1.4.2.5
+++ crypto/telnet/telnet/telnet.c	27 Mar 2005 18:34:33 -0000
@@ -1318,6 +1318,7 @@
 }
 
 unsigned char slc_reply[128];
+unsigned char const * const slc_reply_eom = &slc_reply[sizeof(slc_reply)];
 unsigned char *slc_replyp;
 
 void
@@ -1333,6 +1334,14 @@
 void
 slc_add_reply(unsigned char func, unsigned char flags, cc_t value)
 {
+	/* A sequence of up to 6 bytes my be written for this member of the SLC
+	 * suboption list by this function.  The end of negotiation command,
+	 * which is written by slc_end_reply(), will require 2 additional
+	 * bytes.  Do not proceed unless there is sufficient space for these
+	 * items.
+	 */
+	if (&slc_replyp[6+2] > slc_reply_eom)
+		return;
 	if ((*slc_replyp++ = func) == IAC)
 		*slc_replyp++ = IAC;
 	if ((*slc_replyp++ = flags) == IAC)
@@ -1346,6 +1355,9 @@
 {
     int len;
 
+    /* The end of negotiation command requires 2 bytes. */
+    if (&slc_replyp[2] > slc_reply_eom)
+            return;
     *slc_replyp++ = IAC;
     *slc_replyp++ = SE;
     len = slc_replyp - slc_reply;
@@ -1463,8 +1475,8 @@
 	}
 }
 
-#define	OPT_REPLY_SIZE	256
-unsigned char *opt_reply;
+#define	OPT_REPLY_SIZE	(2 * SUBBUFSIZE)
+unsigned char *opt_reply = NULL;
 unsigned char *opt_replyp;
 unsigned char *opt_replyend;
 
@@ -1517,9 +1529,9 @@
 		return;
 	}
 	vp = env_getvalue(ep);
-	if (opt_replyp + (vp ? strlen((char *)vp) : 0) +
-				strlen((char *)ep) + 6 > opt_replyend)
-	{
+        if (opt_replyp + (vp ? 2 * strlen((char *)vp) : 0) +
+                                2 * strlen((char *)ep) + 6 > opt_replyend)
+        {
 		int len;
 		opt_replyend += OPT_REPLY_SIZE;
 		len = opt_replyend - opt_reply;
@@ -1543,6 +1555,8 @@
 		*opt_replyp++ = ENV_USERVAR;
 	for (;;) {
 		while ((c = *ep++)) {
+			if (opt_replyp + (2 + 2) > opt_replyend)
+				return;
 			switch(c&0xff) {
 			case IAC:
 				*opt_replyp++ = IAC;
@@ -1557,6 +1571,8 @@
 			*opt_replyp++ = c;
 		}
 		if ((ep = vp)) {
+			if (opt_replyp + (1 + 2 + 2) > opt_replyend)
+				return;
 #ifdef	OLD_ENVIRON
 			if (telopt_environ == TELOPT_OLD_ENVIRON)
 				*opt_replyp++ = old_env_value;
@@ -1587,7 +1603,9 @@
 {
 	int len;
 
-	len = opt_replyp - opt_reply + 2;
+	if (opt_replyp + 2 > opt_replyend)
+		return;
+	len = opt_replyp + 2 - opt_reply;
 	if (emptyok || len > 6) {
 		*opt_replyp++ = IAC;
 		*opt_replyp++ = SE;
Index: crypto/heimdal/appl/telnet/telnet/telnet.c
===================================================================
RCS file: /home/ncvs/src/crypto/heimdal/appl/telnet/telnet/telnet.c,v
retrieving revision 1.1.1.1.2.3
diff -u -r1.1.1.1.2.3 telnet.c
--- crypto/heimdal/appl/telnet/telnet/telnet.c	1 Sep 2002 04:21:35 -0000	1.1.1.1.2.3
+++ crypto/heimdal/appl/telnet/telnet/telnet.c	27 Mar 2005 18:34:08 -0000
@@ -1294,6 +1294,7 @@
 
 
 unsigned char slc_reply[128];
+unsigned char const * const slc_reply_eom = &slc_reply[sizeof(slc_reply)];
 unsigned char *slc_replyp;
 
 void
@@ -1309,6 +1310,14 @@
 void
 slc_add_reply(unsigned char func, unsigned char flags, cc_t value)
 {
+	/* A sequence of up to 6 bytes my be written for this member of the SLC
+	 * suboption list by this function.  The end of negotiation command,
+	 * which is written by slc_end_reply(), will require 2 additional
+	 * bytes.  Do not proceed unless there is sufficient space for these
+	 * items.
+	 */
+	if (&slc_replyp[6+2] > slc_reply_eom)
+		return;
 	if ((*slc_replyp++ = func) == IAC)
 		*slc_replyp++ = IAC;
 	if ((*slc_replyp++ = flags) == IAC)
@@ -1322,6 +1331,9 @@
 {
     int len;
 
+    /* The end of negotiation command requires 2 bytes. */
+    if (&slc_replyp[2] > slc_reply_eom)
+            return;
     *slc_replyp++ = IAC;
     *slc_replyp++ = SE;
     len = slc_replyp - slc_reply;
@@ -1415,8 +1427,8 @@
 	}
 }
 
-#define	OPT_REPLY_SIZE	256
-unsigned char *opt_reply;
+#define	OPT_REPLY_SIZE	(2 * SUBBUFSIZE)
+unsigned char *opt_reply = NULL;
 unsigned char *opt_replyp;
 unsigned char *opt_replyend;
 
@@ -1475,9 +1487,9 @@
 		return;
 	}
 	vp = env_getvalue(ep);
-	if (opt_replyp + (vp ? strlen((char *)vp) : 0) +
-				strlen((char *)ep) + 6 > opt_replyend)
-	{
+        if (opt_replyp + (vp ? 2 * strlen((char *)vp) : 0) +
+                                2 * strlen((char *)ep) + 6 > opt_replyend)
+        {
 		int len;
 		void *tmp;
 		opt_replyend += OPT_REPLY_SIZE;
@@ -1503,6 +1515,8 @@
 		*opt_replyp++ = ENV_USERVAR;
 	for (;;) {
 		while ((c = *ep++)) {
+			if (opt_replyp + (2 + 2) > opt_replyend)
+				return;
 			switch(c&0xff) {
 			case IAC:
 				*opt_replyp++ = IAC;
@@ -1517,6 +1531,8 @@
 			*opt_replyp++ = c;
 		}
 		if ((ep = vp)) {
+			if (opt_replyp + (1 + 2 + 2) > opt_replyend)
+				return;
 #ifdef	OLD_ENVIRON
 			if (telopt_environ == TELOPT_OLD_ENVIRON)
 				*opt_replyp++ = old_env_value;
@@ -1547,7 +1563,9 @@
 {
 	int len;
 
-	len = opt_replyp - opt_reply + 2;
+	if (opt_replyp + 2 > opt_replyend)
+		return;
+	len = opt_replyp + 2 - opt_reply;
 	if (emptyok || len > 6) {
 		*opt_replyp++ = IAC;
 		*opt_replyp++ = SE;
Index: crypto/kerberosIV/appl/telnet/telnet/telnet.c
===================================================================
RCS file: /home/ncvs/src/crypto/kerberosIV/appl/telnet/telnet/Attic/telnet.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 telnet.c
--- crypto/kerberosIV/appl/telnet/telnet/telnet.c	19 Sep 1999 14:19:15 -0000	1.1.1.1
+++ crypto/kerberosIV/appl/telnet/telnet/telnet.c	27 Mar 2005 18:34:21 -0000
@@ -1285,6 +1285,7 @@
 
 
 unsigned char slc_reply[128];
+unsigned char const * const slc_reply_eom = &slc_reply[sizeof(slc_reply)];
 unsigned char *slc_replyp;
 
 void
@@ -1300,6 +1301,14 @@
 void
 slc_add_reply(unsigned char func, unsigned char flags, cc_t value)
 {
+	/* A sequence of up to 6 bytes my be written for this member of the SLC
+	 * suboption list by this function.  The end of negotiation command,
+	 * which is written by slc_end_reply(), will require 2 additional
+	 * bytes.  Do not proceed unless there is sufficient space for these
+	 * items.
+	 */
+	if (&slc_replyp[6+2] > slc_reply_eom)
+		return;
 	if ((*slc_replyp++ = func) == IAC)
 		*slc_replyp++ = IAC;
 	if ((*slc_replyp++ = flags) == IAC)
@@ -1313,6 +1322,9 @@
 {
     int len;
 
+    /* The end of negotiation command requires 2 bytes. */
+    if (&slc_replyp[2] > slc_reply_eom)
+            return;
     *slc_replyp++ = IAC;
     *slc_replyp++ = SE;
     len = slc_replyp - slc_reply;
@@ -1406,8 +1418,8 @@
 	}
 }
 
-#define	OPT_REPLY_SIZE	256
-unsigned char *opt_reply;
+#define	OPT_REPLY_SIZE	(2 * SUBBUFSIZE)
+unsigned char *opt_reply = NULL;
 unsigned char *opt_replyp;
 unsigned char *opt_replyend;
 
@@ -1460,9 +1472,9 @@
 		return;
 	}
 	vp = env_getvalue(ep);
-	if (opt_replyp + (vp ? strlen((char *)vp) : 0) +
-				strlen((char *)ep) + 6 > opt_replyend)
-	{
+        if (opt_replyp + (vp ? 2 * strlen((char *)vp) : 0) +
+                                2 * strlen((char *)ep) + 6 > opt_replyend)
+        {
 		int len;
 		opt_replyend += OPT_REPLY_SIZE;
 		len = opt_replyend - opt_reply;
@@ -1486,6 +1498,8 @@
 		*opt_replyp++ = ENV_USERVAR;
 	for (;;) {
 		while ((c = *ep++)) {
+			if (opt_replyp + (2 + 2) > opt_replyend)
+				return;
 			switch(c&0xff) {
 			case IAC:
 				*opt_replyp++ = IAC;
@@ -1500,6 +1514,8 @@
 			*opt_replyp++ = c;
 		}
 		if ((ep = vp)) {
+			if (opt_replyp + (1 + 2 + 2) > opt_replyend)
+				return;
 #ifdef	OLD_ENVIRON
 			if (telopt_environ == TELOPT_OLD_ENVIRON)
 				*opt_replyp++ = old_env_value;
@@ -1530,7 +1546,9 @@
 {
 	int len;
 
-	len = opt_replyp - opt_reply + 2;
+	if (opt_replyp + 2 > opt_replyend)
+		return;
+	len = opt_replyp + 2 - opt_reply;
 	if (emptyok || len > 6) {
 		*opt_replyp++ = IAC;
 		*opt_replyp++ = SE;
