import UBI glibc-2.34-168.el9_6.19

This commit is contained in:
eabdullin 2025-06-09 08:25:34 +00:00
parent 39a4f1a064
commit 4655139964
13 changed files with 1324 additions and 1 deletions

View File

@ -0,0 +1,33 @@
commit 61c3450db96dce96ad2b24b4f0b548e6a46d68e5
Author: Florian Weimer <fweimer@redhat.com>
Date: Tue Dec 17 18:12:03 2024 +0100
x86: Avoid integer truncation with large cache sizes (bug 32470)
Some hypervisors report 1 TiB L3 cache size. This results
in some variables incorrectly getting zeroed, causing crashes
in memcpy/memmove because invariants are violated.
Conflicts:
sysdeps/x86/dl-cacheinfo.h
(HAVE_TUNABLES still in use downstream)
diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
index 276442c2f1f03cd6..a65418892d8dc5e2 100644
--- a/sysdeps/x86/dl-cacheinfo.h
+++ b/sysdeps/x86/dl-cacheinfo.h
@@ -960,12 +960,12 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
#if HAVE_TUNABLES
/* NB: The REP MOVSB threshold must be greater than VEC_SIZE * 8. */
- unsigned int minimum_rep_movsb_threshold;
+ unsigned long int minimum_rep_movsb_threshold;
#endif
/* NB: The default REP MOVSB threshold is 4096 * (VEC_SIZE / 16) for
VEC_SIZE == 64 or 32. For VEC_SIZE == 16, the default REP MOVSB
threshold is 2048 * (VEC_SIZE / 16). */
- unsigned int rep_movsb_threshold;
+ unsigned long int rep_movsb_threshold;
if (CPU_FEATURE_USABLE_P (cpu_features, AVX512F)
&& !CPU_FEATURE_PREFERRED_P (cpu_features, Prefer_No_AVX512))
{

View File

@ -0,0 +1,95 @@
commit 5451fa962cd0a90a0e2ec1d8910a559ace02bba0
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Mon Nov 6 17:25:49 2023 -0300
elf: Ignore LD_LIBRARY_PATH and debug env var for setuid for static
It mimics the ld.so behavior.
Checked on x86_64-linux-gnu.
Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Conflicts:
elf/dl-support.c
(tunables are still optional downstream,
LD_PROFILE_OUTPUT handling is still present
for static binaries)
diff --git a/elf/dl-support.c b/elf/dl-support.c
index a2e45e7b14e3a6b9..1fea55c443505890 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -272,8 +272,6 @@ _dl_non_dynamic_init (void)
_dl_main_map.l_phdr = GL(dl_phdr);
_dl_main_map.l_phnum = GL(dl_phnum);
- _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
-
/* Set up the data structures for the system-supplied DSO early,
so they can influence _dl_init_paths. */
setup_vdso (NULL, NULL);
@@ -281,6 +279,30 @@ _dl_non_dynamic_init (void)
/* With vDSO setup we can initialize the function pointers. */
setup_vdso_pointers ();
+ if (__libc_enable_secure)
+ {
+ static const char unsecure_envvars[] =
+ UNSECURE_ENVVARS
+#ifdef EXTRA_UNSECURE_ENVVARS
+ EXTRA_UNSECURE_ENVVARS
+#endif
+ ;
+ const char *cp = unsecure_envvars;
+
+ while (cp < unsecure_envvars + sizeof (unsecure_envvars))
+ {
+ __unsetenv (cp);
+ cp = strchr (cp, '\0') + 1;
+ }
+
+#if !HAVE_TUNABLES
+ if (__access ("/etc/suid-debug", F_OK) != 0)
+ __unsetenv ("MALLOC_CHECK_");
+#endif
+}
+
+ _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
+
/* Initialize the data structures for the search paths for shared
objects. */
_dl_init_paths (getenv ("LD_LIBRARY_PATH"), "LD_LIBRARY_PATH",
@@ -298,32 +320,11 @@ _dl_non_dynamic_init (void)
_dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0';
_dl_profile_output = getenv ("LD_PROFILE_OUTPUT");
+
if (_dl_profile_output == NULL || _dl_profile_output[0] == '\0')
_dl_profile_output
= &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0];
- if (__libc_enable_secure)
- {
- static const char unsecure_envvars[] =
- UNSECURE_ENVVARS
-#ifdef EXTRA_UNSECURE_ENVVARS
- EXTRA_UNSECURE_ENVVARS
-#endif
- ;
- const char *cp = unsecure_envvars;
-
- while (cp < unsecure_envvars + sizeof (unsecure_envvars))
- {
- __unsetenv (cp);
- cp = (const char *) __rawmemchr (cp, '\0') + 1;
- }
-
-#if !HAVE_TUNABLES
- if (__access ("/etc/suid-debug", F_OK) != 0)
- __unsetenv ("MALLOC_CHECK_");
-#endif
- }
-
#ifdef DL_PLATFORM_INIT
DL_PLATFORM_INIT;
#endif

View File

@ -0,0 +1,56 @@
commit f0c09fe61678df6f7f18fe1ebff074e62fa5ca7a
Author: Florian Weimer <fweimer@redhat.com>
Date: Tue May 20 19:36:02 2025 +0200
support: Use const char * argument in support_capture_subprogram_self_sgid
The function does not modify the passed-in string, so make this clear
via the prototype.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
diff --git a/support/capture_subprocess.h b/support/capture_subprocess.h
index 4be430f099bcc8cd..4229300d4b0aab29 100644
--- a/support/capture_subprocess.h
+++ b/support/capture_subprocess.h
@@ -44,8 +44,7 @@ struct support_capture_subprocess support_capture_subprogram
/* Copy the running program into a setgid binary and run it with CHILD_ID
argument. If execution is successful, return the exit status of the child
program, otherwise return a non-zero failure exit code. */
-int support_capture_subprogram_self_sgid
- (char *child_id);
+int support_capture_subprogram_self_sgid (const char *child_id);
/* Deallocate the subprocess data captured by
support_capture_subprocess. */
diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c
index 0bacf6dbc23b0732..6e6ac8bbb7f64859 100644
--- a/support/support_capture_subprocess.c
+++ b/support/support_capture_subprocess.c
@@ -109,7 +109,7 @@ support_capture_subprogram (const char *file, char *const argv[])
safely make it SGID with the TARGET group ID. Then runs the
executable. */
static int
-copy_and_spawn_sgid (char *child_id, gid_t gid)
+copy_and_spawn_sgid (const char *child_id, gid_t gid)
{
char *dirname = xasprintf ("%s/tst-tunables-setuid.%jd",
test_dir, (intmax_t) getpid ());
@@ -172,7 +172,7 @@ copy_and_spawn_sgid (char *child_id, gid_t gid)
ret = 0;
infd = outfd = -1;
- char * const args[] = {execname, child_id, NULL};
+ char * const args[] = {execname, (char *) child_id, NULL};
status = support_subprogram_wait (args[0], args);
@@ -199,7 +199,7 @@ err:
}
int
-support_capture_subprogram_self_sgid (char *child_id)
+support_capture_subprogram_self_sgid (const char *child_id)
{
gid_t target = 0;
const int count = 64;

View File

@ -0,0 +1,41 @@
commit d0b8aa6de4529231fadfe604ac2c434e559c2d9e
Author: Florian Weimer <fweimer@redhat.com>
Date: Mon Dec 23 13:57:55 2024 +0100
support: Add support_record_failure_barrier
This can be used to stop execution after a TEST_COMPARE_BLOB
failure, for example.
diff --git a/support/check.h b/support/check.h
index 8e045dd9c0c36b4c..6b8b70a10961db6c 100644
--- a/support/check.h
+++ b/support/check.h
@@ -207,6 +207,9 @@ void support_record_failure_reset (void);
failures or not. */
int support_record_failure_is_failed (void);
+/* Terminate the process if any failures have been encountered so far. */
+void support_record_failure_barrier (void);
+
__END_DECLS
#endif /* SUPPORT_CHECK_H */
diff --git a/support/support_record_failure.c b/support/support_record_failure.c
index 903da401555fc83a..c0bd489637990b70 100644
--- a/support/support_record_failure.c
+++ b/support/support_record_failure.c
@@ -112,3 +112,13 @@ support_record_failure_is_failed (void)
synchronization for reliable test error reporting anyway. */
return __atomic_load_n (&state->failed, __ATOMIC_RELAXED);
}
+
+void
+support_record_failure_barrier (void)
+{
+ if (__atomic_load_n (&state->failed, __ATOMIC_RELAXED))
+ {
+ puts ("error: exiting due to previous errors");
+ exit (1);
+ }
+}

View File

@ -0,0 +1,158 @@
commit d8f7a79335b0d861c12c42aec94c04cd5bb181e2
Author: Florian Weimer <fweimer@redhat.com>
Date: Tue May 20 19:36:02 2025 +0200
elf: Test case for bug 32976 (CVE-2025-4802)
Check that LD_LIBRARY_PATH is ignored for AT_SECURE statically
linked binaries, using support_capture_subprogram_self_sgid.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Conflicts:
elf/Makefile
(test list differences)
diff --git a/elf/Makefile b/elf/Makefile
index 46a800a4559e0e46..b89ff11754e48fa1 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -260,6 +260,7 @@ tests-static-normal := \
tst-array1-static \
tst-array5-static \
tst-dl-iter-static \
+ tst-dlopen-sgid \
tst-dst-static \
tst-env-setuid \
tst-env-setuid-tunables \
@@ -774,6 +775,7 @@ modules-names = \
tst-dlmopen-gethostbyname-mod \
tst-dlmopen-twice-mod1 \
tst-dlmopen-twice-mod2 \
+ tst-dlopen-sgid-mod \
tst-dlopen-tlsreinitmod1 \
tst-dlopen-tlsreinitmod2 \
tst-dlopen-tlsreinitmod3 \
@@ -2887,3 +2889,5 @@ tst-tls22-mod1.so-no-z-defs = yes
tst-tls22-mod1-gnu2.so-no-z-defs = yes
tst-tls22-mod2.so-no-z-defs = yes
tst-tls22-mod2-gnu2.so-no-z-defs = yes
+
+$(objpfx)tst-dlopen-sgid.out: $(objpfx)tst-dlopen-sgid-mod.so
diff --git a/elf/tst-dlopen-sgid-mod.c b/elf/tst-dlopen-sgid-mod.c
new file mode 100644
index 0000000000000000..5eb79eef485da4c9
--- /dev/null
+++ b/elf/tst-dlopen-sgid-mod.c
@@ -0,0 +1 @@
+/* Opening this object should not succeed. */
diff --git a/elf/tst-dlopen-sgid.c b/elf/tst-dlopen-sgid.c
new file mode 100644
index 0000000000000000..47829a405e90b6b9
--- /dev/null
+++ b/elf/tst-dlopen-sgid.c
@@ -0,0 +1,104 @@
+/* Test case for ignored LD_LIBRARY_PATH in static startug (bug 32976).
+ 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/>. */
+
+#include <dlfcn.h>
+#include <gnu/lib-names.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <support/capture_subprocess.h>
+#include <support/check.h>
+#include <support/support.h>
+#include <support/temp_file.h>
+#include <unistd.h>
+
+/* This is the name of our test object. Use a custom module for
+ testing, so that this object does not get picked up from the system
+ path. */
+static const char dso_name[] = "tst-dlopen-sgid-mod.so";
+
+/* Used to mark the recursive invocation. */
+static const char magic_argument[] = "run-actual-test";
+
+static int
+do_test (void)
+{
+/* Pathname of the directory that receives the shared objects this
+ test attempts to load. */
+ char *libdir = support_create_temp_directory ("tst-dlopen-sgid-");
+
+ /* This is supposed to be ignored and stripped. */
+ TEST_COMPARE (setenv ("LD_LIBRARY_PATH", libdir, 1), 0);
+
+ /* Copy of libc.so.6. */
+ {
+ char *from = xasprintf ("%s/%s", support_objdir_root, LIBC_SO);
+ char *to = xasprintf ("%s/%s", libdir, LIBC_SO);
+ add_temp_file (to);
+ support_copy_file (from, to);
+ free (to);
+ free (from);
+ }
+
+ /* Copy of the test object. */
+ {
+ char *from = xasprintf ("%s/elf/%s", support_objdir_root, dso_name);
+ char *to = xasprintf ("%s/%s", libdir, dso_name);
+ add_temp_file (to);
+ support_copy_file (from, to);
+ free (to);
+ free (from);
+ }
+
+ TEST_COMPARE (support_capture_subprogram_self_sgid (magic_argument), 0);
+
+ free (libdir);
+
+ return 0;
+}
+
+static void
+alternative_main (int argc, char **argv)
+{
+ if (argc == 2 && strcmp (argv[1], magic_argument) == 0)
+ {
+ if (getgid () == getegid ())
+ /* This can happen if the file system is mounted nosuid. */
+ FAIL_UNSUPPORTED ("SGID failed: GID and EGID match (%jd)\n",
+ (intmax_t) getgid ());
+
+ /* Should be removed due to SGID. */
+ TEST_COMPARE_STRING (getenv ("LD_LIBRARY_PATH"), NULL);
+
+ TEST_VERIFY (dlopen (dso_name, RTLD_NOW) == NULL);
+ {
+ const char *message = dlerror ();
+ TEST_COMPARE_STRING (message,
+ "tst-dlopen-sgid-mod.so:"
+ " cannot open shared object file:"
+ " No such file or directory");
+ }
+
+ support_record_failure_barrier ();
+ exit (EXIT_SUCCESS);
+ }
+}
+
+#define PREPARE alternative_main
+#include <support/test-driver.c>

View File

@ -0,0 +1,42 @@
commit 35fc356fa3b4f485bd3ba3114c9f774e5df7d3c2
Author: Florian Weimer <fweimer@redhat.com>
Date: Wed May 21 08:43:32 2025 +0200
elf: Fix subprocess status handling for tst-dlopen-sgid (bug 32987)
This should really move into support_capture_subprogram_self_sgid.
Reviewed-by: Sam James <sam@gentoo.org>
diff --git a/elf/tst-dlopen-sgid.c b/elf/tst-dlopen-sgid.c
index 47829a405e90b6b9..5688b79f2e870b1d 100644
--- a/elf/tst-dlopen-sgid.c
+++ b/elf/tst-dlopen-sgid.c
@@ -26,6 +26,8 @@
#include <support/check.h>
#include <support/support.h>
#include <support/temp_file.h>
+#include <support/test-driver.h>
+#include <sys/wait.h>
#include <unistd.h>
/* This is the name of our test object. Use a custom module for
@@ -66,10 +68,16 @@ do_test (void)
free (from);
}
- TEST_COMPARE (support_capture_subprogram_self_sgid (magic_argument), 0);
-
free (libdir);
+ int status = support_capture_subprogram_self_sgid (magic_argument);
+
+ if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
+ return EXIT_UNSUPPORTED;
+
+ if (!WIFEXITED (status))
+ FAIL_EXIT1 ("Unexpected exit status %d from child process\n", status);
+
return 0;
}

View File

@ -0,0 +1,105 @@
commit 2f769cec448d84a62b7dd0d4ff56978fe22c0cd6
Author: Florian Weimer <fweimer@redhat.com>
Date: Wed May 21 16:47:34 2025 +0200
support: Pick group in support_capture_subprogram_self_sgid if UID == 0
When running as root, it is likely that we can run under any group.
Pick a harmless group from /etc/group in this case.
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c
index 6e6ac8bbb7f64859..755ee13553b3d253 100644
--- a/support/support_capture_subprocess.c
+++ b/support/support_capture_subprocess.c
@@ -21,7 +21,11 @@
#include <errno.h>
#include <fcntl.h>
+#include <grp.h>
+#include <scratch_buffer.h>
+#include <stdio_ext.h>
#include <stdlib.h>
+#include <string.h>
#include <support/check.h>
#include <support/xunistd.h>
#include <support/xsocket.h>
@@ -198,10 +202,48 @@ err:
return status;
}
+/* Returns true if a group with NAME has been found, and writes its
+ GID to *TARGET. */
+static bool
+find_sgid_group (gid_t *target, const char *name)
+{
+ /* Do not use getgrname_r because it does not work in statically
+ linked binaries if the system libc is different. */
+ FILE *fp = fopen ("/etc/group", "rce");
+ if (fp == NULL)
+ return false;
+ __fsetlocking (fp, FSETLOCKING_BYCALLER);
+
+ bool ok = false;
+ struct scratch_buffer buf;
+ scratch_buffer_init (&buf);
+ while (true)
+ {
+ struct group grp;
+ struct group *result = NULL;
+ int status = fgetgrent_r (fp, &grp, buf.data, buf.length, &result);
+ if (status == 0 && result != NULL)
+ {
+ if (strcmp (result->gr_name, name) == 0)
+ {
+ *target = result->gr_gid;
+ ok = true;
+ break;
+ }
+ }
+ else if (errno != ERANGE)
+ break;
+ else if (!scratch_buffer_grow (&buf))
+ break;
+ }
+ scratch_buffer_free (&buf);
+ fclose (fp);
+ return ok;
+}
+
int
support_capture_subprogram_self_sgid (const char *child_id)
{
- gid_t target = 0;
const int count = 64;
gid_t groups[count];
@@ -213,6 +255,7 @@ support_capture_subprogram_self_sgid (const char *child_id)
(intmax_t) getuid ());
gid_t current = getgid ();
+ gid_t target = current;
for (int i = 0; i < ret; ++i)
{
if (groups[i] != current)
@@ -222,9 +265,16 @@ support_capture_subprogram_self_sgid (const char *child_id)
}
}
- if (target == 0)
- FAIL_UNSUPPORTED("Could not find a suitable GID for user %jd\n",
- (intmax_t) getuid ());
+ if (target == current)
+ {
+ /* If running as root, try to find a harmless group for SGID. */
+ if (getuid () != 0
+ || (!find_sgid_group (&target, "nogroup")
+ && !find_sgid_group (&target, "bin")
+ && !find_sgid_group (&target, "daemon")))
+ FAIL_UNSUPPORTED("Could not find a suitable GID for user %jd\n",
+ (intmax_t) getuid ());
+ }
return copy_and_spawn_sgid (child_id, target);
}

