From e2e7d1ceae007d997926a783d65c1c4d9b67a71b Mon Sep 17 00:00:00 2001 From: Funda Wang Date: Thu, 1 Feb 2024 14:13:28 +0800 Subject: [PATCH] fix CVE-2023-6246, CVE-2023-6779, and CVE-2023-6780 --- 0087-CVE-2023-6246.patch | 181 +++++++++++++++++++++++++++++++++++++++ 0088-CVE-2023-6779.patch | 106 +++++++++++++++++++++++ 0089-CVE-2023-6780.patch | 41 +++++++++ glibc.spec | 12 ++- 4 files changed, 337 insertions(+), 3 deletions(-) create mode 100644 0087-CVE-2023-6246.patch create mode 100644 0088-CVE-2023-6779.patch create mode 100644 0089-CVE-2023-6780.patch diff --git a/0087-CVE-2023-6246.patch b/0087-CVE-2023-6246.patch new file mode 100644 index 0000000..9ddca42 --- /dev/null +++ b/0087-CVE-2023-6246.patch @@ -0,0 +1,181 @@ +From d1a83b6767f68b3cb5b4b4ea2617254acd040c82 Mon Sep 17 00:00:00 2001 +From: Arjun Shankar +Date: Mon, 15 Jan 2024 17:44:43 +0100 +Subject: [PATCH] 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 ba8232a0e9..66e9ded8f9 100644 +--- a/misc/Makefile ++++ b/misc/Makefile +@@ -115,7 +115,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) +@@ -175,6 +178,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 f67d4b58a4..fe1daf988b 100644 +--- a/misc/syslog.c ++++ b/misc/syslog.c +@@ -122,8 +122,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; + +@@ -175,29 +176,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.39.3 + diff --git a/0088-CVE-2023-6779.patch b/0088-CVE-2023-6779.patch new file mode 100644 index 0000000..8a658bb --- /dev/null +++ b/0088-CVE-2023-6779.patch @@ -0,0 +1,106 @@ +From 2bc9d7c002bdac38b5c2a3f11b78e309d7765b83 Mon Sep 17 00:00:00 2001 +From: Arjun Shankar +Date: Mon, 15 Jan 2024 17:44:44 +0100 +Subject: [PATCH] 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 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; + } + } + +-- +2.39.3 + diff --git a/0089-CVE-2023-6780.patch b/0089-CVE-2023-6780.patch new file mode 100644 index 0000000..d6190b7 --- /dev/null +++ b/0089-CVE-2023-6780.patch @@ -0,0 +1,41 @@ +From b9b7d6a27aa0632f334352fa400771115b3c69b7 Mon Sep 17 00:00:00 2001 +From: Arjun Shankar +Date: Mon, 15 Jan 2024 17:44:45 +0100 +Subject: [PATCH] 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 3108ae9134..9336036666 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 */ +@@ -217,7 +218,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.39.3 + diff --git a/glibc.spec b/glibc.spec index e92e815..46a17d5 100644 --- a/glibc.spec +++ b/glibc.spec @@ -1,4 +1,4 @@ -%define anolis_release 12 +%define anolis_release 13 %bcond_without testsuite %bcond_without benchtests @@ -182,6 +182,9 @@ Patch0183: 0083-CVE-2023-4527.patch Patch0184: 0084-CVE-2023-4806.patch Patch0185: 0085-CVE-2023-5156.patch Patch0186: 0086-CVE-2023-4911.patch +Patch0187: 0087-CVE-2023-6246.patch +Patch0188: 0088-CVE-2023-6779.patch +Patch0189: 0089-CVE-2023-6780.patch BuildRequires: audit-libs-devel >= 1.1.3 libcap-devel systemtap-sdt-devel BuildRequires: procps-ng util-linux gawk sed >= 3.95 gettext @@ -1135,10 +1138,13 @@ update_gconv_modules_cache () %{_libdir}/libpthread_nonshared.a %changelog +* Thu Feb 01 2024 Funda Wang - 2.36-13 +- fix CVE-2023-6246, CVE-2023-6779, and CVE-2023-6780. + * Tue Oct 24 2023 Peng Fan - 2.36-12 - LoongArch: Not provided libanl, libnsl and libutil by LoongArch. -* Thu Oct 11 2023 Peng Fan - 2.36-11 +* Wed Oct 11 2023 Peng Fan - 2.36-11 - LoongArch: Ignore kernel version checks. - Temporarily not pack libanl.so and libutil.so in LoongArch. @@ -1182,4 +1188,4 @@ update_gconv_modules_cache () - RISC-V ABI wants to install everything in /lib64/lp64d or /usr/lib64/lp64d. Make these be symlinks to /lib64 or /usr/lib64 respectively. * Tue Feb 22 2022 Chunmei Xu - 2.35-1 -- upstream 2.35 release tarball and add patches from release/2.35/master \ No newline at end of file +- upstream 2.35 release tarball and add patches from release/2.35/master