Patch attached, based on FreeBSD one.

Bye,
Gerardo
--- heimdal-0.6.3/appl/telnet/telnet/telnet.c.orig      2002-05-03 
12:19:43.000000000 +0200
+++ heimdal-0.6.3/appl/telnet/telnet/telnet.c   2005-04-21 01:07:40.854403312 
+0200
@@ -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;

Reply via email to