• 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