diff --git a/glibc-RHEL-104151.patch b/glibc-RHEL-104151.patch new file mode 100644 index 0000000..8248df4 --- /dev/null +++ b/glibc-RHEL-104151.patch @@ -0,0 +1,51 @@ +commit cdcf24ee14c27b77744ff52ab3ae852821207eb0 +Author: Florian Weimer +Date: Thu Jul 17 14:44:05 2025 +0200 + + iconv: iconv -o should not create executable files (bug 33164) + + The mistake is that open must use 0666 to pick up the umask, + and not 0777 (which is required by mkdir). + + Fixes commit 8ef3cff9d1ceafe369f982d980678d749fb93bd2 + ("iconv: Support in-place conversions (bug 10460, bug 32033)"). + + Reviewed-by: H.J. Lu + +diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c +index a2f1d34e4579f80f..30ebfa0696db1635 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 23098ac56a344c48..562f90fe513e94d7 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/glibc-RHEL-105324.patch b/glibc-RHEL-105324.patch new file mode 100644 index 0000000..5a4bd50 --- /dev/null +++ b/glibc-RHEL-105324.patch @@ -0,0 +1,229 @@ +commit 7ea06e994093fa0bcca0d0ee2c1db271d8d7885d +Author: Florian Weimer +Date: Mon Jul 21 21:43:49 2025 +0200 + + posix: Fix double-free after allocation failure in regcomp (bug 33185) + + If a memory allocation failure occurs during bracket expression + parsing in regcomp, a double-free error may result. + + Reported-by: Anastasia Belova + Co-authored-by: Paul Eggert + Reviewed-by: Andreas K. Huettel + +diff --git a/posix/Makefile b/posix/Makefile +index a1e84853a8797233..18ddb8c34176848e 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/regcomp.c b/posix/regcomp.c +index 5380d3c7b9d5139d..6595bb3c0d01a9f8 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 0000000000000000..3c091d8c44ebe56f +--- /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 ++ . */ ++ ++/* 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* 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 diff --git a/glibc-RHEL-95246-1.patch b/glibc-RHEL-95246-1.patch new file mode 100644 index 0000000..0b431c6 --- /dev/null +++ b/glibc-RHEL-95246-1.patch @@ -0,0 +1,26 @@ +commit 062257c5d929e3c9a83a26624a09e57936ac6b5e +Author: Joseph Myers +Date: Thu Dec 5 21:40:57 2024 +0000 + + Fix typo in elf/Makefile:postclean-generated + + The postclean-generated setting in elf/Makefile lists + $(objpfx)/dso-sort-tests-2.generated-makefile twice and + $(objpfx)/dso-sort-tests-1.generated-makefile not at all, which looks + like a typo; fix it to list each once. + + Tested for x86_64. + +diff --git a/elf/Makefile b/elf/Makefile +index 51d52b57876fc5ba..3af1ad44fb789c4c 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -1229,7 +1229,7 @@ $(objpfx)$(1).generated-makefile: $(1) + endef + endif + +-postclean-generated += $(objpfx)/dso-sort-tests-2.generated-makefile \ ++postclean-generated += $(objpfx)/dso-sort-tests-1.generated-makefile \ + $(objpfx)/dso-sort-tests-2.generated-makefile + + # Generate from each testcase description file diff --git a/glibc-RHEL-95246-2.patch b/glibc-RHEL-95246-2.patch new file mode 100644 index 0000000..2358e0c --- /dev/null +++ b/glibc-RHEL-95246-2.patch @@ -0,0 +1,98 @@ +commit 2fca4b624bd3ceb8c756b4145c7e96aa032b2b98 +Author: Florian Weimer +Date: Wed Jun 4 17:44:19 2025 +0200 + + Makefile: Avoid $(objpfx)/ in makefiles + + If paths with both $(objpfx)/ and $(objpfx) (which already includes + a trailing slash) appear during the build, this can trigger unexpected + rebuilds, or incorrect concurrent rebuilds. + +Conflicts: + elf/Makefile + (additional generated files upstream) + +diff --git a/elf/Makefile b/elf/Makefile +index 3af1ad44fb789c4c..0d34de3b2c99e5bd 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -1229,8 +1229,8 @@ $(objpfx)$(1).generated-makefile: $(1) + endef + endif + +-postclean-generated += $(objpfx)/dso-sort-tests-1.generated-makefile \ +- $(objpfx)/dso-sort-tests-2.generated-makefile ++postclean-generated += $(objpfx)dso-sort-tests-1.generated-makefile \ ++ $(objpfx)dso-sort-tests-2.generated-makefile + + # Generate from each testcase description file + $(eval $(call include_dsosort_tests,dso-sort-tests-1.def)) +@@ -2823,7 +2823,7 @@ $(objpfx)tst-rtld-list-diagnostics.out: tst-rtld-list-diagnostics.py \ + > $@; \ + $(evaluate-test) + +-$(objpfx)tst-rtld-run-static.out: $(objpfx)/ldconfig ++$(objpfx)tst-rtld-run-static.out: $(objpfx)ldconfig + + $(objpfx)tst-dl_find_object.out: \ + $(objpfx)tst-dl_find_object-mod1.so $(objpfx)tst-dl_find_object-mod2.so +diff --git a/nss/Makefile b/nss/Makefile +index 9331b3308c36c45b..37bec502fcff2f72 100644 +--- a/nss/Makefile ++++ b/nss/Makefile +@@ -475,39 +475,39 @@ libof-nss_test1 = extramodules + libof-nss_test2 = extramodules + libof-nss_test_errno = extramodules + libof-nss_test_gai_hv2_canonname = extramodules +-$(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps) ++$(objpfx)libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps) + $(build-module) +-$(objpfx)/libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps) ++$(objpfx)libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps) + $(build-module) +-$(objpfx)/libnss_test_errno.so: $(objpfx)nss_test_errno.os $(link-libc-deps) ++$(objpfx)libnss_test_errno.so: $(objpfx)nss_test_errno.os $(link-libc-deps) + $(build-module) +-$(objpfx)/libnss_test_gai_hv2_canonname.so: \ ++$(objpfx)libnss_test_gai_hv2_canonname.so: \ + $(objpfx)nss_test_gai_hv2_canonname.os $(link-libc-deps) + $(build-module) + $(objpfx)nss_test2.os : nss_test1.c + # Use the nss_files suffix for these objects as well. +-$(objpfx)/libnss_test1.so$(libnss_files.so-version): $(objpfx)/libnss_test1.so ++$(objpfx)libnss_test1.so$(libnss_files.so-version): $(objpfx)libnss_test1.so + $(make-link) +-$(objpfx)/libnss_test2.so$(libnss_files.so-version): $(objpfx)/libnss_test2.so ++$(objpfx)libnss_test2.so$(libnss_files.so-version): $(objpfx)libnss_test2.so + $(make-link) +-$(objpfx)/libnss_test_errno.so$(libnss_files.so-version): \ +- $(objpfx)/libnss_test_errno.so ++$(objpfx)libnss_test_errno.so$(libnss_files.so-version): \ ++ $(objpfx)libnss_test_errno.so + $(make-link) +-$(objpfx)/libnss_test_gai_hv2_canonname.so$(libnss_files.so-version): \ +- $(objpfx)/libnss_test_gai_hv2_canonname.so ++$(objpfx)libnss_test_gai_hv2_canonname.so$(libnss_files.so-version): \ ++ $(objpfx)libnss_test_gai_hv2_canonname.so + $(make-link) + $(patsubst %,$(objpfx)%.out,$(tests) $(tests-container)) : \ +- $(objpfx)/libnss_test1.so$(libnss_files.so-version) \ +- $(objpfx)/libnss_test2.so$(libnss_files.so-version) \ +- $(objpfx)/libnss_test_errno.so$(libnss_files.so-version) \ +- $(objpfx)/libnss_test_gai_hv2_canonname.so$(libnss_files.so-version) ++ $(objpfx)libnss_test1.so$(libnss_files.so-version) \ ++ $(objpfx)libnss_test2.so$(libnss_files.so-version) \ ++ $(objpfx)libnss_test_errno.so$(libnss_files.so-version) \ ++ $(objpfx)libnss_test_gai_hv2_canonname.so$(libnss_files.so-version) + + ifeq (yes,$(have-thread-library)) + $(objpfx)tst-cancel-getpwuid_r: $(shared-thread-library) + endif + +-$(objpfx)tst-nss-files-alias-leak.out: $(objpfx)/libnss_files.so +-$(objpfx)tst-nss-files-alias-truncated.out: $(objpfx)/libnss_files.so ++$(objpfx)tst-nss-files-alias-leak.out: $(objpfx)libnss_files.so ++$(objpfx)tst-nss-files-alias-truncated.out: $(objpfx)libnss_files.so + + tst-nss-gai-hv2-canonname-ENV = \ + MALLOC_TRACE=$(objpfx)tst-nss-gai-hv2-canonname.mtrace \ diff --git a/glibc.spec b/glibc.spec index a094863..9cd3321 100644 --- a/glibc.spec +++ b/glibc.spec @@ -145,7 +145,7 @@ Version: %{glibcversion} # - It allows using the Release number without the %%dist tag in the dependency # generator to make the generated requires interchangeable between Rawhide # and ELN (.elnYY < .fcXX). -%global baserelease 43 +%global baserelease 46 Release: %{baserelease}%{?dist}.alma.1 # Licenses: @@ -576,6 +576,10 @@ Patch258: glibc-upstream-2.39-211.patch Patch259: glibc-RHEL-82285.patch Patch260: glibc-RHEL-101754-1.patch Patch261: glibc-RHEL-101754-2.patch +Patch262: glibc-RHEL-104151.patch +Patch263: glibc-RHEL-95246-1.patch +Patch264: glibc-RHEL-95246-2.patch +Patch265: glibc-RHEL-105324.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2579,10 +2583,19 @@ update_gconv_modules_cache () %endif %changelog -* Thu Jul 10 2025 Eduard Abdullin - 2.39-43.alma.1 +* Tue Jul 29 2025 Eduard Abdullin - 2.39-46.alma.1 - Overwrite target for x86_64_v2 - Add /usr/lib64/lp64d to ricv64 +* Thu Jul 24 2025 Florian Weimer - 2.39-46 +- CVE-2025-8058: Double free in regcomp (RHEL-105324) + +* Thu Jul 24 2025 Florian Weimer - 2.39-45 +- Reduce spurious rebuilds while running tests (RHEL-95246) + +* Wed Jul 23 2025 Florian Weimer - 2.39-44 +- iconv: Do not create executable output files (RHEL-104151) + * Wed Jul 09 2025 Florian Weimer - 2.39-43 - Rebuild due to SIGNSERVER-1997 (RHEL-102555)