top: address 'show_special()' o-o-b read/write concern
This patch addresses a potential (but unlikely) buffer
overflow by reducing, if necessary, a memcpy length by
3 bytes to provide for an eol '\0' and 2 unused buffer
positions which also might receive the '\0' character.
[ note to future analysis tool: just because you see ]
[ binary data being manipulated in the routine, that ]
[ doesn't mean such function was passed binary data! ]
Reference(s):
. original qualys patch
0116-top-Fix-out-of-bounds-read-write-in-show_special.patch
commit ed8f6d9cc6
Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
2fb269a5b0
commit
d34c6eb5b4
19
top/top.c
19
top/top.c
@ -928,7 +928,7 @@ static void show_special (int interact, const char *glob) {
|
|||||||
/* note: the following is for documentation only,
|
/* note: the following is for documentation only,
|
||||||
the real captab is now found in a group's WIN_t !
|
the real captab is now found in a group's WIN_t !
|
||||||
+------------------------------------------------------+
|
+------------------------------------------------------+
|
||||||
| char *captab[] = { : Cap's/Delim's |
|
| char *captab[] = { : Cap's = Index |
|
||||||
| Cap_norm, Cap_norm, = \000, \001, |
|
| Cap_norm, Cap_norm, = \000, \001, |
|
||||||
| cap_bold, capclr_sum, = \002, \003, |
|
| cap_bold, capclr_sum, = \002, \003, |
|
||||||
| capclr_msg, capclr_pmt, = \004, \005, |
|
| capclr_msg, capclr_pmt, = \004, \005, |
|
||||||
@ -938,9 +938,16 @@ static void show_special (int interact, const char *glob) {
|
|||||||
+------------------------------------------------------+ */
|
+------------------------------------------------------+ */
|
||||||
/* ( Pssst, after adding the termcap transitions, row may )
|
/* ( Pssst, after adding the termcap transitions, row may )
|
||||||
( exceed 300+ bytes, even in an 80x24 terminal window! )
|
( exceed 300+ bytes, even in an 80x24 terminal window! )
|
||||||
( And if we're no longer guaranteed lines created only )
|
( Shown here are the former buffer size specifications )
|
||||||
( by top, we'll need larger buffs plus some protection )
|
( char tmp[SMLBUFSIZ], lin[MEDBUFSIZ], row[LRGBUFSIZ]. )
|
||||||
( against overrunning them with this 'lin_end - glob'. ) */
|
( So now we use larger buffers and a little protection )
|
||||||
|
( against overrunning them with this 'lin_end - glob'. )
|
||||||
|
|
||||||
|
( That was uncovered during 'Inspect' development when )
|
||||||
|
( this guy was being considered for a supporting role. )
|
||||||
|
( However, such an approach was abandoned. As a result )
|
||||||
|
( this function is called only with a glob under top's )
|
||||||
|
( control and never containing any 'raw/binary' chars! ) */
|
||||||
char tmp[LRGBUFSIZ], lin[LRGBUFSIZ], row[ROWMAXSIZ];
|
char tmp[LRGBUFSIZ], lin[LRGBUFSIZ], row[ROWMAXSIZ];
|
||||||
char *rp, *lin_end, *sub_beg, *sub_end;
|
char *rp, *lin_end, *sub_beg, *sub_end;
|
||||||
int room;
|
int room;
|
||||||
@ -948,7 +955,7 @@ static void show_special (int interact, const char *glob) {
|
|||||||
// handle multiple lines passed in a bunch
|
// handle multiple lines passed in a bunch
|
||||||
while ((lin_end = strchr(glob, '\n'))) {
|
while ((lin_end = strchr(glob, '\n'))) {
|
||||||
#define myMIN(a,b) (((a) < (b)) ? (a) : (b))
|
#define myMIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
size_t lessor = myMIN((size_t)(lin_end - glob), sizeof(lin) -1);
|
size_t lessor = myMIN((size_t)(lin_end - glob), sizeof(lin) -3);
|
||||||
|
|
||||||
// create a local copy we can extend and otherwise abuse
|
// create a local copy we can extend and otherwise abuse
|
||||||
memcpy(lin, glob, lessor);
|
memcpy(lin, glob, lessor);
|
||||||
@ -963,6 +970,8 @@ static void show_special (int interact, const char *glob) {
|
|||||||
if ('~' == ch) ch = *(sub_end + 1) - '0';
|
if ('~' == ch) ch = *(sub_end + 1) - '0';
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 0: // no end delim, captab makes normal
|
case 0: // no end delim, captab makes normal
|
||||||
|
// only possible when '\n' was NOT preceeded with a '~#' sequence
|
||||||
|
// ( '~1' thru '~8' is valid range, '~0' is never actually used )
|
||||||
*(sub_end + 1) = '\0'; // extend str end, then fall through
|
*(sub_end + 1) = '\0'; // extend str end, then fall through
|
||||||
*(sub_end + 2) = '\0'; // ( +1 optimization for usual path )
|
*(sub_end + 2) = '\0'; // ( +1 optimization for usual path )
|
||||||
case 1: case 2: case 3: case 4:
|
case 1: case 2: case 3: case 4:
|
||||||
|
Loading…
Reference in New Issue
Block a user