From 2e599fc62b773d7e605b122d64ce0176f5900eaa Mon Sep 17 00:00:00 2001 From: EulerOSWander <314264452@qq.com> Date: Wed, 31 Jan 2024 17:48:11 +0800 Subject: [PATCH 1/2] syslog:Fix heap buffer overflow in _vsyslog_internal Fix CVE-2023-6246 Signed-off-by: EulerOSWander <314264452@qq.com> --- ...buffer-overflow-in-__vsyslog_interna.patch | 181 ++++++++++++++++++ glibc.spec | 6 +- 2 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch diff --git a/0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch b/0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch new file mode 100644 index 0000000..395b520 --- /dev/null +++ b/0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch @@ -0,0 +1,181 @@ +From 23514c72b780f3da097ecf33a793b7ba9c2070d2 Mon Sep 17 00:00:00 2001 +From: Arjun Shankar +Date: Mon, 15 Jan 2024 17:44:43 +0100 +Subject: [PATCH 1/3] syslog: Fix heap buffer overflow in __vsyslog_internal + (CVE-2023-6246) + +__vsyslog_internal did not handle a case where printing a SYSLOG_HEADER +containing a long program name failed to update the required buffer +size, leading to the allocation and overflow of a too-small buffer on +the heap. This commit fixes that. It also adds a new regression test +that uses glibc.malloc.check. + +Reviewed-by: Adhemerval Zanella +Reviewed-by: Carlos O'Donell +Tested-by: Carlos O'Donell +(cherry picked from commit 6bd0e4efcc78f3c0115e5ea9739a1642807450da) +--- + misc/Makefile | 8 ++- + misc/syslog.c | 50 +++++++++++++------ + misc/tst-syslog-long-progname.c | 39 +++++++++++++++ + .../postclean.req | 0 + 4 files changed, 82 insertions(+), 15 deletions(-) + create mode 100644 misc/tst-syslog-long-progname.c + create mode 100644 misc/tst-syslog-long-progname.root/postclean.req + +diff --git a/misc/Makefile b/misc/Makefile +index fe0d49c1de..90b31952c5 100644 +--- a/misc/Makefile ++++ b/misc/Makefile +@@ -289,7 +289,10 @@ tests-special += $(objpfx)tst-error1-mem.out \ + $(objpfx)tst-allocate_once-mem.out + endif + +-tests-container := tst-syslog ++tests-container := \ ++ tst-syslog \ ++ tst-syslog-long-progname \ ++ # tests-container + + CFLAGS-select.c += -fexceptions -fasynchronous-unwind-tables + CFLAGS-tsearch.c += $(uses-callbacks) +@@ -351,6 +354,9 @@ $(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \ + $(evaluate-test) + ++tst-syslog-long-progname-ENV = GLIBC_TUNABLES=glibc.malloc.check=3 \ ++ LD_PRELOAD=libc_malloc_debug.so.0 ++ + $(objpfx)tst-select: $(librt) + $(objpfx)tst-select-time64: $(librt) + $(objpfx)tst-pselect: $(librt) +diff --git a/misc/syslog.c b/misc/syslog.c +index 1b8cb722c5..814d224a1e 100644 +--- a/misc/syslog.c ++++ b/misc/syslog.c +@@ -124,8 +124,9 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap, + { + /* Try to use a static buffer as an optimization. */ + char bufs[1024]; +- char *buf = NULL; +- size_t bufsize = 0; ++ char *buf = bufs; ++ size_t bufsize; ++ + int msgoff; + int saved_errno = errno; + +@@ -177,29 +178,50 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap, + #define SYSLOG_HEADER_WITHOUT_TS(__pri, __msgoff) \ + "<%d>: %n", __pri, __msgoff + +- int l; ++ int l, vl; + if (has_ts) + l = __snprintf (bufs, sizeof bufs, + SYSLOG_HEADER (pri, timestamp, &msgoff, pid)); + else + l = __snprintf (bufs, sizeof bufs, + SYSLOG_HEADER_WITHOUT_TS (pri, &msgoff)); ++ ++ char *pos; ++ size_t len; ++ + if (0 <= l && l < sizeof bufs) + { +- va_list apc; +- va_copy (apc, ap); ++ /* At this point, there is still a chance that we can print the ++ remaining part of the log into bufs and use that. */ ++ pos = bufs + l; ++ len = sizeof (bufs) - l; ++ } ++ else ++ { ++ buf = NULL; ++ /* We already know that bufs is too small to use for this log message. ++ The next vsnprintf into bufs is used only to calculate the total ++ required buffer length. We will discard bufs contents and allocate ++ an appropriately sized buffer later instead. */ ++ pos = bufs; ++ len = sizeof (bufs); ++ } + +- /* Restore errno for %m format. */ +- __set_errno (saved_errno); ++ { ++ va_list apc; ++ va_copy (apc, ap); + +- int vl = __vsnprintf_internal (bufs + l, sizeof bufs - l, fmt, apc, +- mode_flags); +- if (0 <= vl && vl < sizeof bufs - l) +- buf = bufs; +- bufsize = l + vl; ++ /* Restore errno for %m format. */ ++ __set_errno (saved_errno); + +- va_end (apc); +- } ++ vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags); ++ ++ if (!(0 <= vl && vl < len)) ++ buf = NULL; ++ ++ bufsize = l + vl; ++ va_end (apc); ++ } + + if (buf == NULL) + { +diff --git a/misc/tst-syslog-long-progname.c b/misc/tst-syslog-long-progname.c +new file mode 100644 +index 0000000000..88f37a8a00 +--- /dev/null ++++ b/misc/tst-syslog-long-progname.c +@@ -0,0 +1,39 @@ ++/* Test heap buffer overflow in syslog with long __progname (CVE-2023-6246) ++ Copyright (C) 2023 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++extern char * __progname; ++ ++static int ++do_test (void) ++{ ++ char long_progname[2048]; ++ ++ memset (long_progname, 'X', sizeof (long_progname) - 1); ++ long_progname[sizeof (long_progname) - 1] = '\0'; ++ ++ __progname = long_progname; ++ ++ syslog (LOG_INFO, "Hello, World!"); ++ ++ return 0; ++} ++ ++#include +diff --git a/misc/tst-syslog-long-progname.root/postclean.req b/misc/tst-syslog-long-progname.root/postclean.req +new file mode 100644 +index 0000000000..e69de29bb2 +-- +2.33.0 + diff --git a/glibc.spec b/glibc.spec index 4ec1d7a..af3f14a 100644 --- a/glibc.spec +++ b/glibc.spec @@ -67,7 +67,7 @@ ############################################################################## Name: glibc Version: 2.38 -Release: 16 +Release: 18 Summary: The GNU libc libraries License: %{all_license} URL: http://www.gnu.org/software/glibc/ @@ -130,6 +130,7 @@ Patch41: getaddrinfo-translate-ENOMEM-to-EAI_MEMORY-bug-31163.patch Patch42: libio-Check-remaining-buffer-size-in-_IO_wdo_write-b.patch Patch43: elf-Add-a-way-to-check-if-tunable-is-set-BZ-27069.patch Patch44: malloc-Improve-MAP_HUGETLB-with-glibc.malloc.hugetlb.patch +Patch45: 0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch Patch9000: turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch Patch9001: locale-delete-no-hard-link-to-avoid-all_language-pac.patch @@ -1343,6 +1344,9 @@ fi %endif %changelog +* Wed Jan 31 Qingqing Li - 2.38-18 +- backport:fix CVE-2023-6246. + * Sat Jan 13 Qingqing Li - 2.38-17 - elf: Add a way to check if tunable is set (BZ 27069) - malloc: Improve MAPE_HUGETLB with glibc.malloc.hugetlb=2 -- Gitee From d29d31689b0387d0b39154f0576d3929e8558a05 Mon Sep 17 00:00:00 2001 From: EulerOSWander <314264452@qq.com> Date: Thu, 1 Feb 2024 19:31:14 +0800 Subject: [PATCH 2/2] [Backport]Fix CVE-2023-6779 CVE-2023-6780 Fix Heap buffer overflow and integer overflow issue. Signed-off-by: EulerOSWander <314264452@qq.com> --- ...buffer-overflow-in-__vsyslog_interna.patch | 106 ++++++++++++++++++ ...er-overflow-in-__vsyslog_internal-CV.patch | 41 +++++++ glibc.spec | 7 +- 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 0002-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch create mode 100644 0003-syslog-Fix-integer-overflow-in-__vsyslog_internal-CV.patch diff --git a/0002-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch b/0002-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch new file mode 100644 index 0000000..c19c3bf --- /dev/null +++ b/0002-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch @@ -0,0 +1,106 @@ +From d0338312aace5bbfef85e03055e1212dd0e49578 Mon Sep 17 00:00:00 2001 +From: Arjun Shankar +Date: Mon, 15 Jan 2024 17:44:44 +0100 +Subject: [PATCH 2/3] 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) +--- + 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; + } + } + +-- +2.33.0 + diff --git a/0003-syslog-Fix-integer-overflow-in-__vsyslog_internal-CV.patch b/0003-syslog-Fix-integer-overflow-in-__vsyslog_internal-CV.patch new file mode 100644 index 0000000..70ee520 --- /dev/null +++ b/0003-syslog-Fix-integer-overflow-in-__vsyslog_internal-CV.patch @@ -0,0 +1,41 @@ +From d37c2b20a4787463d192b32041c3406c2bd91de0 Mon Sep 17 00:00:00 2001 +From: Arjun Shankar +Date: Mon, 15 Jan 2024 17:44:45 +0100 +Subject: [PATCH 3/3] syslog: Fix integer overflow in __vsyslog_internal + (CVE-2023-6780) + +__vsyslog_internal calculated a buffer size by adding two integers, but +did not first check if the addition would overflow. This commit fixes +that. + +Reviewed-by: Carlos O'Donell +Tested-by: Carlos O'Donell +(cherry picked from commit ddf542da94caf97ff43cc2875c88749880b7259b) +--- + misc/syslog.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/misc/syslog.c b/misc/syslog.c +index 53440e47ad..4af87f54fd 100644 +--- a/misc/syslog.c ++++ b/misc/syslog.c +@@ -41,6 +41,7 @@ static char sccsid[] = "@(#)syslog.c 8.4 (Berkeley) 3/18/94"; + #include + #include + #include ++#include + + static int LogType = SOCK_DGRAM; /* type of socket connection */ + static int LogFile = -1; /* fd for log */ +@@ -219,7 +220,7 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap, + vl = __vsnprintf_internal (pos, len, fmt, apc, mode_flags); + va_end (apc); + +- if (vl < 0) ++ if (vl < 0 || vl >= INT_MAX - l) + goto out; + + if (vl >= len) +-- +2.33.0 + diff --git a/glibc.spec b/glibc.spec index af3f14a..5e3c8f0 100644 --- a/glibc.spec +++ b/glibc.spec @@ -67,7 +67,7 @@ ############################################################################## Name: glibc Version: 2.38 -Release: 18 +Release: 19 Summary: The GNU libc libraries License: %{all_license} URL: http://www.gnu.org/software/glibc/ @@ -131,6 +131,8 @@ Patch42: libio-Check-remaining-buffer-size-in-_IO_wdo_write-b.patch Patch43: elf-Add-a-way-to-check-if-tunable-is-set-BZ-27069.patch Patch44: malloc-Improve-MAP_HUGETLB-with-glibc.malloc.hugetlb.patch Patch45: 0001-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch +Patch46: 0002-syslog-Fix-heap-buffer-overflow-in-__vsyslog_interna.patch +Patch47: 0003-syslog-Fix-integer-overflow-in-__vsyslog_internal-CV.patch Patch9000: turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch Patch9001: locale-delete-no-hard-link-to-avoid-all_language-pac.patch @@ -1344,6 +1346,9 @@ fi %endif %changelog +* Thu Feb 1 Hewenliang - 2.38-19 +- backport:fix CVE-2023-6779 CVE-2023-6780 + * Wed Jan 31 Qingqing Li - 2.38-18 - backport:fix CVE-2023-6246. -- Gitee