Bug#1109399: marked as done (unblock: glibc/2.41-10 (pre-approval)) (2/
From
Debian Bug Tracking System@21:1/5 to
All on Mon Jul 21 23:20:01 2025
[continued from previous message]
+ static void
+@@ -109,111 +114,88 @@ 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 int
-copy_and_spawn_sgid (char *child_id, gid_t gid)
++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 ());
-@@ -182,7 +182,7 @@ copy_and_spawn_sgid (char *child_id, gid_t gid)
- ret = 0;
- infd = outfd = -1;
+- 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, child_id, NULL};
+ char * const args[] = {execname, (char *) child_id, NULL};
-
- status = support_subprogram_wait (args[0], args);
-
-@@ -211,7 +211,7 @@ err:
++ 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)
++ if (WIFEXITED (status))
+ {
+- unlink (execname);
+- free (execname);
++ if (WEXITSTATUS (status) == 0)
++ return;
++ else
++ exit (WEXITSTATUS (status));
+ }
+- if (dirname != NULL)
++ else
++ FAIL_EXIT1 ("subprogram failed with status %d", 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)
+ {
+- rmdir (dirname);
+- free (dirname);
++ 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;
+ }
+-
+- 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;
++ scratch_buffer_free (&buf);
++ fclose (fp);
++ return ok;
}
- int
+-int
-support_capture_subprogram_self_sgid (char *child_id)
++void
+support_capture_subprogram_self_sgid (const char *child_id)
{
- gid_t target = 0;
+- gid_t target = 0;
const int count = 64;
+ gid_t groups[count];
+
+@@ -225,6 +207,7 @@ support_capture_subprogram_self_sgid (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)
+@@ -234,11 +217,18 @@ support_capture_subprogram_self_sgid (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);
++ copy_and_spawn_sgid (child_id, target);
+ }
+
+ void
diff --git a/sysdeps/aarch64/fpu/asinh_sve.c b/sysdeps/aarch64/fpu/asinh_sve.c
index 0889f79dbb..ff6b71390c 100644
--- a/sysdeps/aarch64/fpu/asinh_sve.c
@@ -4731,10 +5026,34 @@ index a30892f080..dcc3e0883b 100644
return lazy;
}
diff --git a/sysdeps/sparc/sparc32/start.S b/sysdeps/sparc/sparc32/start.S -index 694b020ce0..cef7c96cac 100644
+index 694b020ce0..8393760da6 100644
--- a/sysdeps/sparc/sparc32/start.S
+++ b/sysdeps/sparc/sparc32/start.S
-@@ -73,6 +73,10 @@ _start:
+@@ -35,6 +35,7 @@
+
+ #include <sysdep.h>
+
++#define FRAME_SIZE 104
+
+ .section ".text"
+ .align 4
+@@ -48,12 +49,12 @@ _start:
+ /* Terminate the stack frame, and reserve space for functions to
+ drop their arguments. */
+ mov %g0, %fp
+- sub %sp, 6*4, %sp
++ sub %sp, FRAME_SIZE, %sp
+
+ /* Extract the arguments and environment as encoded on the stack. The
+ argument info starts after one register window (16 words) past the SP. */
+- ld [%sp+22*4], %o1
+- add %sp, 23*4, %o2
++ ld [%sp+168], %o1
++ add %sp, 172, %o2
+
+ /* Load the addresses of the user entry points. */
+ #ifndef PIC
+@@ -73,6 +74,10 @@ _start:
be NULL. */
mov %g1, %o5
diff --git a/debian/patches/hurd-i386/local-pthread_once-2.42.diff b/debian/patches/hurd-i386/local-pthread_once-2.42.diff
new file mode 100644
index 00000000..716ebb08
--- /dev/null
+++ b/debian/patches/hurd-i386/local-pthread_once-2.42.diff
@@ -0,0 +1,52 @@
+Note: Keep the 2.41 symbol until we rebuild packages against the 2.42
+symbol.
+
+Index: glibc-upstream/sysdeps/htl/pt-once.c +===================================================================
+--- glibc-upstream.orig/sysdeps/htl/pt-once.c
++++ glibc-upstream/sysdeps/htl/pt-once.c
+@@ -58,5 +58,8 @@ libc_hidden_def (__pthread_once)
+ versioned_symbol (libc, __pthread_once, pthread_once, GLIBC_2_42);
+
+ #if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_12, GLIBC_2_42)
++compat_symbol (libpthread, __pthread_once, pthread_once, GLIBC_2_41); ++#endif
++#if OTHER_SHLIB_COMPAT (libpthread, GLIBC_2_12, GLIBC_2_42)
+ compat_symbol (libpthread, __pthread_once, pthread_once, GLIBC_2_12);
+ #endif
+Index: glibc-upstream/sysdeps/mach/hurd/i386/libc.abilist +===================================================================
+--- glibc-upstream.orig/sysdeps/mach/hurd/i386/libc.abilist
++++ glibc-upstream/sysdeps