View File

@ -0,0 +1,52 @@
commit 6286cca2cb8389dcffec39238a8bf15ffea96396
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Thu Jun 1 07:23:15 2023 -0400
support: Don't fail on fchown when spawning sgid processes
In some cases (e.g. when podman creates user containers), the only other
group assigned to the executing user is nobody and fchown fails with it
because the group is not mapped. Do not fail the test in this case,
instead exit as unsupported.
Reported-by: Frédéric Bérat <fberat@redhat.com>
Tested-by: Frédéric Bérat <fberat@redhat.com>
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c
index 755ee13553b3d253..544636e52eeaee73 100644
--- a/support/support_capture_subprocess.c
+++ b/support/support_capture_subprocess.c
@@ -157,9 +157,18 @@ copy_and_spawn_sgid (const char *child_id, gid_t gid)
p += wrcount;
}
}
- TEST_VERIFY (fchown (outfd, getuid (), gid) == 0);
+
+ bool chowned = false;
+ TEST_VERIFY ((chowned = fchown (outfd, getuid (), gid) == 0)
+ || errno == EPERM);
if (support_record_failure_is_failed ())
goto err;
+ else if (!chowned)
+ {
+ ret = 77;
+ goto err;
+ }
+
TEST_VERIFY (fchmod (outfd, 02750) == 0);
if (support_record_failure_is_failed ())
goto err;
@@ -196,8 +205,10 @@ err:
free (dirname);
}
+ if (ret == 77)
+ FAIL_UNSUPPORTED ("Failed to make sgid executable for test\n");
if (ret != 0)
- FAIL_EXIT1("Failed to make sgid executable for test\n");
+ FAIL_EXIT1 ("Failed to make sgid executable for test\n");
return status;
}

