From FreeBSD:

Correct a pair of buffer overflows in the telnet(1) command:

   (CAN-2005-0468) A heap buffer overflow in env_opt_add() and related
   functions.

   (CAN-2005-0469) A global uninitialized data section buffer overflow in
   slc_add_reply() and related functions.

  As a result of these vulnerabilities, it may be possible for a malicious
  telnet server or active network attacker to cause telnet(1) to execute
  arbitrary code with the privileges of the user running it.

  Security: CAN-2005-0468, CAN-2005-0469
  Security: FreeBSD-SA-05:01.telnet
  Security: http://www.idefense.com/application/poi/display?id=220&type=vulnerabilities
  Security: http://www.idefense.com/application/poi/display?id=221&type=vulnerabilities

  These fixes are based in part on patches
  Submitted by:   Solar Designer <solar@openwall.com>


git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@14693 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2005-03-28 22:43:34 +00:00
parent f0683a224b
commit 02805ed17d

View File

@@ -1294,6 +1294,7 @@ slc_check()
unsigned char slc_reply[128]; unsigned char slc_reply[128];
unsigned char const * const slc_reply_eom = &slc_reply[sizeof(slc_reply)];
unsigned char *slc_replyp; unsigned char *slc_replyp;
void void
@@ -1309,6 +1310,14 @@ slc_start_reply()
void void
slc_add_reply(unsigned char func, unsigned char flags, cc_t value) 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) if ((*slc_replyp++ = func) == IAC)
*slc_replyp++ = IAC; *slc_replyp++ = IAC;
if ((*slc_replyp++ = flags) == IAC) if ((*slc_replyp++ = flags) == IAC)
@@ -1322,6 +1331,9 @@ slc_end_reply()
{ {
int len; int len;
/* The end of negotiation command requires 2 bytes. */
if (&slc_replyp[2] > slc_reply_eom)
return;
*slc_replyp++ = IAC; *slc_replyp++ = IAC;
*slc_replyp++ = SE; *slc_replyp++ = SE;
len = slc_replyp - slc_reply; len = slc_replyp - slc_reply;
@@ -1415,7 +1427,7 @@ env_opt(unsigned char *buf, int len)
} }
} }
#define OPT_REPLY_SIZE 256 #define OPT_REPLY_SIZE (2 * SUBBUFSIZE)
unsigned char *opt_reply; unsigned char *opt_reply;
unsigned char *opt_replyp; unsigned char *opt_replyp;
unsigned char *opt_replyend; unsigned char *opt_replyend;
@@ -1475,8 +1487,8 @@ env_opt_add(unsigned char *ep)
return; return;
} }
vp = env_getvalue(ep); vp = env_getvalue(ep);
if (opt_replyp + (vp ? strlen((char *)vp) : 0) + if (opt_replyp + (vp ? 2 * strlen((char *)vp) : 0) +
strlen((char *)ep) + 6 > opt_replyend) 2 * strlen((char *)ep) + 6 > opt_replyend)
{ {
int len; int len;
void *tmp; void *tmp;
@@ -1503,6 +1515,8 @@ env_opt_add(unsigned char *ep)
*opt_replyp++ = ENV_USERVAR; *opt_replyp++ = ENV_USERVAR;
for (;;) { for (;;) {
while ((c = *ep++)) { while ((c = *ep++)) {
if (opt_replyp + (2 + 2) > opt_replyend)
return;
switch(c&0xff) { switch(c&0xff) {
case IAC: case IAC:
*opt_replyp++ = IAC; *opt_replyp++ = IAC;
@@ -1517,6 +1531,8 @@ env_opt_add(unsigned char *ep)
*opt_replyp++ = c; *opt_replyp++ = c;
} }
if ((ep = vp)) { if ((ep = vp)) {
if (opt_replyp + (1 + 2 + 2) > opt_replyend)
return;
#ifdef OLD_ENVIRON #ifdef OLD_ENVIRON
if (telopt_environ == TELOPT_OLD_ENVIRON) if (telopt_environ == TELOPT_OLD_ENVIRON)
*opt_replyp++ = old_env_value; *opt_replyp++ = old_env_value;
@@ -1547,7 +1563,9 @@ env_opt_end(int emptyok)
{ {
int len; 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) { if (emptyok || len > 6) {
*opt_replyp++ = IAC; *opt_replyp++ = IAC;
*opt_replyp++ = SE; *opt_replyp++ = SE;