From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2012) id DE6443858C5E; Tue, 30 Jan 2024 18:06:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DE6443858C5E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1706637975; bh=4a9SkIUDjC5q22faQMnKuo16uQ5cqpiqVRLxDPc3TnQ=; h=From:To:Subject:Date:From; b=EuIyEXDG62pu2iPoWDXGLndPyVZ0T9hv82+TWoGSugIu7aXpPp3Du/o6Z3tpZVsnf NQ5Oriu3fDyP6kZuYNB8q9O6bZNNybUp5uwTdc9ISBjGCUVeZFysxq7z8/ZGCioRWM v3mkhGCD0+aVW4zsDSHwUaWWI+I+VLDzBK+Z/S2M= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Arjun Shankar To: glibc-cvs@sourceware.org Subject: [glibc/release/2.36/master] syslog: Fix heap buffer overflow in __vsyslog_internal (CVE-2023-6779) X-Act-Checkin: glibc X-Git-Author: Arjun Shankar X-Git-Refname: refs/heads/release/2.36/master X-Git-Oldrev: d1a83b6767f68b3cb5b4b4ea2617254acd040c82 X-Git-Newrev: 2bc9d7c002bdac38b5c2a3f11b78e309d7765b83 Message-Id: <20240130180615.DE6443858C5E@sourceware.org> Date: Tue, 30 Jan 2024 18:06:15 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=2bc9d7c002bdac38b5c2a3f11b78e309d7765b83 commit 2bc9d7c002bdac38b5c2a3f11b78e309d7765b83 Author: Arjun Shankar Date: Mon Jan 15 17:44:44 2024 +0100 syslog: Fix heap buffer overflow in __vsyslog_internal (CVE-2023-6779) __vsyslog_internal used the return value of snprintf/vsnprintf to calculate buffer sizes for memory allocation. If these functions (for any reason) failed and returned -1, the resulting buffer would be too small to hold output. This commit fixes that. All snprintf/vsnprintf calls are checked for negative return values and the function silently returns upon encountering them. Reviewed-by: Carlos O'Donell (cherry picked from commit 7e5a0c286da33159d47d0122007aac016f3e02cd) Diff: --- misc/syslog.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/misc/syslog.c b/misc/syslog.c index fe1daf988b..3108ae9134 100644 --- a/misc/syslog.c +++ b/misc/syslog.c @@ -183,11 +183,13 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap, else l = __snprintf (bufs, sizeof bufs, SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff)); + if (l < 0) + goto out; char *pos; size_t len; - if (0 <= l && l < sizeof bufs) + if (l < sizeof bufs) { /* At this point, there is still a chance that we can print the remaining part of the log into bufs and use that. */ @@ -213,12 +215,15 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap, __set_errno (saved_errno); vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags); + va_end (apc); + + if (vl < 0) + goto out; - if (!(0 <= vl && vl < len)) + if (vl >= len) buf = NULL; bufsize = l + vl; - va_end (apc); } if (buf == NULL) @@ -229,25 +234,37 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap, /* Tell the cancellation handler to free this buffer. */ clarg.buf = buf; + int cl; if (has_ts) - __snprintf (buf, l + 1, - SYSLOG_HEADER (pri, timestamp, &msgoff, pid)); + cl = __snprintf (buf, l + 1, + SYSLOG_HEADER (pri, timestamp, &msgoff, pid)); else - __snprintf (buf, l + 1, - SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff)); + cl = __snprintf (buf, l + 1, + SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff)); + if (cl != l) + goto out; va_list apc; va_copy (apc, ap); - __vsnprintf_internal (buf + l, bufsize - l + 1, fmt, apc, - mode_flags); + cl = __vsnprintf_internal (buf + l, bufsize - l + 1, fmt, apc, + mode_flags); va_end (apc); + + if (cl != vl) + goto out; } else { + int bl; /* Nothing much to do but emit an error message. */ - bufsize = __snprintf (bufs, sizeof bufs, - "out of memory[%d]", __getpid ()); + bl = __snprintf (bufs, sizeof bufs, + "out of memory[%d]", __getpid ()); + if (bl < 0 || bl >= sizeof bufs) + goto out; + + bufsize = bl; buf = bufs; + msgoff = 0; } }