View File

@ -0,0 +1,314 @@
commit 3a3fb2ed83f79100c116c824454095ecfb335ad7
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu May 22 14:36:37 2025 +0200
Fix error reporting (false negatives) in SGID tests
And simplify the interface of support_capture_subprogram_self_sgid.
Use the existing framework for temporary directories (now with
mode 0700) and directory/file deletion. Handle all execution
errors within support_capture_subprogram_self_sgid. In particular,
this includes test failures because the invoked program did not
exit with exit status zero. Existing tests that expect exit
status 42 are adjusted to use zero instead.
In addition, fix callers not to call exit (0) with test failures
pending (which may mask them, especially when running with --direct).
Fixes commit 35fc356fa3b4f485bd3ba3114c9f774e5df7d3c2
("elf: Fix subprocess status handling for tst-dlopen-sgid (bug 32987)").
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Conflicts:
elf/tst-env-setuid.c
(missing commit 11f7e3dd8fed66e0b8740af440cd3151e55a466f
("elf: Add all malloc tunable to unsecvars") downstream)
diff --git a/elf/tst-dlopen-sgid.c b/elf/tst-dlopen-sgid.c
index 5688b79f2e870b1d..8aec52e19fc56aba 100644
--- a/elf/tst-dlopen-sgid.c
+++ b/elf/tst-dlopen-sgid.c
@@ -70,13 +70,7 @@ do_test (void)
free (libdir);
- int status = support_capture_subprogram_self_sgid (magic_argument);
-
- if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
- return EXIT_UNSUPPORTED;
-
- if (!WIFEXITED (status))
- FAIL_EXIT1 ("Unexpected exit status %d from child process\n", status);
+ support_capture_subprogram_self_sgid (magic_argument);
return 0;
}
diff --git a/elf/tst-env-setuid-tunables.c b/elf/tst-env-setuid-tunables.c
index cd4e84364074c613..0ee5416026242c65 100644
--- a/elf/tst-env-setuid-tunables.c
+++ b/elf/tst-env-setuid-tunables.c
@@ -127,10 +127,7 @@ do_test (int argc, char **argv)
if (ret != 0)
exit (1);
-
- /* Special return code to make sure that the child executed all the way
- through. */
- exit (42);
+ return 0;
}
else
{
@@ -149,18 +146,7 @@ do_test (int argc, char **argv)
continue;
}
- int status = support_capture_subprogram_self_sgid (buf);
-
- /* Bail out early if unsupported. */
- if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
- return EXIT_UNSUPPORTED;
-
- if (WEXITSTATUS (status) != 42)
- {
- printf (" [%d] child failed with status %d\n", i,
- WEXITSTATUS (status));
- support_record_failure ();
- }
+ support_capture_subprogram_self_sgid (buf);
}
return 0;
}
diff --git a/elf/tst-env-setuid.c b/elf/tst-env-setuid.c
index 49b5e319e27c2404..0b6e60836ade7958 100644
--- a/elf/tst-env-setuid.c
+++ b/elf/tst-env-setuid.c
@@ -104,20 +104,14 @@ do_test (int argc, char **argv)
if (ret != 0)
exit (1);
- exit (EXIT_SUCCESS);
+ return 0;
}
else
{
if (test_parent () != 0)
exit (1);
- int status = support_capture_subprogram_self_sgid (SETGID_CHILD);
-
- if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
- return EXIT_UNSUPPORTED;
-
- if (!WIFEXITED (status))
- FAIL_EXIT1 ("Unexpected exit status %d from child process\n", status);
+ support_capture_subprogram_self_sgid (SETGID_CHILD);
return 0;
}
diff --git a/stdlib/tst-secure-getenv.c b/stdlib/tst-secure-getenv.c
index 5567c9ae215fd924..cd48c717623628e6 100644
--- a/stdlib/tst-secure-getenv.c
+++ b/stdlib/tst-secure-getenv.c
@@ -57,13 +57,7 @@ do_test (void)
exit (1);
}
- int status = support_capture_subprogram_self_sgid (MAGIC_ARGUMENT);
-
- if (WEXITSTATUS (status) == EXIT_UNSUPPORTED)
- return EXIT_UNSUPPORTED;
-
- if (!WIFEXITED (status))
- FAIL_EXIT1 ("Unexpected exit status %d from child process\n", status);
+ support_capture_subprogram_self_sgid (MAGIC_ARGUMENT);
return 0;
}
@@ -82,6 +76,7 @@ alternative_main (int argc, char **argv)
if (secure_getenv ("PATH") != NULL)
FAIL_EXIT (4, "PATH variable not filtered out\n");
+ support_record_failure_barrier ();
exit (EXIT_SUCCESS);
}
}
diff --git a/support/capture_subprocess.h b/support/capture_subprocess.h
index 4229300d4b0aab29..afec0b14d23be7b1 100644
--- a/support/capture_subprocess.h
+++ b/support/capture_subprocess.h
@@ -41,10 +41,12 @@ struct support_capture_subprocess support_capture_subprocess
struct support_capture_subprocess support_capture_subprogram
(const char *file, char *const argv[]);
-/* Copy the running program into a setgid binary and run it with CHILD_ID
- argument. If execution is successful, return the exit status of the child
- program, otherwise return a non-zero failure exit code. */
-int support_capture_subprogram_self_sgid (const char *child_id);
+/* Copy the running program into a setgid binary and run it with
+ CHILD_ID argument. If the program exits with a non-zero status,
+ exit with that exit status (or status 1 if the program did not exit
+ normally). If the test cannot be performed, exit with
+ EXIT_UNSUPPORTED. */
+void support_capture_subprogram_self_sgid (const char *child_id);
/* Deallocate the subprocess data captured by
support_capture_subprocess. */
diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c
index 544636e52eeaee73..73e3a16ddc63da94 100644
--- a/support/support_capture_subprocess.c
+++ b/support/support_capture_subprocess.c
@@ -31,6 +31,7 @@
#include <support/xsocket.h>
#include <support/xspawn.h>
#include <support/support.h>
+#include <support/temp_file.h>
#include <support/test-driver.h>
static void
@@ -112,105 +113,44 @@ support_capture_subprogram (const char *file, char *const argv[])
/* Copies the executable into a restricted directory, so that we can
safely make it SGID with the TARGET group ID. Then runs the
executable. */
-static int
+static void
copy_and_spawn_sgid (const char *child_id, gid_t gid)
{
- char *dirname = xasprintf ("%s/tst-tunables-setuid.%jd",
- test_dir, (intmax_t) getpid ());
+ char *dirname = support_create_temp_directory ("tst-glibc-sgid-");
char *execname = xasprintf ("%s/bin", dirname);
- int infd = -1;
- int outfd = -1;
- int ret = 1, status = 1;
-
- TEST_VERIFY (mkdir (dirname, 0700) == 0);
- if (support_record_failure_is_failed ())
- goto err;
+ add_temp_file (execname);
- infd = open ("/proc/self/exe", O_RDONLY);
- if (infd < 0)
+ if (access ("/proc/self/exe", R_OK) != 0)
FAIL_UNSUPPORTED ("unsupported: Cannot read binary from procfs\n");
- outfd = open (execname, O_WRONLY | O_CREAT | O_EXCL, 0700);
- TEST_VERIFY (outfd >= 0);
- if (support_record_failure_is_failed ())
- goto err;
-
- char buf[4096];
- for (;;)
- {
- ssize_t rdcount = read (infd, buf, sizeof (buf));
- TEST_VERIFY (rdcount >= 0);
- if (support_record_failure_is_failed ())
- goto err;
- if (rdcount == 0)
- break;
- char *p = buf;
- char *end = buf + rdcount;
- while (p != end)
- {
- ssize_t wrcount = write (outfd, buf, end - p);
- if (wrcount == 0)
- errno = ENOSPC;
- TEST_VERIFY (wrcount > 0);
- if (support_record_failure_is_failed ())
- goto err;
- p += wrcount;
- }
- }
+ support_copy_file ("/proc/self/exe", execname);
- bool chowned = false;
- TEST_VERIFY ((chowned = fchown (outfd, getuid (), gid) == 0)
- || errno == EPERM);
- if (support_record_failure_is_failed ())
- goto err;
- else if (!chowned)
- {
- ret = 77;
- goto err;
- }
+ if (chown (execname, getuid (), gid) != 0)
+ FAIL_UNSUPPORTED ("cannot change group of \"%s\" to %jd: %m",
+ execname, (intmax_t) gid);
- TEST_VERIFY (fchmod (outfd, 02750) == 0);
- if (support_record_failure_is_failed ())
- goto err;
- TEST_VERIFY (close (outfd) == 0);
- if (support_record_failure_is_failed ())
- goto err;
- TEST_VERIFY (close (infd) == 0);
- if (support_record_failure_is_failed ())
- goto err;
+ if (chmod (execname, 02750) != 0)
+ FAIL_UNSUPPORTED ("cannot make \"%s\" SGID: %m ", execname);
/* We have the binary, now spawn the subprocess. Avoid using
support_subprogram because we only want the program exit status, not the
contents. */
- ret = 0;
- infd = outfd = -1;
char * const args[] = {execname, (char *) child_id, NULL};
+ int status = support_subprogram_wait (args[0], args);
- status = support_subprogram_wait (args[0], args);
+ free (execname);
+ free (dirname);
-err:
- if (outfd >= 0)
- close (outfd);
- if (infd >= 0)
- close (infd);
- if (execname != NULL)
- {
- unlink (execname);
- free (execname);
- }
- if (dirname != NULL)
+ if (WIFEXITED (status))
{
- rmdir (dirname);
- free (dirname);
+ if (WEXITSTATUS (status) == 0)
+ return;
+ else
+ exit (WEXITSTATUS (status));
}
-
- if (ret == 77)
- FAIL_UNSUPPORTED ("Failed to make sgid executable for test\n");
- if (ret != 0)
- FAIL_EXIT1 ("Failed to make sgid executable for test\n");
-
- return status;
+ else
+ FAIL_EXIT1 ("subprogram failed with status %d", status);
}
/* Returns true if a group with NAME has been found, and writes its
@@ -252,7 +192,7 @@ find_sgid_group (gid_t *target, const char *name)
return ok;
}
-int
+void
support_capture_subprogram_self_sgid (const char *child_id)
{
const int count = 64;
@@ -287,7 +227,7 @@ support_capture_subprogram_self_sgid (const char *child_id)
(intmax_t) getuid ());
}
- return copy_and_spawn_sgid (child_id, target);
+ copy_and_spawn_sgid (child_id, target);
}
void

View File

@ -0,0 +1,193 @@
commit 9f0d2c0ee6c728643fcf9a4879e9f20f5e45ce5f
Author: Arjun Shankar <arjun@redhat.com>
Date: Fri Oct 18 16:03:25 2024 +0200
libio: Fix a deadlock after fork in popen
popen modifies its file handler book-keeping under a lock that wasn't
being taken during fork. This meant that a concurrent popen and fork
could end up copying the lock in a "locked" state into the fork child,
where subsequently calling popen would lead to a deadlock due to the
already (spuriously) held lock.
This commit fixes the deadlock by appropriately taking the lock before
fork, and releasing/resetting it in the parent/child after the fork.
A new test for concurrent popen and fork is also added. It consistently
hangs (and therefore fails via timeout) without the fix applied.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
diff --git a/libio/Makefile b/libio/Makefile
index 8b2d8aaae563788b..38fc72cb8eff193c 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -100,6 +100,7 @@ tests = \
tst-mmap-offend \
tst-mmap-setvbuf \
tst-mmap2-eofsync \
+ tst-popen-fork \
tst-popen1 \
tst-setvbuf1 \
tst-sprintf-chk-ub \
diff --git a/libio/iopopen.c b/libio/iopopen.c
index 6b04222c24aaee92..a966e6dcee142242 100644
--- a/libio/iopopen.c
+++ b/libio/iopopen.c
@@ -60,6 +60,26 @@ unlock (void *not_used)
}
#endif
+/* These lock/unlock/resetlock functions are used during fork. */
+
+void
+_IO_proc_file_chain_lock (void)
+{
+ _IO_lock_lock (proc_file_chain_lock);
+}
+
+void
+_IO_proc_file_chain_unlock (void)
+{
+ _IO_lock_unlock (proc_file_chain_lock);
+}
+
+void
+_IO_proc_file_chain_resetlock (void)
+{
+ _IO_lock_init (proc_file_chain_lock);
+}
+
/* POSIX states popen shall ensure that any streams from previous popen()
calls that remain open in the parent process should be closed in the new
child process.
diff --git a/libio/libioP.h b/libio/libioP.h
index fbe58fc10fb694d0..50570f89de5a7010 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -429,6 +429,12 @@ libc_hidden_proto (_IO_list_resetlock)
extern void _IO_enable_locks (void) __THROW;
libc_hidden_proto (_IO_enable_locks)
+/* Functions for operating popen's proc_file_chain_lock during fork. */
+
+extern void _IO_proc_file_chain_lock (void) __THROW attribute_hidden;
+extern void _IO_proc_file_chain_unlock (void) __THROW attribute_hidden;
+extern void _IO_proc_file_chain_resetlock (void) __THROW attribute_hidden;
+
/* Default jumptable functions. */
extern int _IO_default_underflow (FILE *) __THROW;
diff --git a/libio/tst-popen-fork.c b/libio/tst-popen-fork.c
new file mode 100644
index 0000000000000000..1df30fc6c0a3f583
--- /dev/null
+++ b/libio/tst-popen-fork.c
@@ -0,0 +1,80 @@
+/* Test concurrent popen and fork.
+ Copyright (C) 2024 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/>. */
+
+#include <stdio.h>
+#include <stdatomic.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#include <support/check.h>
+#include <support/xthread.h>
+#include <support/xunistd.h>
+
+static void
+popen_and_pclose (void)
+{
+ FILE *f = popen ("true", "r");
+ TEST_VERIFY_EXIT (f != NULL);
+ pclose (f);
+ return;
+}
+
+static atomic_bool done = ATOMIC_VAR_INIT (0);
+
+static void *
+popen_and_pclose_forever (__attribute__ ((unused))
+ void *arg)
+{
+ while (!atomic_load_explicit (&done, memory_order_acquire))
+ popen_and_pclose ();
+ return NULL;
+}
+
+static int
+do_test (void)
+{
+
+ /* Repeatedly call popen in a loop during the entire test. */
+ pthread_t t = xpthread_create (NULL, popen_and_pclose_forever, NULL);
+
+ /* Repeatedly fork off and reap child processes one-by-one.
+ Each child calls popen once, then exits, leading to the possibility
+ that a child forks *during* our own popen call, thus inheriting any
+ intermediate popen state, possibly including lock state(s). */
+ for (int i = 0; i < 100; i++)
+ {
+ int cpid = xfork ();
+
+ if (cpid == 0)
+ {
+ popen_and_pclose ();
+ _exit (0);
+ }
+ else
+ xwaitpid (cpid, NULL, 0);
+ }
+
+ /* Stop calling popen. */
+ atomic_store_explicit (&done, 1, memory_order_release);
+ xpthread_join (t);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/posix/fork.c b/posix/fork.c
index 890b806eb48cb75a..5a5baf63aa971b43 100644
--- a/posix/fork.c
+++ b/posix/fork.c
@@ -62,6 +62,7 @@ __libc_fork (void)
call_function_static_weak (__nss_database_fork_prepare_parent,
&nss_database_data);
+ _IO_proc_file_chain_lock ();
_IO_list_lock ();
/* Acquire malloc locks. This needs to come last because fork
@@ -92,6 +93,7 @@ __libc_fork (void)
/* Reset locks in the I/O code. */
_IO_list_resetlock ();
+ _IO_proc_file_chain_resetlock ();
call_function_static_weak (__nss_database_fork_subprocess,
&nss_database_data);
@@ -121,6 +123,7 @@ __libc_fork (void)
/* We execute this even if the 'fork' call failed. */
_IO_list_unlock ();
+ _IO_proc_file_chain_unlock ();
}
/* Run the handlers registered for the parent. */

