From d36a5743ffa58689b9bcd09745f894cf3e0aff2f Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Thu, 20 Mar 2025 22:57:52 +0100 Subject: [PATCH] CVE-2025-0395: Fix a buffer overflow in assert (RHEL-83306) Resolves: RHEL-83306 --- glibc-RHEL-83306-1.patch | 62 ++++++++++++++++++ glibc-RHEL-83306-2.patch | 135 +++++++++++++++++++++++++++++++++++++++ glibc.spec | 7 +- 3 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 glibc-RHEL-83306-1.patch create mode 100644 glibc-RHEL-83306-2.patch diff --git a/glibc-RHEL-83306-1.patch b/glibc-RHEL-83306-1.patch new file mode 100644 index 0000000..e47c3e6 --- /dev/null +++ b/glibc-RHEL-83306-1.patch @@ -0,0 +1,62 @@ +commit 68ee0f704cb81e9ad0a78c644a83e1e9cd2ee578 +Author: Siddhesh Poyarekar +Date: Tue Jan 21 16:11:06 2025 -0500 + + Fix underallocation of abort_msg_s struct (CVE-2025-0395) + + Include the space needed to store the length of the message itself, in + addition to the message string. This resolves BZ #32582. + + Signed-off-by: Siddhesh Poyarekar + Reviewed: Adhemerval Zanella + +Conflicts: + sysdeps/posix/libc_fatal.c: Adjust for skipped upstream commit: + cca9684f2d7a74fc0b28bfb1859955e0e28d7b4b + (stdio: Clean up __libc_message after unconditional abort) + +diff --git a/assert/assert.c b/assert/assert.c +index 8ed691bd323c876a..f81d751cdab5ff92 100644 +--- a/assert/assert.c ++++ b/assert/assert.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -64,7 +65,8 @@ __assert_fail_base (const char *fmt, const char *assertion, const char *file, + (void) __fxprintf (NULL, "%s", str); + (void) fflush (stderr); + +- total = (total + 1 + GLRO(dl_pagesize) - 1) & ~(GLRO(dl_pagesize) - 1); ++ total = ALIGN_UP (total + sizeof (struct abort_msg_s) + 1, ++ GLRO(dl_pagesize)); + struct abort_msg_s *buf = __mmap (NULL, total, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + if (__glibc_likely (buf != MAP_FAILED)) +diff --git a/sysdeps/posix/libc_fatal.c b/sysdeps/posix/libc_fatal.c +index 89a20080e16558b5..89d5782a44e251a8 100644 +--- a/sysdeps/posix/libc_fatal.c ++++ b/sysdeps/posix/libc_fatal.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -147,8 +148,8 @@ __libc_message (enum __libc_message_action action, const char *fmt, ...) + + if ((action & do_abort)) + { +- total = ((total + 1 + GLRO(dl_pagesize) - 1) +- & ~(GLRO(dl_pagesize) - 1)); ++ total = ALIGN_UP (total + sizeof (struct abort_msg_s) + 1, ++ GLRO(dl_pagesize)); + struct abort_msg_s *buf = __mmap (NULL, total, + PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); diff --git a/glibc-RHEL-83306-2.patch b/glibc-RHEL-83306-2.patch new file mode 100644 index 0000000..11a246d --- /dev/null +++ b/glibc-RHEL-83306-2.patch @@ -0,0 +1,135 @@ +commit cdb9ba84191ce72e86346fb8b1d906e7cd930ea2 +Author: Siddhesh Poyarekar +Date: Fri Jan 31 12:16:30 2025 -0500 + + assert: Add test for CVE-2025-0395 + + Use the __progname symbol to override the program name to induce the + failure that CVE-2025-0395 describes. + + This is related to BZ #32582 + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Adhemerval Zanella + +Conflicts: + assert/Makefile: Unsorted test list downstream; now sorted. + +diff --git a/assert/Makefile b/assert/Makefile +index e2141e120014c362..2af46926e280deb1 100644 +--- a/assert/Makefile ++++ b/assert/Makefile +@@ -25,7 +25,14 @@ include ../Makeconfig + headers := assert.h + + routines := assert assert-perr __assert +-tests := test-assert test-assert-perr tst-assert-c++ tst-assert-g++ ++ ++tests := \ ++ test-assert \ ++ test-assert-perr \ ++ tst-assert-c++ \ ++ tst-assert-g++ \ ++ tst-assert-sa-2025-0001 \ ++ # tests + + ifeq ($(have-cxx-thread_local),yes) + CFLAGS-tst-assert-c++.o = -std=c++11 +diff --git a/assert/tst-assert-sa-2025-0001.c b/assert/tst-assert-sa-2025-0001.c +new file mode 100644 +index 0000000000000000..102cb0078dafa9c1 +--- /dev/null ++++ b/assert/tst-assert-sa-2025-0001.c +@@ -0,0 +1,92 @@ ++/* Test for CVE-2025-0395. ++ Copyright The GNU Toolchain Authors. ++ 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 ++ . */ ++ ++/* Test that a large enough __progname does not result in a buffer overflow ++ when printing an assertion failure. This was CVE-2025-0395. */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern const char *__progname; ++ ++int ++do_test (int argc, char **argv) ++{ ++ ++ support_need_proc ("Reads /proc/self/maps to add guards to writable maps."); ++ ignore_stderr (); ++ ++ /* XXX assumes that the assert is on a 2 digit line number. */ ++ const char *prompt = ": %s:99: do_test: Assertion `argc < 1' failed.\n"; ++ ++ int ret = fprintf (stderr, prompt, __FILE__); ++ if (ret < 0) ++ FAIL_EXIT1 ("fprintf failed: %m\n"); ++ ++ size_t pagesize = getpagesize (); ++ size_t namesize = pagesize - 1 - ret; ++ ++ /* Alter the progname so that the assert message fills the entire page. */ ++ char progname[namesize]; ++ memset (progname, 'A', namesize - 1); ++ progname[namesize - 1] = '\0'; ++ __progname = progname; ++ ++ FILE *f = xfopen ("/proc/self/maps", "r"); ++ char *line = NULL; ++ size_t len = 0; ++ uintptr_t prev_to = 0; ++ ++ /* Pad the beginning of every writable mapping with a PROT_NONE map. This ++ ensures that the mmap in the assert_fail path never ends up below a ++ writable map and will terminate immediately in case of a buffer ++ overflow. */ ++ while (xgetline (&line, &len, f)) ++ { ++ uintptr_t from, to; ++ char perm[4]; ++ ++ sscanf (line, "%" SCNxPTR "-%" SCNxPTR " %c%c%c%c ", ++ &from, &to, ++ &perm[0], &perm[1], &perm[2], &perm[3]); ++ ++ bool writable = (memchr (perm, 'w', 4) != NULL); ++ ++ if (prev_to != 0 && from - prev_to > pagesize && writable) ++ xmmap ((void *) from - pagesize, pagesize, PROT_NONE, ++ MAP_ANONYMOUS | MAP_PRIVATE, 0); ++ ++ prev_to = to; ++ } ++ ++ xfclose (f); ++ ++ assert (argc < 1); ++ return 0; ++} ++ ++#define EXPECTED_SIGNAL SIGABRT ++#define TEST_FUNCTION_ARGV do_test ++#include diff --git a/glibc.spec b/glibc.spec index be058f4..aa414e1 100644 --- a/glibc.spec +++ b/glibc.spec @@ -115,7 +115,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: %{glibcrelease}.14 +Release: %{glibcrelease}.15 # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -1259,6 +1259,8 @@ Patch1024: glibc-RHEL-8381-8.patch Patch1025: glibc-RHEL-8381-9.patch Patch1026: glibc-RHEL-8381-10.patch Patch1027: glibc-RHEL-78390.patch +Patch1028: glibc-RHEL-83306-1.patch +Patch1029: glibc-RHEL-83306-2.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2920,6 +2922,9 @@ fi %{_libdir}/libpthread_nonshared.a %changelog +* Thu Mar 20 2025 Arjun Shankar - 2.28-251.15 +- CVE-2025-0395: Fix a buffer overflow in assert (RHEL-83306) + * Tue Feb 11 2025 Patsy Griffin - 2.28-251.14 - Correct locking and cancellation cleanup in syslog functions (RHEL-78390)