Package: release.debian.org Severity: normal X-Debbugs-Cc: [email protected] Control: affects -1 + src:glibc User: [email protected] Usertags: unblock
Please unblock package glibc [ Reason ] The reason that triggered this upload is a security issue in regcomp (CVE-2025-8058) that got fixed in the upstream stable branch. It also includes a fix for iconv creating files with the wrong permissions. [ Impact ] If the unblock isn't granted, systems will be vulnerable to CVE-2025-8058. [ Tests ] Tests have been added for both changes, and actually represent the largest part of the debdiff. [ Risks ] Risks are quite low, besides the new tests, changes are small, easily reviewable and covered by additional tests. [ Checklist ] [x] all changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in testing [ Other info ] If it comes to late for the initial Trixie release, this could go in the first point release. unblock glibc/2.41-11
diff --git a/debian/changelog b/debian/changelog index 4ee8be6e..85356f8e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +glibc (2.41-11) unstable; urgency=medium + + * debian/patches/git-updates.diff: update from upstream stable branch: + - Fix iconv to not create executable files with -o. + - Fix double-free after allocation failure in regcomp (GLIBC-SA-2025-0005 + / CVE-2025-8058). Closes: #1109803. + + -- Aurelien Jarno <[email protected]> Sat, 26 Jul 2025 20:29:12 +0200 + glibc (2.41-10) unstable; urgency=medium [ Samuel Thibault ] diff --git a/debian/patches/git-updates.diff b/debian/patches/git-updates.diff index f8df40b4..ac1e1c31 100644 --- a/debian/patches/git-updates.diff +++ b/debian/patches/git-updates.diff @@ -22,10 +22,10 @@ index d0108d2caa..aa547a443f 100644 $(common-objdir):$(subst $(empty) ,:,$(patsubst ../$(subdir),.,$(rpath-dirs:%=$(common-objpfx)%))) else # build-static diff --git a/NEWS b/NEWS -index b11422b060..90d090ea77 100644 +index b11422b060..89d0935beb 100644 --- a/NEWS +++ b/NEWS -@@ -5,6 +5,34 @@ See the end for copying conditions. +@@ -5,6 +5,36 @@ See the end for copying conditions. Please send GNU C library bug reports via <https://sourceware.org/bugzilla/> using `glibc' in the "product" field. @@ -56,6 +56,8 @@ index b11422b060..90d090ea77 100644 + [32981] ports: elf/tst-execstack-prog-static-tunable fails on + sparc64-linux-gnu + [32987] elf: Fix subprocess status handling for tst-dlopen-sgid ++ [33164] iconv -o should not create executable files ++ [33185] Fix double-free after allocation failure in regcomp + Version 2.41 @@ -1589,6 +1591,43 @@ index 9f5990f340..8df6f5906e 100644 +glibc.rtld.execstack: 1 (min: 0, max: 2) glibc.rtld.nns: 0x4 (min: 0x1, max: 0x10) glibc.rtld.optional_static_tls: 0x200 (min: 0x0, max: 0x[f]+) +diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c +index 7dba5d8dff..558cfb11a3 100644 +--- a/iconv/iconv_prog.c ++++ b/iconv/iconv_prog.c +@@ -436,7 +436,7 @@ input_error (const char *path) + static void + open_output_direct (void) + { +- output_fd = open64 (output_file, O_WRONLY | O_CREAT | O_TRUNC, 0777); ++ output_fd = open64 (output_file, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (output_fd < 0) + output_error (); + } +@@ -457,7 +457,7 @@ prepare_output_file (char **argv) + else + { + /* If iconv creates the output file, no overlap is possible. */ +- output_fd = open64 (output_file, O_WRONLY | O_CREAT | O_EXCL, 0777); ++ output_fd = open64 (output_file, O_WRONLY | O_CREAT | O_EXCL, 0666); + if (output_fd >= 0) + output_buffer_size = copy_buffer_size; + else +diff --git a/iconv/tst-iconv_prog-buffer.sh b/iconv/tst-iconv_prog-buffer.sh +index 1c499d590d..40340c38fa 100644 +--- a/iconv/tst-iconv_prog-buffer.sh ++++ b/iconv/tst-iconv_prog-buffer.sh +@@ -75,6 +75,10 @@ run_iconv () { + } + + check_out_expected () { ++ if test -x "$tmp/out" ; then ++ echo "error: iconv output file is executable" ++ failure=true ++ fi + if ! cmp -s "$tmp/out" "$tmp/expected" ; then + echo "error: iconv output difference" >&$logfd + echo "*** expected ***" >&$logfd diff --git a/math/auto-libm-test-in b/math/auto-libm-test-in index 01ba689aa8..4f194da19d 100644 --- a/math/auto-libm-test-in @@ -1797,6 +1836,18 @@ index e98e2df152..43dd16d59c 100644 iattr->stacksize = to - (size_t) iattr->stackaddr; #endif /* We succeed and no need to look further. */ +diff --git a/posix/Makefile b/posix/Makefile +index a650abf598..0e209a7ed0 100644 +--- a/posix/Makefile ++++ b/posix/Makefile +@@ -303,6 +303,7 @@ tests := \ + tst-posix_spawn-setsid \ + tst-preadwrite \ + tst-preadwrite64 \ ++ tst-regcomp-bracket-free \ + tst-regcomp-truncated \ + tst-regex \ + tst-regex2 \ diff --git a/posix/environ.c b/posix/environ.c index a0ed0d80ea..924effe3cd 100644 --- a/posix/environ.c @@ -1816,6 +1867,210 @@ index a0ed0d80ea..924effe3cd 100644 + +struct environ_array *__environ_array_list; +environ_counter __environ_counter; +diff --git a/posix/regcomp.c b/posix/regcomp.c +index 69675d81f7..5c486cee56 100644 +--- a/posix/regcomp.c ++++ b/posix/regcomp.c +@@ -3384,6 +3384,7 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + { + #ifdef RE_ENABLE_I18N + free_charset (mbcset); ++ mbcset = NULL; + #endif + /* Build a tree for simple bracket. */ + br_token.type = SIMPLE_BRACKET; +@@ -3399,7 +3400,8 @@ parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, + parse_bracket_exp_free_return: + re_free (sbcset); + #ifdef RE_ENABLE_I18N +- free_charset (mbcset); ++ if (__glibc_likely (mbcset != NULL)) ++ free_charset (mbcset); + #endif /* RE_ENABLE_I18N */ + return NULL; + } +diff --git a/posix/tst-regcomp-bracket-free.c b/posix/tst-regcomp-bracket-free.c +new file mode 100644 +index 0000000000..3c091d8c44 +--- /dev/null ++++ b/posix/tst-regcomp-bracket-free.c +@@ -0,0 +1,176 @@ ++/* Test regcomp bracket parsing with injected allocation failures (bug 33185). ++ Copyright (C) 2025 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 ++ <https://www.gnu.org/licenses/>. */ ++ ++/* This test invokes regcomp multiple times, failing one memory ++ allocation in each call. The function call should fail with ++ REG_ESPACE (or succeed if it can recover from the allocation ++ failure). Previously, there was double-free bug. */ ++ ++#include <errno.h> ++#include <regex.h> ++#include <stdio.h> ++#include <string.h> ++#include <support/check.h> ++#include <support/namespace.h> ++#include <support/support.h> ++ ++/* Data structure allocated via MAP_SHARED, so that writes from the ++ subprocess are visible. */ ++struct shared_data ++{ ++ /* Number of tracked allocations performed so far. */ ++ volatile unsigned int allocation_count; ++ ++ /* If this number is reached, one allocation fails. */ ++ volatile unsigned int failing_allocation; ++ ++ /* The subprocess stores the expected name here. */ ++ char name[100]; ++}; ++ ++/* Allocation count in shared mapping. */ ++static struct shared_data *shared; ++ ++/* Returns true if a failure should be injected for this allocation. */ ++static bool ++fail_this_allocation (void) ++{ ++ if (shared != NULL) ++ { ++ unsigned int count = shared->allocation_count; ++ shared->allocation_count = count + 1; ++ return count == shared->failing_allocation; ++ } ++ else ++ return false; ++} ++ ++/* Failure-injecting wrappers for allocation functions used by glibc. */ ++ ++void * ++malloc (size_t size) ++{ ++ if (fail_this_allocation ()) ++ { ++ errno = ENOMEM; ++ return NULL; ++ } ++ extern __typeof (malloc) __libc_malloc; ++ return __libc_malloc (size); ++} ++ ++void * ++calloc (size_t a, size_t b) ++{ ++ if (fail_this_allocation ()) ++ { ++ errno = ENOMEM; ++ return NULL; ++ } ++ extern __typeof (calloc) __libc_calloc; ++ return __libc_calloc (a, b); ++} ++ ++void * ++realloc (void *ptr, size_t size) ++{ ++ if (fail_this_allocation ()) ++ { ++ errno = ENOMEM; ++ return NULL; ++ } ++ extern __typeof (realloc) __libc_realloc; ++ return __libc_realloc (ptr, size); ++} ++ ++/* No-op subprocess to verify that support_isolate_in_subprocess does ++ not perform any heap allocations. */ ++static void ++no_op (void *ignored) ++{ ++} ++ ++/* Perform a regcomp call in a subprocess. Used to count its ++ allocations. */ ++static void ++initialize (void *regexp1) ++{ ++ const char *regexp = regexp1; ++ ++ shared->allocation_count = 0; ++ ++ regex_t reg; ++ TEST_COMPARE (regcomp (®, regexp, 0), 0); ++} ++ ++/* Perform regcomp in a subprocess with fault injection. */ ++static void ++test_in_subprocess (void *regexp1) ++{ ++ const char *regexp = regexp1; ++ unsigned int inject_at = shared->failing_allocation; ++ ++ regex_t reg; ++ int ret = regcomp (®, regexp, 0); ++ ++ if (ret != 0) ++ { ++ TEST_COMPARE (ret, REG_ESPACE); ++ printf ("info: allocation %u failure results in return value %d," ++ " error %s (%d)\n", ++ inject_at, ret, strerrorname_np (errno), errno); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ char regexp[] = "[:alpha:]"; ++ ++ shared = support_shared_allocate (sizeof (*shared)); ++ ++ /* Disable fault injection. */ ++ shared->failing_allocation = ~0U; ++ ++ support_isolate_in_subprocess (no_op, NULL); ++ TEST_COMPARE (shared->allocation_count, 0); ++ ++ support_isolate_in_subprocess (initialize, regexp); ++ ++ /* The number of allocations in the successful case, plus some ++ slack. Once the number of expected allocations is exceeded, ++ injecting further failures does not make a difference. */ ++ unsigned int maximum_allocation_count = shared->allocation_count; ++ printf ("info: successful call performs %u allocations\n", ++ maximum_allocation_count); ++ maximum_allocation_count += 10; ++ ++ for (unsigned int inject_at = 0; inject_at <= maximum_allocation_count; ++ ++inject_at) ++ { ++ shared->allocation_count = 0; ++ shared->failing_allocation = inject_at; ++ support_isolate_in_subprocess (test_in_subprocess, regexp); ++ } ++ ++ support_shared_free (shared); ++ ++ return 0; ++} ++ ++#include <support/test-driver.c> diff --git a/stdlib/Makefile b/stdlib/Makefile index 1c4fa2382f..c9c8f702a2 100644 --- a/stdlib/Makefile

