]> granicus.if.org Git - procps-ng/commitdiff
top: Protect scat() from buffer overflows. ___REVERTED
authorJim Warner <james.warner@comcast.net>
Fri, 18 May 2018 05:00:00 +0000 (00:00 -0500)
committerCraig Small <csmall@enc.com.au>
Sat, 19 May 2018 11:42:36 +0000 (21:42 +1000)
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 9c745975b2ea306399ab2484af8ed2f37d472269

Signed-off-by: Jim Warner <james.warner@comcast.net>
top/top.c

index 47f4bdcb8948c5125abb5fd03a5c6bd154a5f613..308378dbff91c1cb44984af957fcc18af8e54323 100644 (file)
--- a/top/top.c
+++ b/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
 \f
@@ -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