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:
parent
59f39da852
commit
c502678715
44
top/top.c
44
top/top.c
@ -344,17 +344,9 @@ static const char *fmtmk (const char *fmts, ...) {
|
||||
/*
|
||||
* This guy is just our way of avoiding the overhead of the standard
|
||||
* strcat function (should the caller choose to participate) */
|
||||
static inline char *scat (char *dst, const char *src, char *buf, size_t size) {
|
||||
char *end = buf + size;
|
||||
if (size <= 0) return buf;
|
||||
if (dst < buf) return buf;
|
||||
|
||||
while (dst < end && *dst) dst++;
|
||||
while (dst < end && (*(dst++) = *(src++)));
|
||||
if (dst >= end) {
|
||||
*--end = '\0';
|
||||
return end;
|
||||
}
|
||||
static inline char *scat (char *dst, const char *src) {
|
||||
while (*dst) dst++;
|
||||
while ((*(dst++) = *(src++)));
|
||||
return --dst;
|
||||
} // end: scat
|
||||
|
||||
@ -661,7 +653,7 @@ static void xalloc_our_handler (const char *fmts, ...) {
|
||||
va_start(va, fmts);
|
||||
vsnprintf(buf, sizeof(buf), fmts, va);
|
||||
va_end(va);
|
||||
scat(buf, "\n", buf, sizeof(buf));
|
||||
scat(buf, "\n");
|
||||
bye_bye(buf);
|
||||
} // end: xalloc_our_handler
|
||||
|
||||
@ -976,7 +968,7 @@ static void show_special (int interact, const char *glob) {
|
||||
*sub_end = '\0';
|
||||
snprintf(tmp, sizeof(tmp), "%s%.*s%s"
|
||||
, 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 += utf8_delta(sub_beg);
|
||||
if (!ch) goto done_substrings;
|
||||
@ -2056,12 +2048,12 @@ static void build_headers (void) {
|
||||
do {
|
||||
if (VIZISw(w)) {
|
||||
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++) {
|
||||
f = w->procflgs[i];
|
||||
#ifdef USE_X_COLHDR
|
||||
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);
|
||||
}
|
||||
#else
|
||||
@ -2071,10 +2063,10 @@ static void build_headers (void) {
|
||||
Frames_libflags |= Fieldstab[f].lflg;
|
||||
s = scat(s, utf8_justify(N_col(f)
|
||||
, 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
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
@ -2159,7 +2151,7 @@ static void calibrate_fields (void) {
|
||||
while accounting for a possible leading window number */
|
||||
w->varcolsz = varcolcnt = 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++) {
|
||||
f = w->pflgsall[i + w->begpflg];
|
||||
w->procflgs[i] = f;
|
||||
@ -2171,7 +2163,7 @@ static void calibrate_fields (void) {
|
||||
// oops, won't fit -- we're outta here...
|
||||
if (Screen_cols < ((int)(s - w->columnhdr) + len)) break;
|
||||
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
|
||||
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
|
||||
fit within screen width, including a leading window number */
|
||||
*(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;
|
||||
for (i = w->totpflgs - 1; -1 < i; i--) {
|
||||
f = w->pflgsall[i];
|
||||
@ -2197,7 +2189,7 @@ static void calibrate_fields (void) {
|
||||
h = N_col(f);
|
||||
len = (VARcol(f) ? (int)strlen(h) : Fieldstab[f].width) + COLPADSIZ;
|
||||
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;
|
||||
}
|
||||
#ifndef USE_X_COLHDR
|
||||
@ -3469,7 +3461,7 @@ static void inspection_utility (int pid) {
|
||||
Inspect.tab[sel].caps = "~4"; dst[0] = '\0'; \
|
||||
for (i = 0; i < Inspect.total; i++) { char _s[SMLBUFSIZ]; \
|
||||
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];
|
||||
static int sel;
|
||||
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)
|
||||
SETw(w, Show_JRNUMS);
|
||||
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
|
||||
w->rc.graph_cpus = w->rc.graph_mems = 0;
|
||||
// these next 2 are really global, but best documented here
|
||||
Rc.summ_mscale = Rc.task_mscale = SK_Kb;
|
||||
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
|
||||
default:
|
||||
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...
|
||||
*(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++) {
|
||||
const char *cp = NULL;
|
||||
@ -5907,7 +5899,7 @@ static const char *task_show (const WIN_t *q, const proc_t *p) {
|
||||
|
||||
if (cp) {
|
||||
if (q->osel_tot && !osel_matched(q, i, cp)) return "";
|
||||
rp = scat(rp, cp, rbuf, sizeof(rbuf));
|
||||
rp = scat(rp, cp);
|
||||
}
|
||||
#undef S
|
||||
#undef W
|
||||
|
Loading…
Reference in New Issue
Block a user