top: Protect scat() from buffer overflows. ___REVERTED

The whole idea was to make top's 'scat' function small
and very quick, unlike that standard 'strcat' routine.

To achieve that end we ignore the potential for buffer
overruns and trust callers to provide adequate dest's.

Reference(s):
. original qualys patch
0109-top-Protect-scat-from-buffer-overflows.patch
commit 9c745975b2

Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
Jim Warner 2018-05-18 00:00:00 -05:00 committed by Craig Small
parent 59f39da852
commit c502678715

View File

@ -344,17 +344,9 @@ static const char *fmtmk (const char *fmts, ...) {
/* /*
* This guy is just our way of avoiding the overhead of the standard * This guy is just our way of avoiding the overhead of the standard
* strcat function (should the caller choose to participate) */ * strcat function (should the caller choose to participate) */
static inline char *scat (char *dst, const char *src, char *buf, size_t size) { static inline char *scat (char *dst, const char *src) {
char *end = buf + size; while (*dst) dst++;
if (size <= 0) return buf; while ((*(dst++) = *(src++)));
if (dst < buf) return buf;
while (dst < end && *dst) dst++;
while (dst < end && (*(dst++) = *(src++)));
if (dst >= end) {
*--end = '\0';
return end;
}
return --dst; return --dst;
} // end: scat } // end: scat
@ -661,7 +653,7 @@ static void xalloc_our_handler (const char *fmts, ...) {
va_start(va, fmts); va_start(va, fmts);
vsnprintf(buf, sizeof(buf), fmts, va); vsnprintf(buf, sizeof(buf), fmts, va);
va_end(va); va_end(va);
scat(buf, "\n", buf, sizeof(buf)); scat(buf, "\n");
bye_bye(buf); bye_bye(buf);
} // end: xalloc_our_handler } // end: xalloc_our_handler
@ -976,7 +968,7 @@ static void show_special (int interact, const char *glob) {
*sub_end = '\0'; *sub_end = '\0';
snprintf(tmp, sizeof(tmp), "%s%.*s%s" snprintf(tmp, sizeof(tmp), "%s%.*s%s"
, Curwin->captab[ch], utf8_embody(sub_beg, room), sub_beg, Caps_off); , Curwin->captab[ch], utf8_embody(sub_beg, room), sub_beg, Caps_off);
rp = scat(rp, tmp, row, sizeof(row)); rp = scat(rp, tmp);
room -= (sub_end - sub_beg); room -= (sub_end - sub_beg);
room += utf8_delta(sub_beg); room += utf8_delta(sub_beg);
if (!ch) goto done_substrings; if (!ch) goto done_substrings;
@ -2056,12 +2048,12 @@ static void build_headers (void) {
do { do {
if (VIZISw(w)) { if (VIZISw(w)) {
memset((s = w->columnhdr), 0, sizeof(w->columnhdr)); memset((s = w->columnhdr), 0, sizeof(w->columnhdr));
if (Rc.mode_altscr) s = scat(s, fmtmk("%d", w->winnum), w->columnhdr, sizeof(w->columnhdr)); if (Rc.mode_altscr) s = scat(s, fmtmk("%d", w->winnum));
for (i = 0; i < w->maxpflgs; i++) { for (i = 0; i < w->maxpflgs; i++) {
f = w->procflgs[i]; f = w->procflgs[i];
#ifdef USE_X_COLHDR #ifdef USE_X_COLHDR
if (CHKw(w, Show_HICOLS) && f == w->rc.sortindx) { if (CHKw(w, Show_HICOLS) && f == w->rc.sortindx) {
s = scat(s, fmtmk("%s%s", Caps_off, w->capclr_msg), w->columnhdr, sizeof(w->columnhdr)); s = scat(s, fmtmk("%s%s", Caps_off, w->capclr_msg));
w->hdrcaplen += strlen(Caps_off) + strlen(w->capclr_msg); w->hdrcaplen += strlen(Caps_off) + strlen(w->capclr_msg);
} }
#else #else
@ -2071,10 +2063,10 @@ static void build_headers (void) {
Frames_libflags |= Fieldstab[f].lflg; Frames_libflags |= Fieldstab[f].lflg;
s = scat(s, utf8_justify(N_col(f) s = scat(s, utf8_justify(N_col(f)
, VARcol(f) ? w->varcolsz : Fieldstab[f].width , VARcol(f) ? w->varcolsz : Fieldstab[f].width
, CHKw(w, Fieldstab[f].align)), w->columnhdr, sizeof(w->columnhdr)); , CHKw(w, Fieldstab[f].align)));
#ifdef USE_X_COLHDR #ifdef USE_X_COLHDR
if (CHKw(w, Show_HICOLS) && f == w->rc.sortindx) { if (CHKw(w, Show_HICOLS) && f == w->rc.sortindx) {
s = scat(s, fmtmk("%s%s", Caps_off, w->capclr_hdr), w->columnhdr, sizeof(w->columnhdr)); s = scat(s, fmtmk("%s%s", Caps_off, w->capclr_hdr));
w->hdrcaplen += strlen(Caps_off) + strlen(w->capclr_hdr); w->hdrcaplen += strlen(Caps_off) + strlen(w->capclr_hdr);
} }
#endif #endif
@ -2159,7 +2151,7 @@ static void calibrate_fields (void) {
while accounting for a possible leading window number */ while accounting for a possible leading window number */
w->varcolsz = varcolcnt = 0; w->varcolsz = varcolcnt = 0;
*(s = w->columnhdr) = '\0'; *(s = w->columnhdr) = '\0';
if (Rc.mode_altscr) s = scat(s, " ", w->columnhdr, sizeof(w->columnhdr)); if (Rc.mode_altscr) s = scat(s, " ");
for (i = 0; i + w->begpflg < w->totpflgs; i++) { for (i = 0; i + w->begpflg < w->totpflgs; i++) {
f = w->pflgsall[i + w->begpflg]; f = w->pflgsall[i + w->begpflg];
w->procflgs[i] = f; w->procflgs[i] = f;
@ -2171,7 +2163,7 @@ static void calibrate_fields (void) {
// oops, won't fit -- we're outta here... // oops, won't fit -- we're outta here...
if (Screen_cols < ((int)(s - w->columnhdr) + len)) break; if (Screen_cols < ((int)(s - w->columnhdr) + len)) break;
if (VARcol(f)) { ++varcolcnt; w->varcolsz += strlen(h); } if (VARcol(f)) { ++varcolcnt; w->varcolsz += strlen(h); }
s = scat(s, fmtmk("%*.*s", len, len, h), w->columnhdr, sizeof(w->columnhdr)); s = scat(s, fmtmk("%*.*s", len, len, h));
} }
#ifndef USE_X_COLHDR #ifndef USE_X_COLHDR
if (i >= 1 && EU_XON == w->procflgs[i - 1]) --i; if (i >= 1 && EU_XON == w->procflgs[i - 1]) --i;
@ -2187,7 +2179,7 @@ static void calibrate_fields (void) {
/* establish the field where all remaining fields would still /* establish the field where all remaining fields would still
fit within screen width, including a leading window number */ fit within screen width, including a leading window number */
*(s = w->columnhdr) = '\0'; *(s = w->columnhdr) = '\0';
if (Rc.mode_altscr) s = scat(s, " ", w->columnhdr, sizeof(w->columnhdr)); if (Rc.mode_altscr) s = scat(s, " ");
w->endpflg = 0; w->endpflg = 0;
for (i = w->totpflgs - 1; -1 < i; i--) { for (i = w->totpflgs - 1; -1 < i; i--) {
f = w->pflgsall[i]; f = w->pflgsall[i];
@ -2197,7 +2189,7 @@ static void calibrate_fields (void) {
h = N_col(f); h = N_col(f);
len = (VARcol(f) ? (int)strlen(h) : Fieldstab[f].width) + COLPADSIZ; len = (VARcol(f) ? (int)strlen(h) : Fieldstab[f].width) + COLPADSIZ;
if (Screen_cols < ((int)(s - w->columnhdr) + len)) break; if (Screen_cols < ((int)(s - w->columnhdr) + len)) break;
s = scat(s, fmtmk("%*.*s", len, len, h), w->columnhdr, sizeof(w->columnhdr)); s = scat(s, fmtmk("%*.*s", len, len, h));
w->endpflg = i; w->endpflg = i;
} }
#ifndef USE_X_COLHDR #ifndef USE_X_COLHDR
@ -3469,7 +3461,7 @@ static void inspection_utility (int pid) {
Inspect.tab[sel].caps = "~4"; dst[0] = '\0'; \ Inspect.tab[sel].caps = "~4"; dst[0] = '\0'; \
for (i = 0; i < Inspect.total; i++) { char _s[SMLBUFSIZ]; \ for (i = 0; i < Inspect.total; i++) { char _s[SMLBUFSIZ]; \
snprintf(_s, sizeof(_s), " %s %s", Inspect.tab[i].name, Inspect.tab[i].caps); \ snprintf(_s, sizeof(_s), " %s %s", Inspect.tab[i].name, Inspect.tab[i].caps); \
scat(dst, _s, dst, sizeof(dst)); } } strcat(dst, _s); } }
char sels[MEDBUFSIZ]; char sels[MEDBUFSIZ];
static int sel; static int sel;
int i, key; int i, key;
@ -3759,13 +3751,13 @@ error Hey, fix the above fscanf 'PFLAGSSIZ' dependency !
case 'f': // 3.3.0 thru 3.3.3 (ng) case 'f': // 3.3.0 thru 3.3.3 (ng)
SETw(w, Show_JRNUMS); SETw(w, Show_JRNUMS);
case 'g': // from 3.3.4 thru 3.3.8 case 'g': // from 3.3.4 thru 3.3.8
scat(w->rc.fieldscur, RCF_PLUS_H, w->rc.fieldscur, sizeof(w->rc.fieldscur)); scat(w->rc.fieldscur, RCF_PLUS_H);
case 'h': // this is release 3.3.9 case 'h': // this is release 3.3.9
w->rc.graph_cpus = w->rc.graph_mems = 0; w->rc.graph_cpus = w->rc.graph_mems = 0;
// these next 2 are really global, but best documented here // these next 2 are really global, but best documented here
Rc.summ_mscale = Rc.task_mscale = SK_Kb; Rc.summ_mscale = Rc.task_mscale = SK_Kb;
case 'i': // actual RCF_VERSION_ID case 'i': // actual RCF_VERSION_ID
scat(w->rc.fieldscur, RCF_PLUS_J, w->rc.fieldscur, sizeof(w->rc.fieldscur)); scat(w->rc.fieldscur, RCF_PLUS_J);
case 'j': // and the next version case 'j': // and the next version
default: default:
if (strlen(w->rc.fieldscur) != sizeof(DEF_FIELDS) - 1) if (strlen(w->rc.fieldscur) != sizeof(DEF_FIELDS) - 1)
@ -5697,7 +5689,7 @@ static const char *task_show (const WIN_t *q, const proc_t *p) {
// we must begin a row with a possible window number in mind... // we must begin a row with a possible window number in mind...
*(rp = rbuf) = '\0'; *(rp = rbuf) = '\0';
if (Rc.mode_altscr) rp = scat(rp, " ", rbuf, sizeof(rbuf)); if (Rc.mode_altscr) rp = scat(rp, " ");
for (x = 0; x < q->maxpflgs; x++) { for (x = 0; x < q->maxpflgs; x++) {
const char *cp = NULL; const char *cp = NULL;
@ -5907,7 +5899,7 @@ static const char *task_show (const WIN_t *q, const proc_t *p) {
if (cp) { if (cp) {
if (q->osel_tot && !osel_matched(q, i, cp)) return ""; if (q->osel_tot && !osel_matched(q, i, cp)) return "";
rp = scat(rp, cp, rbuf, sizeof(rbuf)); rp = scat(rp, cp);
} }
#undef S #undef S
#undef W #undef W