]> granicus.if.org Git - procps-ng/commitdiff
ps/output.c: Protect outbuf in various pr_*() functions.
authorQualys Security Advisory <qsa@qualys.com>
Thu, 1 Jan 1970 00:00:00 +0000 (00:00 +0000)
committerCraig Small <csmall@enc.com.au>
Fri, 18 May 2018 21:32:21 +0000 (07:32 +1000)
pr_bsdstart(): Replace "strcpy(outbuf," with "snprintf(outbuf, COLWID,"
(which is used in all surrounding functions). (side note: the fact that
many pr_*() functions simply return "snprintf(outbuf, COLWID," justifies
the "amount" checks added to show_one_proc() by the "ps/output.c:
Replace strcpy() with snprintf() in show_one_proc()." patch)

pr_stime(): Check the return value of strftime() (in case of an error,
"the contents of the array are undefined").

help_pr_sig(): Handle the "len < 8" case, otherwise "sig+len-8" may
point outside the sig string.

pr_context(): Handle the empty string case, or else "outbuf[len-1]"
points outside outbuf.

ps/output.c

index 14174b184beb3cc8aeae411444dd964413ca124e..a60c98e8eaa3330a70686a246fabde42ad6d8447 100644 (file)
@@ -884,8 +884,8 @@ static int pr_bsdstart(char *restrict const outbuf, const proc_t *restrict const
   start = getbtime() + pp->start_time / Hertz;
   seconds_ago = seconds_since_1970 - start;
   if(seconds_ago < 0) seconds_ago=0;
-  if(seconds_ago > 3600*24)  strcpy(outbuf, ctime(&start)+4);
-  else                       strcpy(outbuf, ctime(&start)+10);
+  if(seconds_ago > 3600*24)  snprintf(outbuf, COLWID, "%s", ctime(&start)+4);
+  else                       snprintf(outbuf, COLWID, "%s", ctime(&start)+10);
   outbuf[6] = '\0';
   return 6;
 }
@@ -1021,6 +1021,7 @@ static int pr_stime(char *restrict const outbuf, const proc_t *restrict const pp
   const char *fmt;
   int tm_year;
   int tm_yday;
+  size_t len;
   our_time = localtime(&seconds_since_1970);   /* not reentrant */
   tm_year = our_time->tm_year;
   tm_yday = our_time->tm_yday;
@@ -1029,7 +1030,9 @@ static int pr_stime(char *restrict const outbuf, const proc_t *restrict const pp
   fmt = "%H:%M";                                   /* 03:02 23:59 */
   if(tm_yday != proc_time->tm_yday) fmt = "%b%d";  /* Jun06 Aug27 */
   if(tm_year != proc_time->tm_year) fmt = "%Y";    /* 1991 2001 */
-  return strftime(outbuf, 42, fmt, proc_time);
+  len = strftime(outbuf, COLWID, fmt, proc_time);
+  if(len <= 0 || len >= COLWID) outbuf[len = 0] = '\0';
+  return len;
 }
 
 static int pr_start(char *restrict const outbuf, const proc_t *restrict const pp){
@@ -1047,14 +1050,15 @@ static int pr_start(char *restrict const outbuf, const proc_t *restrict const pp
 
 #ifdef SIGNAL_STRING
 static int help_pr_sig(char *restrict const outbuf, const char *restrict const sig){
-  long len = 0;
-  len = strlen(sig);
+  const size_t len = strlen(sig);
   if(wide_signals){
     if(len>8) return snprintf(outbuf, COLWID, "%s", sig);
     return snprintf(outbuf, COLWID, "00000000%s", sig);
   }
   if(len-strspn(sig,"0") > 8)
     return snprintf(outbuf, COLWID, "<%s", sig+len-8);
+  if(len < 8)
+    return snprintf(outbuf, COLWID, "%s%s", "00000000"+len, sig);
   return snprintf(outbuf, COLWID,  "%s", sig+len-8);
 }
 #else
@@ -1337,7 +1341,7 @@ static int pr_context(char *restrict const outbuf, const proc_t *restrict const
     len = strlen(context);
     if(len > max_len) len = max_len;
     memcpy(outbuf, context, len);
-    if (outbuf[len-1] == '\n') --len;
+    if (len >= 1 && outbuf[len-1] == '\n') --len;
     outbuf[len] = '\0';
     ps_freecon(context);
   }else{