More work on CVE-2019-0053.

Telnet protocol messages must remain sane at all costs, instead of
being truncated because indata was oversized.  Some additional cases
of insufficient buffer declaration are corrected.
This commit is contained in:
Mats Erik Andersson
2020-01-29 21:07:10 +01:00
parent 45f0ab0a8f
commit 07fdb4201a
5 changed files with 55 additions and 15 deletions

View File

@@ -1,3 +1,22 @@
2020-01-29 Mats Erik Andersson <gnu@gisladisker.se>
More work on CVE-2019-0053.
Telnet protocol messages must not be corrupted when buffer
overflows are detected, but should be reported as errors.
* telnet/telnet.c (suboption): Check that prepared protocol
message in fact fits in intermediary buffer without truncation.
Tweak indentation for visibility of protocol elements in snprintf.
Allocate space also for final NUL-character.
* telnetd/telnetd.c (telnetdrun): Increase DATA string size by one.
* telnetd/termstat.c (localstat, flowstat, clientstat): Likewise.
Insufficiently declared length of string variable.
* telnetd/utility.c (printsub): Declare TBUF with maximal extent.
2020-01-28 Mats Erik Andersson <gnu@gisladisker.se>
Better test coverage, mostly IPv6.

View File

@@ -859,10 +859,13 @@ suboption (void)
#endif /* defined(TN3270) */
name = gettermname ();
len = strlen (name) + 4 + 2;
if (len < NETROOM ())
if ((len < NETROOM ()) && (len <= sizeof (temp)))
{
snprintf ((char *) temp, sizeof (temp), "%c%c%c%c%s%c%c", IAC, SB, TELOPT_TTYPE,
TELQUAL_IS, name, IAC, SE);
snprintf ((char *) temp, sizeof (temp), "%c%c%c%c%s%c%c",
IAC, SB, TELOPT_TTYPE, TELQUAL_IS,
name,
IAC, SE);
ring_supply_data (&netoring, temp, len);
printsub ('>', &temp[2], len - 2);
}
@@ -880,13 +883,15 @@ suboption (void)
if (SB_GET () == TELQUAL_SEND)
{
long ospeed, ispeed;
unsigned char temp[50];
unsigned char temp[50]; /* Two six-digit integers plus 7. */
int len;
TerminalSpeeds (&ispeed, &ospeed);
snprintf ((char *) temp, sizeof (temp), "%c%c%c%c%d,%d%c%c", IAC, SB, TELOPT_TSPEED,
TELQUAL_IS, (int) ospeed, (int) ispeed, IAC, SE);
snprintf ((char *) temp, sizeof (temp), "%c%c%c%c%d,%d%c%c",
IAC, SB, TELOPT_TSPEED, TELQUAL_IS,
(int) ospeed, (int) ispeed,
IAC, SE);
len = strlen ((char *) temp + 4) + 4; /* temp[3] is 0 ... */
if (len < NETROOM ())
@@ -999,8 +1004,23 @@ suboption (void)
send_wont (TELOPT_XDISPLOC, 1);
break;
}
snprintf ((char *) temp, sizeof (temp), "%c%c%c%c%s%c%c", IAC, SB, TELOPT_XDISPLOC,
TELQUAL_IS, dp, IAC, SE);
/* Remote host, and display server must not be corrupted
* by truncation. In addition, every character of telnet
* protocol must remain unsevered. Check that DP fits in
* full within TEMP. Otherwise report buffer error.
*/
if (strlen (dp) > sizeof (temp) - 4 - 2)
{
printf ("lm_will: not enough room in buffer\n");
break;
}
/* Go ahead safely. */
snprintf ((char *) temp, sizeof (temp), "%c%c%c%c%s%c%c",
IAC, SB, TELOPT_XDISPLOC, TELQUAL_IS,
dp,
IAC, SE);
len = strlen ((char *) temp + 4) + 4; /* temp[3] is 0 ... */
if (len < NETROOM ())

View File

@@ -704,7 +704,7 @@ telnetd_run (void)
int newflow = (c & TIOCPKT_DOSTOP) ? 1 : 0;
if (newflow != flowmode)
{
char data[6];
char data[7];
sprintf (data, "%c%c%c%c%c%c",
IAC, SB, TELOPT_LFLOW,

View File

@@ -304,7 +304,7 @@ localstat (void)
}
else if (lmodetype == REAL_LINEMODE)
{
char data[7];
char data[8];
send_do (TELOPT_LINEMODE, 1);
/* send along edit modes */
@@ -339,7 +339,7 @@ localstat (void)
/*
* Send along appropriate edit mode mask.
*/
char data[7];
char data[8];
sprintf (data, "%c%c%c%c%c%c%c",
IAC, SB, TELOPT_LINEMODE,
@@ -391,7 +391,7 @@ flowstat (void)
{
if (his_state_is_will (TELOPT_LFLOW))
{
char data[6];
char data[7];
if (tty_flowmode () != flowmode)
{
@@ -476,7 +476,7 @@ clientstat (register int code, register int parm1, register int parm2)
if (lmodetype == REAL_LINEMODE && uselinemode)
if (uselinemode)
{
char data[7];
char data[8];
useeditmode = 0;
if (tty_isediting ())
@@ -553,7 +553,7 @@ clientstat (register int code, register int parm1, register int parm2)
if (!ack)
{
char data[7];
char data[8];
sprintf (data, "%c%c%c%c%c%c%c",
IAC, SB, TELOPT_LINEMODE,

View File

@@ -1225,7 +1225,8 @@ printsub (int direction, unsigned char *pointer, int length)
break;
}
{
char tbuf[32];
char tbuf[sizeof ("|EDIT|TRAPSIG|SOFT_TAB|LIT_ECHO|ACK")];
snprintf (tbuf, sizeof (tbuf), "%s%s%s%s%s",
pointer[2] & MODE_EDIT ? "|EDIT" : "",
pointer[2] & MODE_TRAPSIG ? "|TRAPSIG" : "",