From 263c0ebdd847ebe1382a1ba5f0cb8570d949ca2a Mon Sep 17 00:00:00 2001 From: Qualys Security Advisory Date: Thu, 1 Jan 1970 00:00:00 +0000 Subject: [PATCH] proc/readproc.c: Harden fill_cgroup_cvt(). Check the return value of snprintf(), otherwise dst may point out-of-bounds when it reaches the end of the dst_buffer (the snprintf() always returns 1 in that case, even if there is not enough space left), and vMAX becomes negative and is passed to snprintf() as a size_t. --- proc/readproc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/proc/readproc.c b/proc/readproc.c index 2ee0f28d..18644ffb 100644 --- a/proc/readproc.c +++ b/proc/readproc.c @@ -821,7 +821,7 @@ static char** vectorize_this_str (const char* src) { static void fill_cgroup_cvt (const char* directory, proc_t *restrict p) { #define vMAX ( MAX_BUFSZ - (int)(dst - dst_buffer) ) char *src, *dst, *grp, *eob, *name; - int tot, x, whackable_int = MAX_BUFSZ; + int tot, x, whackable_int = MAX_BUFSZ, len; *(dst = dst_buffer) = '\0'; // empty destination tot = read_unvectored(src_buffer, MAX_BUFSZ, directory, "cgroup", '\0'); @@ -833,7 +833,10 @@ static void fill_cgroup_cvt (const char* directory, proc_t *restrict p) { #if 0 grp += strspn(grp, "0123456789:"); // jump past group number #endif - dst += snprintf(dst, vMAX, "%s", (dst > dst_buffer) ? "," : ""); + if (vMAX <= 1) break; + len = snprintf(dst, vMAX, "%s", (dst > dst_buffer) ? "," : ""); + if (len < 0 || len >= vMAX) break; + dst += len; dst += escape_str(dst, grp, vMAX, &whackable_int); } p->cgroup = vectorize_this_str(dst_buffer[0] ? dst_buffer : "-");