View File

@ -0,0 +1,26 @@
commit 6a290b2895b77be839fcb7c44a6a9879560097ad
Author: Arjun Shankar <arjun@redhat.com>
Date: Fri Oct 25 09:33:45 2024 +0200
libio: Correctly link tst-popen-fork against libpthread
tst-popen-fork failed to build for Hurd due to not being linked with
libpthread. This commit fixes that.
Tested with build-many-glibcs.py for i686-gnu.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
diff --git a/libio/Makefile b/libio/Makefile
index 38fc72cb8eff193c..570fa1a02b3565c8 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -125,6 +125,8 @@ tests = \
tst_wscanf \
# tests
+$(objpfx)tst-popen-fork: $(shared-thread-library)
+
tests-internal = tst-vtables tst-vtables-interposed
ifeq (yes,$(build-shared))

View File

@ -0,0 +1,181 @@
commit aa3d7bd5299b33bffc118aa618b59bfa66059bcb
Author: Florian Weimer <fweimer@redhat.com>
Date: Thu Feb 13 21:56:52 2025 +0100
elf: Keep using minimal malloc after early DTV resize (bug 32412)
If an auditor loads many TLS-using modules during startup, it is
possible to trigger DTV resizing. Previously, the DTV was marked
as allocated by the main malloc afterwards, even if the minimal
malloc was still in use. With this change, _dl_resize_dtv marks
the resized DTV as allocated with the minimal malloc.
The new test reuses TLS-using modules from other auditing tests.
Reviewed-by: DJ Delorie <dj@redhat.com>
diff --git a/elf/Makefile b/elf/Makefile
index b89ff11754e48fa1..41adea8d1c6d13ca 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -363,6 +363,7 @@ tests += \
tst-align2 \
tst-audit-tlsdesc \
tst-audit-tlsdesc-dlopen \
+ tst-audit-tlsdesc-dlopen2 \
tst-audit1 \
tst-audit2 \
tst-audit8 \
@@ -744,6 +745,7 @@ modules-names = \
tst-auditmanymod8 \
tst-auditmanymod9 \
tst-auditmod-tlsdesc \
+ tst-auditmod-tlsdesc2 \
tst-auditmod1 \
tst-auditmod9a \
tst-auditmod9b \
@@ -2773,6 +2775,9 @@ $(objpfx)tst-audit-tlsdesc.out: $(objpfx)tst-auditmod-tlsdesc.so
tst-audit-tlsdesc-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
$(objpfx)tst-audit-tlsdesc-dlopen.out: $(objpfx)tst-auditmod-tlsdesc.so
tst-audit-tlsdesc-dlopen-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc.so
+$(objpfx)tst-audit-tlsdesc-dlopen2.out: $(objpfx)tst-auditmod-tlsdesc2.so \
+ $(patsubst %, $(objpfx)%.so, $(tlsmod17a-modules))
+tst-audit-tlsdesc-dlopen2-ENV = LD_AUDIT=$(objpfx)tst-auditmod-tlsdesc2.so
$(objpfx)tst-dlmopen-twice.out: \
$(objpfx)tst-dlmopen-twice-mod1.so \
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index 99323db9ca6f76b7..1b1bc4292eb24747 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -534,6 +534,13 @@ _dl_resize_dtv (dtv_t *dtv, size_t max_modid)
if (newp == NULL)
oom ();
memcpy (newp, &dtv[-1], (2 + oldsize) * sizeof (dtv_t));
+#ifdef SHARED
+ /* Auditors can trigger a DTV resize event while the full malloc
+ is not yet in use. Mark the new DTV allocation as the
+ initial allocation. */
+ if (!__rtld_malloc_is_complete ())
+ GL(dl_initial_dtv) = &newp[1];
+#endif
}
else
{
diff --git a/elf/tst-audit-tlsdesc-dlopen2.c b/elf/tst-audit-tlsdesc-dlopen2.c
new file mode 100644
index 0000000000000000..7ba2c4129a9bcc53
--- /dev/null
+++ b/elf/tst-audit-tlsdesc-dlopen2.c
@@ -0,0 +1,46 @@
+/* Loading TLS-using modules from auditors (bug 32412). Main program.
+ Copyright (C) 2021-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/>. */
+
+#include <support/xdlfcn.h>
+#include <stdio.h>
+
+static int
+do_test (void)
+{
+ puts ("info: start of main program");
+
+ /* Load TLS-using modules, to trigger DTV resizing. The dynamic
+ linker will load them again (requiring their own TLS) because the
+ dlopen calls from the auditor were in the auditing namespace. */
+ for (int i = 1; i <= 19; ++i)
+ {
+ char dso[30];
+ snprintf (dso, sizeof (dso), "tst-tlsmod17a%d.so", i);
+ char sym[30];
+ snprintf (sym, sizeof(sym), "tlsmod17a%d", i);
+
+ void *handle = xdlopen (dso, RTLD_LAZY);
+ int (*func) (void) = xdlsym (handle, sym);
+ /* Trigger TLS allocation. */
+ func ();
+ }
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/elf/tst-auditmod-tlsdesc2.c b/elf/tst-auditmod-tlsdesc2.c
new file mode 100644
index 0000000000000000..50275cd34d1219c6
--- /dev/null
+++ b/elf/tst-auditmod-tlsdesc2.c
@@ -0,0 +1,59 @@
+/* Loading TLS-using modules from auditors (bug 32412). Audit module.
+ Copyright (C) 2021-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/>. */
+
+#include <dlfcn.h>
+#include <link.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+
+unsigned int
+la_version (unsigned int version)
+{
+ /* Open some modules, to trigger DTV resizing before the switch to
+ the main malloc. */
+ for (int i = 1; i <= 19; ++i)
+ {
+ char dso[30];
+ snprintf (dso, sizeof (dso), "tst-tlsmod17a%d.so", i);
+ char sym[30];
+ snprintf (sym, sizeof(sym), "tlsmod17a%d", i);
+
+ void *handle = dlopen (dso, RTLD_LAZY);
+ if (handle == NULL)
+ {
+ printf ("error: dlmopen from auditor: %s\n", dlerror ());
+ fflush (stdout);
+ _exit (1);
+ }
+ int (*func) (void) = dlsym (handle, sym);
+ if (func == NULL)
+ {
+ printf ("error: dlsym from auditor: %s\n", dlerror ());
+ fflush (stdout);
+ _exit (1);
+ }
+ /* Trigger TLS allocation. */
+ func ();
+ }
+
+ puts ("info: TLS-using modules loaded from auditor");
+ fflush (stdout);
+
+ return LAV_CURRENT;
+}

View File

@ -157,7 +157,7 @@ end \
Summary: The GNU libc libraries
Name: glibc
Version: %{glibcversion}
Release: 168%{?dist}.14
Release: 168%{?dist}.19
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
# libraries.
@ -1166,6 +1166,18 @@ Patch858: glibc-RHEL-84306-15.patch
Patch859: glibc-RHEL-83982-1.patch
Patch860: glibc-RHEL-83982-2.patch
Patch861: glibc-RHEL-83982-3.patch
Patch862: glibc-RHEL-92690-1.patch
Patch863: glibc-RHEL-92690-2.patch
Patch864: glibc-RHEL-92690-3.patch
Patch865: glibc-RHEL-92690-4.patch
Patch866: glibc-RHEL-92690-5.patch
Patch867: glibc-RHEL-92690-6.patch
Patch868: glibc-RHEL-92690-7.patch
Patch869: glibc-RHEL-92690-8.patch
Patch870: glibc-RHEL-71583.patch
Patch871: glibc-RHEL-93665-1.patch
Patch872: glibc-RHEL-93665-2.patch
Patch873: glibc-RHEL-93877.patch
##############################################################################
# Continued list of core "glibc" package information:
@ -3159,6 +3171,21 @@ update_gconv_modules_cache ()
%endif
%changelog
* Wed May 28 2025 Florian Weimer <fweimer@redhat.com> - 2.34-168.19
- elf: Keep using minimal malloc after early DTV resize (RHEL-93877)
* Wed May 28 2025 Frédéric Bérat <fberat@redhat.com> - 2.34-168.18
- Fix deadlock in popen after multi-threaded fork (RHEL-93665)
* Tue May 27 2025 Florian Weimer <fweimer@redhat.com> - 2.34-168.17
- x86: Avoid integer truncation with large cache sizes (RHEL-71583)
* Thu May 22 2025 Florian Weimer <fweimer@redhat.com> - 2.34-168.16
- SGID test enhancements (RHEL-92690)
* Wed May 21 2025 Florian Weimer <fweimer@redhat.com> - 2.34-168.15
- CVE-2025-4802: static setuid dlopen may search LD_LIBRARY_PATH (RHEL-92690)
* Tue Apr 8 2025 Florian Weimer <fweimer@redhat.com> - 2.34-168.14
- Increase reliability of stdio-common/tst-setvbuf2 (RHEL-83982)