fix MITKRB5-SA-2005-001 telnet client vuln
authorTom Yu <tlyu@mit.edu>
Tue, 29 Mar 2005 21:21:14 +0000 (21:21 +0000)
committerTom Yu <tlyu@mit.edu>
Tue, 29 Mar 2005 21:21:14 +0000 (21:21 +0000)
* telnet.c (slc_add_reply, slc_end_reply): Fix buffer overflow
vulnerability by checking lengths.
(env_opt_add): Ensure buffer allocation is sufficiently large,
accounting for expansion during IAC quoting.

ticket: new
tags: pullup
version_reported: 1.4
target_version: 1.4.1
component: telnet

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@17162 dc483132-0cff-0310-8789-dd5450dbe970

src/appl/telnet/telnet/ChangeLog
src/appl/telnet/telnet/telnet.c

index 91d52591a0788fefbae13ceb22d62342271debae..e223a7750a413ed8a88ebc1e6af28bf28338c900 100644 (file)
@@ -1,3 +1,10 @@
+2005-03-28  Tom Yu  <tlyu@mit.edu>
+
+       * telnet.c (slc_add_reply, slc_end_reply): Fix buffer overflow
+       vulnerability by checking lengths.
+       (env_opt_add): Ensure buffer allocation is sufficiently large,
+       accounting for expansion during IAC quoting.
+
 2004-03-04  Ken Raeburn  <raeburn@mit.edu>
 
        * configure.in: Deleted; configure this dir from parent now.
index a92bbd5d13b1d9857699bed5428160f91d00dd43..6215fc1e9bd26dce1c4a4952af656024050d2351 100644 (file)
@@ -1475,6 +1475,8 @@ slc_add_reply(func, flags, value)
        unsigned char flags;
        cc_t value;
 {
+       if ((slc_replyp - slc_reply) + 6 > sizeof(slc_reply))
+               return;
        if ((*slc_replyp++ = func) == IAC)
                *slc_replyp++ = IAC;
        if ((*slc_replyp++ = flags) == IAC)
@@ -1488,11 +1490,12 @@ slc_end_reply()
 {
     register int len;
 
-    *slc_replyp++ = IAC;
-    *slc_replyp++ = SE;
     len = slc_replyp - slc_reply;
-    if (len <= 6)
+    if (len <= 4 || (len + 2 > sizeof(slc_reply)))
        return;
+    *slc_replyp++ = IAC;
+    *slc_replyp++ = SE;
+    len += 2;
     if (NETROOM() > len) {
        ring_supply_data(&netoring, slc_reply, slc_replyp - slc_reply);
        printsub('>', &slc_reply[2], slc_replyp - slc_reply - 2);
@@ -1645,6 +1648,7 @@ env_opt_add(ep)
        register unsigned char *ep;
 {
        register unsigned char *vp, c;
+       unsigned int len, olen, elen;
 
        if (opt_reply == NULL)          /*XXX*/
                return;                 /*XXX*/
@@ -1662,19 +1666,19 @@ env_opt_add(ep)
                return;
        }
        vp = env_getvalue(ep);
-       if (opt_replyp + (vp ? strlen((char *)vp) : 0) +
-                               strlen((char *)ep) + 6 > opt_replyend)
+       elen = 2 * (vp ? strlen((char *)vp) : 0) +
+               2 * strlen((char *)ep) + 6;
+       if ((opt_replyend - opt_replyp) < elen)
        {
-               register unsigned int len;
-               opt_replyend += OPT_REPLY_SIZE;
-               len = opt_replyend - opt_reply;
+               len = opt_replyend - opt_reply + elen;
+               olen = opt_replyp - opt_reply;
                opt_reply = (unsigned char *)realloc(opt_reply, len);
                if (opt_reply == NULL) {
 /*@*/                  printf("env_opt_add: realloc() failed!!!\n");
                        opt_reply = opt_replyp = opt_replyend = NULL;
                        return;
                }
-               opt_replyp = opt_reply + len - (opt_replyend - opt_replyp);
+               opt_replyp = opt_reply + olen;
                opt_replyend = opt_reply + len;
        }
        if (opt_welldefined((char *) ep))