From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2012) id 28F813858435; Tue, 30 Jan 2024 18:02:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 28F813858435 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1706637736; bh=xlI6zWe/yCP5YSvuw45i8NOpQssJzTMUwgjAxCxMVt4=; h=From:To:Subject:Date:From; b=B6YZGX+aEjdw4CflXLORO/jVHAcWfI+Q+r2Y0UiipqLMza5KfCQiL0x8h8LF78wGW nd41+COPZmLGLBFlpowIQrW7m0PIzSeoR5k0Dgokge4q9M5avnfGLYhrAKsKRiwpjO OviYujHD68qREK7DhmFoIPeFsBGwJmxqW4x+PoII= 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] 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/master X-Git-Oldrev: 6bd0e4efcc78f3c0115e5ea9739a1642807450da X-Git-Newrev: 7e5a0c286da33159d47d0122007aac016f3e02cd Message-Id: <20240130180216.28F813858435@sourceware.org> Date: Tue, 30 Jan 2024 18:02:16 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=7e5a0c286da33159d47d0122007aac016f3e02cd commit 7e5a0c286da33159d47d0122007aac016f3e02cd 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 Diff: --- misc/syslog.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/misc/syslog.c b/misc/syslog.c index 814d224a1e..53440e47ad 100644 --- a/misc/syslog.c +++ b/misc/syslog.c @@ -185,11 +185,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. */ @@ -215,12 +217,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) @@ -231,25 +236,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; } }