From db25d0375a389ec3c2f5e6f2422a1ddff97841bd Mon Sep 17 00:00:00 2001 From: Qualys Security Advisory Date: Thu, 1 Jan 1970 00:00:00 +0000 Subject: [PATCH] ps/output.c: Protect outbuf in various pr_*() functions. 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 | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/ps/output.c b/ps/output.c index 14174b18..a60c98e8 100644 --- a/ps/output.c +++ b/ps/output.c @@ -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{