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>
This commit is contained in:
parent
654f669c9a
commit
14aab889f4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=144231
@ -1326,6 +1326,7 @@ slc_check(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
@ -1341,6 +1342,14 @@ slc_start_reply(void)
|
|||||||
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)
|
||||||
@ -1354,6 +1363,9 @@ slc_end_reply(void)
|
|||||||
{
|
{
|
||||||
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;
|
||||||
@ -1471,8 +1483,8 @@ 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 = NULL;
|
||||||
unsigned char *opt_replyp;
|
unsigned char *opt_replyp;
|
||||||
unsigned char *opt_replyend;
|
unsigned char *opt_replyend;
|
||||||
|
|
||||||
@ -1525,9 +1537,9 @@ 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;
|
||||||
opt_replyend += OPT_REPLY_SIZE;
|
opt_replyend += OPT_REPLY_SIZE;
|
||||||
len = opt_replyend - opt_reply;
|
len = opt_replyend - opt_reply;
|
||||||
@ -1551,6 +1563,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;
|
||||||
@ -1565,6 +1579,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;
|
||||||
@ -1595,7 +1611,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;
|
||||||
|
Loading…
Reference in New Issue
Block a user