diff options
author | Jacques Vidrine <nectar@FreeBSD.org> | 2005-03-28 15:50:17 +0000 |
---|---|---|
committer | Jacques Vidrine <nectar@FreeBSD.org> | 2005-03-28 15:50:17 +0000 |
commit | 3ba520e893870c055bb37da41f3269634703eaab (patch) | |
tree | 9a271712241f2ecd52170b77d6d470ad1dc9f440 | |
parent | 59ca7ea8d6881e2e82a49403eb92e061ec83149c (diff) |
MFC src/contrib/telnet/telnet.c 1.16: Correct buffer overflows in
telnet(1).
Security: CAN-2005-0468, CAN-2005-0469
Approved by: security-officer
Notes
Notes:
svn path=/releng/5.3/; revision=144234
-rw-r--r-- | UPDATING | 3 | ||||
-rw-r--r-- | contrib/telnet/telnet/telnet.c | 30 | ||||
-rw-r--r-- | sys/conf/newvers.sh | 2 |
3 files changed, 28 insertions, 7 deletions
@@ -8,6 +8,9 @@ Items affecting the ports and packages system can be found in /usr/ports/UPDATING. Please read that file before running portupgrade. Important recent entries: 20040724 (default X changes). +20050328: p6 FreeBSD-SA-05:01.telnet + Correct buffer overflows in telnet(1). + 20050114: p5 FreeBSD-EN-05:03.ipi Avoid more than two pending IPI interrupt vectors per local APIC as this may cause deadlocks. diff --git a/contrib/telnet/telnet/telnet.c b/contrib/telnet/telnet/telnet.c index 82ee4649b703..0ce1abceb836 100644 --- a/contrib/telnet/telnet/telnet.c +++ b/contrib/telnet/telnet/telnet.c @@ -1318,6 +1318,7 @@ slc_check(void) } 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 @@ slc_start_reply(void) 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 @@ slc_end_reply(void) { 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 @@ env_opt(unsigned char *buf, int len) } } -#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 @@ env_opt_add(unsigned char *ep) 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 @@ env_opt_add(unsigned char *ep) *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 @@ env_opt_add(unsigned char *ep) *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 @@ env_opt_end(int emptyok) { 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; diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index de452be60fb0..eba0beb3bbc8 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="5.3" -BRANCH="RELEASE-p5" +BRANCH="RELEASE-p6" RELEASE="${REVISION}-${BRANCH}" VERSION="${TYPE} ${RELEASE}" |