Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian....@packages.debian.org
Usertags: pu
X-Debbugs-Cc: gl...@packages.debian.org, debian-b...@lists.debian.org
Control: affects -1 + src:glibc

[ Reason ]
The upstream stable branch got a few fixes during the bookworm freeze
period, and this update pulls them into the debian package. In short:
 - Fix a buffer overflow and memory corruption in the gmon
   functionality.
 - Fix a deadlock in getaddrinfo() and system() functions
 - Fix y2038 support in strftime on 32-bit architectures.
 - Fix possible segmentation fault in applications using sgetsgent()
   when /etc/gshadow contains very long lines
 - Fix support for old C90 compilers.

In addition this include a Slovak translation update fixing typos, that
also arrived during the bookworm freeze.

[ Impact ]
In case the update isn't approved, systems will be left with the above
issues which are not critical but can affect some applications.

[ Tests ]
The upstream fixes come with additional tests, which represent a
significant part of the diff.

[ Risks ]
The changes to do not affect critical part of the library, and come with
additional tests. The upstream changes have been in some distribution
for a few months and in experimental for more than a month, and the
translation changes in experimental for more than 3 weeks. All of them
are in sid for more than ten days.

[ 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 (old)stable
  [x] the issue is verified as fixed in unstable

[ Changes ]
Please find below the changelog with additional explanations:

* debian/patches/git-updates.diff: update from upstream stable branch:
  - Affecting bookworm release architectures:
    - Improve mcount overflow handling in gmon.
    - Fix a buffer overflow in gmon (CVE-2023-0687).
    - Fix a memory corruption when incorrectly calling gmon functions
      repeatedly on in wrong order.

    => Those are three security issues affecting the gmon feature of
    glibc, one of them has a CVE entry, but it is disputed. The binaries
    we ship in packages are not gmon enabled, but users might do that
    and use them in production, so it's better to fix them.  More
    details can be found on the upstream BTS:
    https://sourceware.org/bugzilla/show_bug.cgi?id=27576
    https://sourceware.org/bugzilla/show_bug.cgi?id=29444
    https://sourceware.org/bugzilla/show_bug.cgi?id=30101

    - Fix a deadlock in getaddrinfo (__check_pf) with deferred cancellation.

    => This fixes a deadlock that can happen in some rare cases
    involving thread cancellation. It is known to affect zookeeper,
    however it is not clear if it can be reproduced with the Debian
    package. More details can be found on the upstream BTS:
    https://sourceware.org/bugzilla/show_bug.cgi?id=20975

    - Fix y2038 support in strftime on 32-bit architectures.

    => This fixes the %s format specification of strftime to return the
    correct string after y2038 instead of failing and returning -1 on
    32-bit architectures when compiling with -D_TIME_BITS=64. There are
    very few packages building that way yet, but coreutils is one of
    them and is likely affected. More details can be found on the
    upstream BTS:
    https://sourceware.org/bugzilla/show_bug.cgi?id=30053

    - Fix corner case parsing of /etc/gshadow which can return bad pointers
      causing segfaults in applications.

    => This fixes the parsing of /etc/gshadow when it contains very long
    lines, and causes sgetsgent() to not return any data while still
    indicating success. This can cause a segmentation fault in
    applications using this function. More details can be found on the
    upstream BTS: https://sourceware.org/bugzilla/show_bug.cgi?id=30151

    - Fix a deadlock in system() when called concurrently from multiple
      threads.
    
    => This fix an issue when system() is called from multiple threads.
    While the upstream BTS contains a reproducer, it is not clear if it
    is affect more than custom code or if Debian packages are affected.
    More details can be found on the upstream BTS:
    https://sourceware.org/bugzilla/show_bug.cgi?id=30163

    - cdefs: limit definition of fortification macros to __FORTIFY_LEVEL > 0
      to support old C90 compilers.

    => This fixes the glibc headers to correctly support for old C90
    compilers that user might use on their system. It's not clear if we
    ship such a compiler as a Debian package though.

  - Not affecting bookworm release architectures:
    - Fix LFS POSIX lock constants for powerpc64.
    - Fix GL(dl_phdr) and GL(dl_phnum) for static builds.  Closes: #1028200.
  - Not affecting debian architectures:
    - Fix LFS POSIX lock constants on 32 bit arch with 64 bit default
      time_t.

  => The above fixes are fixing upstream which do not concern bookworm
  release architectures, and there is no stable for debian-ports
  architectures. However it doesn't make sense to exclude the
  corresponding changes, and backport fixes one by one instead of using
  the upstream branch.

  - No change in the generated code:
    - Fix asm constraints in amd64 version of feraiseexcept (bug not visible
      with GCC 12).

  => This is a two lines fix patch to fix an issue with GCC 13, but it
  doesn't affect glibc build with GCC 12.

* debian/po/sk.po: Fix typos in the Slovak translation.

=> The above change fixes some typos introduced in the Slovak
translation. It's not a full rewrite of the translation nor a new
translation.

[ Other info ]
debian-boot is in Cc: as glibc has one udeb.
diff --git a/debian/changelog b/debian/changelog
index d67a3e5d..d40a0111 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,35 @@
+glibc (2.36-9+deb12u1) bookworm; urgency=medium
+
+  [ Aurelien Jarno ]
+  * debian/patches/git-updates.diff: update from upstream stable branch:
+    - Affecting bookworm release architectures:
+      - Improve mcount overflow handling in gmon.
+      - Fix a buffer overflow in gmon (CVE-2023-0687).
+      - Fix a memory corruption when incorrectly calling gmon functions
+        repeatedly on in wrong order.
+      - Fix a deadlock in getaddrinfo (__check_pf) with deferred cancellation.
+      - Fix y2038 support in strftime on 32-bit architectures.
+      - Fix corner case parsing of /etc/gshadow which can return bad pointers
+        causing segfaults in applications.
+      - Fix a deadlock in system() when called concurrently from multiple
+        threads.
+      - cdefs: limit definition of fortification macros to __FORTIFY_LEVEL > 0
+        to support old C90 compilers.
+    - Not affecting bookworm release architectures:
+      - Fix LFS POSIX lock constants for powerpc64.
+      - Fix GL(dl_phdr) and GL(dl_phnum) for static builds.  Closes: #1028200.
+    - Not affecting debian architectures:
+      - Fix LFS POSIX lock constants on 32 bit arch with 64 bit default
+        time_t.
+    - No change in the generated code:
+      - Fix asm constraints in amd64 version of feraiseexcept (bug not visible
+        with GCC 12).
+
+  [ Andrej Shadura ]
+  * debian/po/sk.po: Fix typos in the Slovak translation.
+
+ -- Aurelien Jarno <aure...@debian.org>  Thu, 22 Jun 2023 19:33:59 +0200
+
 glibc (2.36-9) unstable; urgency=medium
 
   [ Aurelien Jarno ]
diff --git a/debian/patches/git-updates.diff b/debian/patches/git-updates.diff
index 0d3d0800..9203223b 100644
--- a/debian/patches/git-updates.diff
+++ b/debian/patches/git-updates.diff
@@ -68,10 +68,10 @@ index d1e139d03c..09c0cf8357 100644
  else                                          # -s
  verbose       :=
 diff --git a/NEWS b/NEWS
-index f61e521fc8..8c79e83b77 100644
+index f61e521fc8..9f6b48b63d 100644
 --- a/NEWS
 +++ b/NEWS
-@@ -5,6 +5,54 @@ See the end for copying conditions.
+@@ -5,6 +5,65 @@ See the end for copying conditions.
  Please send GNU C library bug reports via <https://sourceware.org/bugzilla/>
  using `glibc' in the "product" field.
  
@@ -94,8 +94,13 @@ index f61e521fc8..8c79e83b77 100644
 +The following bugs are resolved with this release:
 +
 +  [12154] Do not fail DNS resolution for CNAMEs which are not host names
++  [20975] Deferred cancellation triggers in __check_pf and looses lock 
leading to deadlock
 +  [24816] Fix tst-nss-files-hosts-long on single-stack hosts
++  [27576] gmon: improve mcount overflow handling
 +  [28846] CMSG_NXTHDR may trigger -Wstrict-overflow warning
++  [29444] gmon: Fix allocated buffer overflow (bug 29444)
++  [29864] libc: __libc_start_main() should obtain program headers
++    address (_dl_phdr) from the auxv, not the ELF header.
 +  [29305] Conserve NSS buffer space during DNS packet parsing
 +  [29402] nscd: nscd: No such file or directory
 +  [29415] nscd: Fix netlink cache invalidation if epoll is used
@@ -122,6 +127,12 @@ index f61e521fc8..8c79e83b77 100644
 +  [29771] Restore IPC_64 support in sysvipc *ctl functions
 +  [29776] elf/tst-tlsopt-powerpc fails when compiled with -mcpu=power10
 +  [29951] time: Set daylight to 1 for matching DST/offset change
++  [30053] time: strftime %s returns -1 after 2038 on 32 bits systems
++  [30101] gmon: fix memory corruption issues
++  [30151] gshadow: Matching sgetsgent, sgetsgent_r ERANGE handling
++  [30163] posix: Fix system blocks SIGCHLD erroneously
++  [30305] x86_64: Fix asm constraints in feraiseexcept
++  [30477] libc: [RISCV]: time64 does not work on riscv32
 +
  Version 2.36
  
@@ -189,6 +200,75 @@ index 2b99dea33b..aac8c49b00 100644
    return __cmsg;
  }
  #endif        /* Use `extern inline'.  */
+diff --git a/csu/libc-start.c b/csu/libc-start.c
+index 543560f36c..bfeee6d851 100644
+--- a/csu/libc-start.c
++++ b/csu/libc-start.c
+@@ -262,28 +262,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** 
MAIN_AUXVEC_DECL),
+   }
+ #  endif
+   _dl_aux_init (auxvec);
+-  if (GL(dl_phdr) == NULL)
+ # endif
+-    {
+-      /* Starting from binutils-2.23, the linker will define the
+-         magic symbol __ehdr_start to point to our own ELF header
+-         if it is visible in a segment that also includes the phdrs.
+-         So we can set up _dl_phdr and _dl_phnum even without any
+-         information from auxv.  */
+-
+-      extern const ElfW(Ehdr) __ehdr_start
+-# if BUILD_PIE_DEFAULT
+-      __attribute__ ((visibility ("hidden")));
+-# else
+-      __attribute__ ((weak, visibility ("hidden")));
+-      if (&__ehdr_start != NULL)
+-# endif
+-        {
+-          assert (__ehdr_start.e_phentsize == sizeof *GL(dl_phdr));
+-          GL(dl_phdr) = (const void *) &__ehdr_start + __ehdr_start.e_phoff;
+-          GL(dl_phnum) = __ehdr_start.e_phnum;
+-        }
+-    }
+ 
+   __tunables_init (__environ);
+ 
+diff --git a/csu/libc-tls.c b/csu/libc-tls.c
+index 0a216c5502..7fdf7cd7a8 100644
+--- a/csu/libc-tls.c
++++ b/csu/libc-tls.c
+@@ -118,19 +118,18 @@ __libc_setup_tls (void)
+   __tls_pre_init_tp ();
+ 
+   /* Look through the TLS segment if there is any.  */
+-  if (_dl_phdr != NULL)
+-    for (phdr = _dl_phdr; phdr < &_dl_phdr[_dl_phnum]; ++phdr)
+-      if (phdr->p_type == PT_TLS)
+-      {
+-        /* Remember the values we need.  */
+-        memsz = phdr->p_memsz;
+-        filesz = phdr->p_filesz;
+-        initimage = (void *) phdr->p_vaddr + main_map->l_addr;
+-        align = phdr->p_align;
+-        if (phdr->p_align > max_align)
+-          max_align = phdr->p_align;
+-        break;
+-      }
++  for (phdr = _dl_phdr; phdr < &_dl_phdr[_dl_phnum]; ++phdr)
++    if (phdr->p_type == PT_TLS)
++      {
++      /* Remember the values we need.  */
++      memsz = phdr->p_memsz;
++      filesz = phdr->p_filesz;
++      initimage = (void *) phdr->p_vaddr + main_map->l_addr;
++      align = phdr->p_align;
++      if (phdr->p_align > max_align)
++        max_align = phdr->p_align;
++      break;
++      }
+ 
+   /* Calculate the size of the static TLS surplus, with 0 auditors.  */
+   _dl_tls_static_surplus_init (0);
 diff --git a/dlfcn/dlopen.c b/dlfcn/dlopen.c
 index 2696dde4b1..9b07b4e132 100644
 --- a/dlfcn/dlopen.c
@@ -203,7 +283,7 @@ index 2696dde4b1..9b07b4e132 100644
  
  void *
 diff --git a/elf/Makefile b/elf/Makefile
-index fd77d0c7c8..72178d33ff 100644
+index fd77d0c7c8..48788fcdb8 100644
 --- a/elf/Makefile
 +++ b/elf/Makefile
 @@ -374,6 +374,8 @@ tests += \
@@ -223,7 +303,15 @@ index fd77d0c7c8..72178d33ff 100644
    tst-dlopenfail \
    tst-dlopenfail-2 \
    tst-dlopenrpath \
-@@ -765,6 +768,8 @@ modules-names += \
+@@ -631,6 +634,7 @@ ifeq ($(run-built-tests),yes)
+ tests-special += \
+   $(objpfx)noload-mem.out \
+   $(objpfx)tst-ldconfig-X.out \
++  $(objpfx)tst-ldconfig-p.out \
+   $(objpfx)tst-leaks1-mem.out \
+   $(objpfx)tst-rtld-help.out \
+   # tests-special
+@@ -765,6 +769,8 @@ modules-names += \
    tst-alignmod3 \
    tst-array2dep \
    tst-array5dep \
@@ -232,7 +320,7 @@ index fd77d0c7c8..72178d33ff 100644
    tst-audit11mod1 \
    tst-audit11mod2 \
    tst-audit12mod1 \
-@@ -798,6 +803,7 @@ modules-names += \
+@@ -798,6 +804,7 @@ modules-names += \
    tst-auditmanymod7 \
    tst-auditmanymod8 \
    tst-auditmanymod9 \
@@ -240,7 +328,7 @@ index fd77d0c7c8..72178d33ff 100644
    tst-auditmod1 \
    tst-auditmod9a \
    tst-auditmod9b \
-@@ -834,6 +840,8 @@ modules-names += \
+@@ -834,6 +841,8 @@ modules-names += \
    tst-dlmopen1mod \
    tst-dlmopen-dlerror-mod \
    tst-dlmopen-gethostbyname-mod \
@@ -249,7 +337,7 @@ index fd77d0c7c8..72178d33ff 100644
    tst-dlopenfaillinkmod \
    tst-dlopenfailmod1 \
    tst-dlopenfailmod2 \
-@@ -990,23 +998,8 @@ modules-names += tst-gnu2-tls1mod
+@@ -990,23 +999,8 @@ modules-names += tst-gnu2-tls1mod
  $(objpfx)tst-gnu2-tls1: $(objpfx)tst-gnu2-tls1mod.so
  tst-gnu2-tls1mod.so-no-z-defs = yes
  CFLAGS-tst-gnu2-tls1mod.c += -mtls-dialect=gnu2
@@ -274,7 +362,19 @@ index fd77d0c7c8..72178d33ff 100644
  ifeq (yes,$(have-protected-data))
  modules-names += tst-protected1moda tst-protected1modb
  tests += tst-protected1a tst-protected1b
-@@ -2967,3 +2960,25 @@ $(objpfx)tst-tls-allocation-failure-static-patched.out: 
\
+@@ -2410,6 +2404,11 @@ $(objpfx)tst-ldconfig-X.out : tst-ldconfig-X.sh 
$(objpfx)ldconfig
+                '$(run-program-env)' > $@; \
+       $(evaluate-test)
+ 
++$(objpfx)tst-ldconfig-p.out : tst-ldconfig-p.sh $(objpfx)ldconfig
++      $(SHELL) $< '$(common-objpfx)' '$(test-wrapper-env)' \
++               '$(run-program-env)' > $@; \
++      $(evaluate-test)
++
+ # Test static linking of all the libraries we can possibly link
+ # together.  Note that in some configurations this may be less than the
+ # complete list of libraries we build but we try to maxmimize this list.
+@@ -2967,3 +2966,25 @@ $(objpfx)tst-tls-allocation-failure-static-patched.out: 
\
        grep -q '^Fatal glibc error: Cannot allocate TLS block$$' $@ \
          && grep -q '^status: 127$$' $@; \
          $(evaluate-test)
@@ -487,6 +587,92 @@ index 96638d7ed1..3e2a6a584e 100644
  }
  
  #endif /* HAVE_TUNABLES.  */
+diff --git a/elf/dl-support.c b/elf/dl-support.c
+index 4af0b5b2ce..f45b630ba5 100644
+--- a/elf/dl-support.c
++++ b/elf/dl-support.c
+@@ -255,6 +255,25 @@ _dl_aux_init (ElfW(auxv_t) *av)
+   for (int i = 0; i < array_length (auxv_values); ++i)
+     auxv_values[i] = 0;
+   _dl_parse_auxv (av, auxv_values);
++
++  _dl_phdr = (void*) auxv_values[AT_PHDR];
++  _dl_phnum = auxv_values[AT_PHNUM];
++
++  if (_dl_phdr == NULL)
++    {
++      /* Starting from binutils-2.23, the linker will define the
++         magic symbol __ehdr_start to point to our own ELF header
++         if it is visible in a segment that also includes the phdrs.
++         So we can set up _dl_phdr and _dl_phnum even without any
++         information from auxv.  */
++
++      extern const ElfW(Ehdr) __ehdr_start attribute_hidden;
++      assert (__ehdr_start.e_phentsize == sizeof *GL(dl_phdr));
++      _dl_phdr = (const void *) &__ehdr_start + __ehdr_start.e_phoff;
++      _dl_phnum = __ehdr_start.e_phnum;
++    }
++
++  assert (_dl_phdr != NULL);
+ }
+ #endif
+ 
+@@ -323,20 +342,19 @@ _dl_non_dynamic_init (void)
+   if (_dl_platform != NULL)
+     _dl_platformlen = strlen (_dl_platform);
+ 
+-  if (_dl_phdr != NULL)
+-    for (const ElfW(Phdr) *ph = _dl_phdr; ph < &_dl_phdr[_dl_phnum]; ++ph)
+-      switch (ph->p_type)
+-      {
+-      /* Check if the stack is nonexecutable.  */
+-      case PT_GNU_STACK:
+-        _dl_stack_flags = ph->p_flags;
+-        break;
+-
+-      case PT_GNU_RELRO:
+-        _dl_main_map.l_relro_addr = ph->p_vaddr;
+-        _dl_main_map.l_relro_size = ph->p_memsz;
+-        break;
+-      }
++  for (const ElfW(Phdr) *ph = _dl_phdr; ph < &_dl_phdr[_dl_phnum]; ++ph)
++    switch (ph->p_type)
++      {
++      /* Check if the stack is nonexecutable.  */
++      case PT_GNU_STACK:
++      _dl_stack_flags = ph->p_flags;
++      break;
++
++      case PT_GNU_RELRO:
++      _dl_main_map.l_relro_addr = ph->p_vaddr;
++      _dl_main_map.l_relro_size = ph->p_memsz;
++      break;
++      }
+ 
+   call_function_static_weak (_dl_find_object_init);
+ 
+diff --git a/elf/dl-tunables.list b/elf/dl-tunables.list
+index e6a56b3070..9fa3b484cf 100644
+--- a/elf/dl-tunables.list
++++ b/elf/dl-tunables.list
+@@ -169,4 +169,17 @@ glibc {
+       default: 2
+     }
+   }
++
++  gmon {
++    minarcs {
++      type: INT_32
++      minval: 50
++      default: 50
++    }
++    maxarcs {
++      type: INT_32
++      minval: 50
++      default: 1048576
++    }
++  }
+ }
 diff --git a/elf/dso-sort-tests-1.def b/elf/dso-sort-tests-1.def
 index 5f7f18ef27..4bf9052db1 100644
 --- a/elf/dso-sort-tests-1.def
@@ -709,6 +895,552 @@ index 0000000000..70c71fe19c
 +}
 +
 +#include <support/test-driver.c>
+diff --git a/elf/tst-ldconfig-p.sh b/elf/tst-ldconfig-p.sh
+new file mode 100644
+index 0000000000..ec937bf4ec
+--- /dev/null
++++ b/elf/tst-ldconfig-p.sh
+@@ -0,0 +1,77 @@
++#!/bin/sh
++# Test that ldconfig -p prints something useful.
++# Copyright (C) 2023 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/>.
++
++# Check that the newly built ldconfig -p can dump the system
++# /etc/ld.so.cache file.  This should always work even if the ABIs are
++# not compatible, except in a cross-endian build (that presumably
++# involves emulation when running ldconfig).
++
++common_objpfx=$1
++test_wrapper_env=$2
++run_program_env=$3
++
++if ! test -r /etc/ld.so.cache; then
++    echo "warning: /etc/ld.so.cache does not exist, test skipped"
++    exit 77
++fi
++
++testout="${common_objpfx}elf/tst-ldconfig-p.out"
++# Truncate file.
++: > "$testout"
++
++${test_wrapper_env} \
++${run_program_env} \
++${common_objpfx}elf/ldconfig -p \
++  $testroot/lib >>"$testout" 2>>"$testout"
++status=$?
++echo "info: ldconfig exit status: $status" >>"$testout"
++
++errors=0
++case $status in
++    (0)
++      if head -n 1 "$testout" | \
++              grep -q "libs found in cache \`/etc/ld.so.cache'\$" ; then
++          echo "info: initial string found" >>"$testout"
++      else
++          echo "error: initial string not found" >>"$testout"
++          errors=1
++      fi
++      if grep -q "^   libc\.so\..* => " "$testout"; then
++          echo "info: libc.so.* string found" >>"$testout"
++      else
++          echo "error: libc.so.* string not found" >>"$testout"
++          errors=1
++      fi
++      ;;
++    (1)
++      if head -n 1 "$testout" | \
++              grep -q ": Cache file has wrong endianness\.$" ; then
++          echo "info: cache file has wrong endianess" >> "$testout"
++      else
++          echo "error: unexpected ldconfig error message" >> "$testout"
++          errors=1
++      fi
++      ;;
++    (*)
++      echo "error: unexpected exit status" >> "$testout"
++      errors=1
++      ;;
++esac
++
++exit $errors
+diff --git a/gmon/Makefile b/gmon/Makefile
+index 552b7d7751..fbe2b0ba5c 100644
+--- a/gmon/Makefile
++++ b/gmon/Makefile
+@@ -1,4 +1,5 @@
+-# Copyright (C) 1995-2022 Free Software Foundation, Inc.
++# Copyright (C) 1995-2023 Free Software Foundation, Inc.
++# Copyright The GNU Toolchain Authors.
+ # This file is part of the GNU C Library.
+ 
+ # The GNU C Library is free software; you can redistribute it and/or
+@@ -25,7 +26,7 @@ include ../Makeconfig
+ headers       := sys/gmon.h sys/gmon_out.h sys/profil.h
+ routines := gmon mcount profil sprofil prof-freq
+ 
+-tests = tst-sprofil tst-gmon
++tests = tst-sprofil tst-gmon tst-mcleanup
+ ifeq ($(build-profile),yes)
+ tests += tst-profile-static
+ tests-static  += tst-profile-static
+@@ -56,6 +57,14 @@ ifeq ($(run-built-tests),yes)
+ tests-special += $(objpfx)tst-gmon-gprof.out
+ endif
+ 
++CFLAGS-tst-mcleanup.c := -fno-omit-frame-pointer -pg
++tst-mcleanup-no-pie = yes
++CRT-tst-mcleanup := $(csu-objpfx)g$(start-installed-name)
++tst-mcleanup-ENV := GMON_OUT_PREFIX=$(objpfx)tst-mcleanup.data
++ifeq ($(run-built-tests),yes)
++tests-special += $(objpfx)tst-mcleanup.out
++endif
++
+ CFLAGS-tst-gmon-static.c := $(PIE-ccflag) -fno-omit-frame-pointer -pg
+ CRT-tst-gmon-static := $(csu-objpfx)g$(static-start-installed-name)
+ tst-gmon-static-no-pie = yes
+@@ -103,6 +112,18 @@ $(objpfx)tst-gmon.out: clean-tst-gmon-data
+ clean-tst-gmon-data:
+       rm -f $(objpfx)tst-gmon.data.*
+ 
++$(objpfx)tst-mcount-overflow.o: clean-tst-mcount-overflow-data
++clean-tst-mcount-overflow-data:
++      rm -f $(objpfx)tst-mcount-overflow.data.*
++
++$(objpfx)tst-mcount-overflow-check.out: tst-mcount-overflow-check.sh 
$(objpfx)tst-mcount-overflow.out
++      $(SHELL) $< $(objpfx)tst-mcount-overflow > $@; \
++      $(evaluate-test)
++
++$(objpfx)tst-mcleanup.out: clean-tst-mcleanup-data
++clean-tst-mcleanup-data:
++      rm -f $(objpfx)tst-mcleanup.data.*
++
+ $(objpfx)tst-gmon-gprof.out: tst-gmon-gprof.sh $(objpfx)tst-gmon.out
+       $(SHELL) $< $(GPROF) $(objpfx)tst-gmon $(objpfx)tst-gmon.data.* > $@; \
+       $(evaluate-test)
+diff --git a/gmon/gmon.c b/gmon/gmon.c
+index dee64803ad..97be1f72ca 100644
+--- a/gmon/gmon.c
++++ b/gmon/gmon.c
+@@ -97,11 +97,8 @@ __moncontrol (int mode)
+ {
+   struct gmonparam *p = &_gmonparam;
+ 
+-  /* Don't change the state if we ran into an error.  */
+-  if (p->state == GMON_PROF_ERROR)
+-    return;
+-
+-  if (mode)
++  /* Treat start request as stop if error or gmon not initialized. */
++  if (mode && p->state != GMON_PROF_ERROR && p->tos != NULL)
+     {
+       /* start */
+       __profil((void *) p->kcount, p->kcountsize, p->lowpc, s_scale);
+@@ -111,7 +108,9 @@ __moncontrol (int mode)
+     {
+       /* stop */
+       __profil(NULL, 0, 0, 0);
+-      p->state = GMON_PROF_OFF;
++      /* Don't change the state if we ran into an error. */
++      if (p->state != GMON_PROF_ERROR)
++        p->state = GMON_PROF_OFF;
+     }
+ }
+ libc_hidden_def (__moncontrol)
+@@ -124,6 +123,19 @@ __monstartup (u_long lowpc, u_long highpc)
+   int o;
+   char *cp;
+   struct gmonparam *p = &_gmonparam;
++  long int minarcs, maxarcs;
++
++  /* No tunables, we use hardcoded defaults */
++  minarcs = MINARCS;
++  maxarcs = MAXARCS;
++
++  /*
++   * If we are incorrectly called twice in a row (without an
++   * intervening call to _mcleanup), ignore the second call to
++   * prevent leaking memory.
++   */
++  if (p->tos != NULL)
++      return;
+ 
+   /*
+    * round lowpc and highpc to multiples of the density we're using
+@@ -132,6 +144,8 @@ __monstartup (u_long lowpc, u_long highpc)
+   p->lowpc = ROUNDDOWN(lowpc, HISTFRACTION * sizeof(HISTCOUNTER));
+   p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER));
+   p->textsize = p->highpc - p->lowpc;
++  /* This looks like a typo, but it's here to align the p->froms
++     section.  */
+   p->kcountsize = ROUNDUP(p->textsize / HISTFRACTION, sizeof(*p->froms));
+   p->hashfraction = HASHFRACTION;
+   p->log_hashfraction = -1;
+@@ -142,12 +156,12 @@ __monstartup (u_long lowpc, u_long highpc)
+        instead of integer division.  Precompute shift amount. */
+       p->log_hashfraction = ffs(p->hashfraction * sizeof(*p->froms)) - 1;
+   }
+-  p->fromssize = p->textsize / HASHFRACTION;
++  p->fromssize = ROUNDUP(p->textsize / HASHFRACTION, sizeof(*p->froms));
+   p->tolimit = p->textsize * ARCDENSITY / 100;
+-  if (p->tolimit < MINARCS)
+-    p->tolimit = MINARCS;
+-  else if (p->tolimit > MAXARCS)
+-    p->tolimit = MAXARCS;
++  if (p->tolimit < minarcs)
++    p->tolimit = minarcs;
++  else if (p->tolimit > maxarcs)
++    p->tolimit = maxarcs;
+   p->tossize = p->tolimit * sizeof(struct tostruct);
+ 
+   cp = calloc (p->kcountsize + p->fromssize + p->tossize, 1);
+@@ -440,9 +454,14 @@ _mcleanup (void)
+ {
+   __moncontrol (0);
+ 
+-  if (_gmonparam.state != GMON_PROF_ERROR)
++  if (_gmonparam.state != GMON_PROF_ERROR && _gmonparam.tos != NULL)
+     write_gmon ();
+ 
+   /* free the memory. */
+   free (_gmonparam.tos);
++
++  /* reset buffer to initial state for safety */
++  memset(&_gmonparam, 0, sizeof _gmonparam);
++  /* somewhat confusingly, ON=0, OFF=3 */
++  _gmonparam.state = GMON_PROF_OFF;
+ }
+diff --git a/gmon/mcount.c b/gmon/mcount.c
+index 9d4a1a50fa..f7180fdb83 100644
+--- a/gmon/mcount.c
++++ b/gmon/mcount.c
+@@ -41,6 +41,10 @@ static char sccsid[] = "@(#)mcount.c        8.1 (Berkeley) 
6/4/93";
+ 
+ #include <atomic.h>
+ 
++#include <not-cancel.h>
++#include <unistd.h>
++#define ERR(s) __write_nocancel (STDERR_FILENO, s, sizeof (s) - 1)
++
+ /*
+  * mcount is called on entry to each function compiled with the profiling
+  * switch set.  _mcount(), which is declared in a machine-dependent way
+@@ -170,6 +174,7 @@ done:
+       return;
+ overflow:
+       p->state = GMON_PROF_ERROR;
++      ERR("mcount: call graph buffer size limit exceeded, gmon.out will not 
be generated\n");
+       return;
+ }
+ 
+diff --git a/gmon/sys/gmon.h b/gmon/sys/gmon.h
+index b4cc3b043a..af0582a371 100644
+--- a/gmon/sys/gmon.h
++++ b/gmon/sys/gmon.h
+@@ -111,6 +111,8 @@ extern struct __bb *__bb_head;
+  * Always allocate at least this many tostructs.  This
+  * hides the inadequacy of the ARCDENSITY heuristic, at least
+  * for small programs.
++ *
++ * Value can be overridden at runtime by glibc.gmon.minarcs tunable.
+  */
+ #define MINARCS               50
+ 
+@@ -124,8 +126,8 @@ extern struct __bb *__bb_head;
+  * Used to be max representable value of ARCINDEX minus 2, but now
+  * that ARCINDEX is a long, that's too large; we don't really want
+  * to allow a 48 gigabyte table.
+- * The old value of 1<<16 wasn't high enough in practice for large C++
+- * programs; will 1<<20 be adequate for long?  FIXME
++ *
++ * Value can be overridden at runtime by glibc.gmon.maxarcs tunable.
+  */
+ #define MAXARCS               (1 << 20)
+ 
+diff --git a/gmon/tst-mcleanup.c b/gmon/tst-mcleanup.c
+new file mode 100644
+index 0000000000..b259653ec8
+--- /dev/null
++++ b/gmon/tst-mcleanup.c
+@@ -0,0 +1,31 @@
++/* Test program for repeated invocation of _mcleanup
++   Copyright The GNU Toolchain Authors.
++   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/>.  */
++
++/* Intentionally calls _mcleanup() twice: once manually, it will be
++   called again as an atexit handler. This is incorrect use of the API,
++   but the point of the test is to make sure we don't crash when the
++   API is misused in this way. */
++
++#include <sys/gmon.h>
++
++int
++main (void)
++{
++  _mcleanup();
++  return 0;
++}
+diff --git a/gmon/tst-mcount-overflow-check.sh 
b/gmon/tst-mcount-overflow-check.sh
+new file mode 100644
+index 0000000000..27eb5538fd
+--- /dev/null
++++ b/gmon/tst-mcount-overflow-check.sh
+@@ -0,0 +1,45 @@
++#!/bin/sh
++# Test expected messages generated when mcount overflows
++# Copyright (C) 2017-2023 Free Software Foundation, Inc.
++# Copyright The GNU Toolchain Authors.
++# 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/>.
++
++LC_ALL=C
++export LC_ALL
++set -e
++exec 2>&1
++
++program="$1"
++
++check_msg() {
++    if ! grep -q "$1" "$program.out"; then
++       echo "FAIL: expected message not in output: $1"
++       exit 1
++    fi
++}
++
++check_msg 'monstartup: maxarcs < minarcs, setting maxarcs = minarcs'
++check_msg 'mcount: call graph buffer size limit exceeded, gmon.out will not 
be generated'
++
++for data_file in $1.data.*; do
++  if [ -f "$data_file" ]; then
++    echo "FAIL: expected no data files, but found $data_file"
++    exit 1
++  fi
++done
++
++echo PASS
+diff --git a/gmon/tst-mcount-overflow.c b/gmon/tst-mcount-overflow.c
+new file mode 100644
+index 0000000000..06cc93ef87
+--- /dev/null
++++ b/gmon/tst-mcount-overflow.c
+@@ -0,0 +1,72 @@
++/* Test program to trigger mcount overflow in profiling collection.
++   Copyright (C) 2017-2023 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/>.  */
++
++/* Program with sufficiently complex, yet pointless, call graph
++   that it will trigger an mcount overflow, when you set the
++   minarcs/maxarcs tunables to very low values. */
++
++#define PREVENT_TAIL_CALL asm volatile ("")
++
++/* Calls REP(n) macro 16 times, for n=0..15.
++ * You need to define REP(n) before using this.
++ */
++#define REPS \
++  REP(0) REP(1) REP(2) REP(3) REP(4) REP(5) REP(6) REP(7) \
++  REP(8) REP(9) REP(10) REP(11) REP(12) REP(13) REP(14) REP(15)
++
++/* Defines 16 leaf functions named f1_0 to f1_15 */
++#define REP(n) \
++  __attribute__ ((noinline, noclone, weak)) void f1_##n (void) {};
++REPS
++#undef REP
++
++/* Calls all 16 leaf functions f1_* in succession */
++__attribute__ ((noinline, noclone, weak)) void
++f2 (void)
++{
++# define REP(n) f1_##n();
++  REPS
++# undef REP
++  PREVENT_TAIL_CALL;
++}
++
++/* Defines 16 functions named f2_0 to f2_15, which all just call f2 */
++#define REP(n) \
++  __attribute__ ((noinline, noclone, weak)) void \
++  f2_##n (void) { f2(); PREVENT_TAIL_CALL; };
++REPS
++#undef REP
++
++__attribute__ ((noinline, noclone, weak)) void
++f3 (int count)
++{
++  for (int i = 0; i < count; ++i)
++    {
++      /* Calls f1_0(), f2_0(), f1_1(), f2_1(), f3_0(), etc */
++#     define REP(n) f1_##n(); f2_##n();
++      REPS
++#     undef REP
++    }
++}
++
++int
++main (void)
++{
++  f3 (1000);
++  return 0;
++}
+diff --git a/gshadow/Makefile b/gshadow/Makefile
+index eff303f538..5b3fa7e387 100644
+--- a/gshadow/Makefile
++++ b/gshadow/Makefile
+@@ -26,7 +26,7 @@ headers              = gshadow.h
+ routines      = getsgent getsgnam sgetsgent fgetsgent putsgent \
+                 getsgent_r getsgnam_r sgetsgent_r fgetsgent_r
+ 
+-tests = tst-gshadow tst-putsgent tst-fgetsgent_r
++tests = tst-gshadow tst-putsgent tst-fgetsgent_r tst-sgetsgent
+ 
+ CFLAGS-getsgent_r.c += -fexceptions
+ CFLAGS-getsgent.c += -fexceptions
+diff --git a/gshadow/sgetsgent_r.c b/gshadow/sgetsgent_r.c
+index 28c826c9b5..a767a643d4 100644
+--- a/gshadow/sgetsgent_r.c
++++ b/gshadow/sgetsgent_r.c
+@@ -61,7 +61,10 @@ __sgetsgent_r (const char *string, struct sgrp *resbuf, 
char *buffer,
+       buffer[buflen - 1] = '\0';
+       sp = strncpy (buffer, string, buflen);
+       if (buffer[buflen - 1] != '\0')
+-      return ERANGE;
++      {
++        __set_errno (ERANGE);
++        return ERANGE;
++      }
+     }
+   else
+     sp = (char *) string;
+diff --git a/gshadow/tst-sgetsgent.c b/gshadow/tst-sgetsgent.c
+new file mode 100644
+index 0000000000..0370c10fd0
+--- /dev/null
++++ b/gshadow/tst-sgetsgent.c
+@@ -0,0 +1,69 @@
++/* Test large input for sgetsgent (bug 30151).
++   Copyright (C) 2023 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 <gshadow.h>
++#include <stddef.h>
++#include <support/check.h>
++#include <support/support.h>
++#include <support/xmemstream.h>
++#include <stdlib.h>
++
++static int
++do_test (void)
++{
++  /* Create a shadow group with 1000 members.  */
++  struct xmemstream mem;
++  xopen_memstream (&mem);
++  const char *passwd = "k+zD0nucwfxAo3sw1NXUj6K5vt5M16+X0TVGdE1uFvq5R8V7efJ";
++  fprintf (mem.out, "group-name:%s::m0", passwd);
++  for (int i = 1; i < 1000; ++i)
++    fprintf (mem.out, ",m%d", i);
++  xfclose_memstream (&mem);
++
++  /* Call sgetsgent.  */
++  char *input = mem.buffer;
++  struct sgrp *e = sgetsgent (input);
++  TEST_VERIFY_EXIT (e != NULL);
++  TEST_COMPARE_STRING (e->sg_namp, "group-name");
++  TEST_COMPARE_STRING (e->sg_passwd, passwd);
++  /* No administrators.  */
++  TEST_COMPARE_STRING (e->sg_adm[0], NULL);
++  /* Check the members list.  */
++  for (int i = 0; i < 1000; ++i)
++    {
++      char *member = xasprintf ("m%d", i);
++      TEST_COMPARE_STRING (e->sg_mem[i], member);
++      free (member);
++    }
++  TEST_COMPARE_STRING (e->sg_mem[1000], NULL);
++
++  /* Check that putsgent brings back the input string.  */
++  xopen_memstream (&mem);
++  TEST_COMPARE (putsgent (e, mem.out), 0);
++  xfclose_memstream (&mem);
++  /* Compare without the trailing '\n' that putsgent added.  */
++  TEST_COMPARE (mem.buffer[mem.length - 1], '\n');
++  mem.buffer[mem.length - 1] = '\0';
++  TEST_COMPARE_STRING (mem.buffer, input);
++
++  free (mem.buffer);
++  free (input);
++  return 0;
++}
++
++#include <support/test-driver.c>
 diff --git a/iconv/gconv_parseconfdir.h b/iconv/gconv_parseconfdir.h
 index debb96b322..b72933b526 100644
 --- a/iconv/gconv_parseconfdir.h
@@ -901,6 +1633,270 @@ index 3590b6f496..4dbbac3800 100644
 +
  # endif /* _RESOLV_H_ && !_ISOMAC */
  #endif
+diff --git a/io/Makefile b/io/Makefile
+index b1710407d0..fb363c612c 100644
+--- a/io/Makefile
++++ b/io/Makefile
+@@ -80,7 +80,8 @@ tests                := test-utime test-stat test-stat2 
test-lfs tst-getcwd \
+                  tst-utimensat \
+                  tst-closefrom \
+                  tst-close_range \
+-                 tst-ftw-bz28126
++                 tst-ftw-bz28126 \
++                 tst-fcntl-lock
+ 
+ tests-time64 := \
+   tst-fcntl-time64 \
+diff --git a/io/tst-fcntl-lock.c b/io/tst-fcntl-lock.c
+new file mode 100644
+index 0000000000..357c4b7b56
+--- /dev/null
++++ b/io/tst-fcntl-lock.c
+@@ -0,0 +1,97 @@
++/* Test for advisory record locking.
++   Copyright (C) 2023 Free Software Foundation, Inc.
++
++   This program is free software; you can redistribute it and/or
++   modify it under the terms of the GNU General Public License
++   as published by the Free Software Foundation; either version 2
++   of the License, or (at your option) any later version.
++
++   This program 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 General Public License for more details.
++
++   You should have received a copy of the GNU General Public License
++   along with this program; if not, see <https://www.gnu.org/licenses/>.
++*/
++
++#include <fcntl.h>
++#include <errno.h>
++#include <unistd.h>
++
++/* This is essentially the POSIX lockf.  */
++
++static int
++fcntl_lockf (int fd, int cmd, off_t len)
++{
++  struct flock fl = {
++    .l_type = F_WRLCK,
++    .l_whence = SEEK_CUR,
++    .l_len = len
++  };
++
++  switch (cmd)
++    {
++    case F_TEST:
++      fl.l_type = F_RDLCK;
++      if (fcntl (fd, F_GETLK, &fl) < 0)
++      return -1;
++      if (fl.l_type == F_UNLCK || fl.l_pid == getpid ())
++      return 0;
++      errno = EACCES;
++      return -1;
++
++    case F_ULOCK:
++      fl.l_type = F_UNLCK;
++      return fcntl (fd, F_SETLK, &fl);
++
++    case F_LOCK:
++      return fcntl (fd, F_SETLKW, &fl);
++
++    case F_TLOCK:
++      return fcntl (fd, F_SETLK, &fl);
++    }
++
++  errno = EINVAL;
++  return -1;
++}
++
++static int
++fcntl64_lockf (int fd, int cmd, off64_t len64)
++  {
++  struct flock64 fl64 = {
++    .l_type = F_WRLCK,
++    .l_whence = SEEK_CUR,
++    .l_len = len64
++  };
++
++  switch (cmd)
++    {
++    case F_TEST:
++      fl64.l_type = F_RDLCK;
++      if (fcntl64 (fd, F_GETLK64, &fl64) < 0)
++      return -1;
++      if (fl64.l_type == F_UNLCK || fl64.l_pid == getpid ())
++      return 0;
++      errno = EACCES;
++      return -1;
++
++    case F_ULOCK:
++      fl64.l_type = F_UNLCK;
++      return fcntl64 (fd, F_SETLK64, &fl64);
++
++    case F_LOCK:
++      return fcntl64 (fd, F_SETLKW64, &fl64);
++
++    case F_TLOCK:
++      return fcntl64 (fd, F_SETLK64, &fl64);
++    }
++
++  errno = EINVAL;
++  return -1;
++}
++
++#define TST_LOCKFD  "tst-fcntl-lock."
++#define LOCKF       fcntl_lockf
++#define LOCKF64     fcntl64_lockf
++#include "tst-lockf.c"
+diff --git a/io/tst-lockf.c b/io/tst-lockf.c
+index be92f33fd1..5e41dc19df 100644
+--- a/io/tst-lockf.c
++++ b/io/tst-lockf.c
+@@ -24,13 +24,23 @@
+ #include <support/capture_subprocess.h>
+ #include <support/check.h>
+ 
++#ifndef TST_LOCKFD
++# define TST_LOCKFD "tst-lockfd."
++#endif
++#ifndef LOCKF
++# define LOCKF lockf
++#endif
++#ifndef LOCKF64
++# define LOCKF64 lockf64
++#endif
++
+ static char *temp_filename;
+ static int temp_fd;
+ 
+ static void
+ do_prepare (int argc, char **argv)
+ {
+-  temp_fd = create_temp_file ("tst-lockfd.", &temp_filename);
++  temp_fd = create_temp_file (TST_LOCKFD, &temp_filename);
+   TEST_VERIFY_EXIT (temp_fd != -1);
+ }
+ #define PREPARE do_prepare
+@@ -40,22 +50,22 @@ do_test_child_lockf (void *closure)
+ {
+   /* Check if parent has [0, 1024) locked.  */
+   TEST_COMPARE (lseek (temp_fd, 0, SEEK_SET), 0);
+-  TEST_COMPARE (lockf (temp_fd, F_TLOCK, 1024), -1);
++  TEST_COMPARE (LOCKF (temp_fd, F_TLOCK, 1024), -1);
+   TEST_COMPARE (errno, EAGAIN);
+-  TEST_COMPARE (lockf (temp_fd, F_TEST, 1024), -1);
++  TEST_COMPARE (LOCKF (temp_fd, F_TEST, 1024), -1);
+   TEST_COMPARE (errno, EACCES);
+   /* Also Check if parent has last 1024 bytes locked.  */
+   TEST_COMPARE (lseek (temp_fd, INT32_MAX-1024, SEEK_SET), INT32_MAX-1024);
+-  TEST_COMPARE (lockf (temp_fd, F_TEST, 1024), -1);
++  TEST_COMPARE (LOCKF (temp_fd, F_TEST, 1024), -1);
+ 
+   /* And try to lock [1024, 2048).  */
+   TEST_COMPARE (lseek (temp_fd, 1024, SEEK_SET), 1024);
+-  TEST_COMPARE (lockf (temp_fd, F_LOCK, 1024), 0);
++  TEST_COMPARE (LOCKF (temp_fd, F_LOCK, 1024), 0);
+ 
+   /* Check if non-LFS interface cap access to 32-bif off_t.  */
+   TEST_COMPARE (lseek64 (temp_fd, (off64_t)INT32_MAX, SEEK_SET),
+               (off64_t)INT32_MAX);
+-  TEST_COMPARE (lockf64 (temp_fd, F_TEST, 1024), 0);
++  TEST_COMPARE (LOCKF64 (temp_fd, F_TEST, 1024), 0);
+ }
+ 
+ static void
+@@ -63,32 +73,32 @@ do_test_child_lockf64 (void *closure)
+ {
+   /* Check if parent has [0, 1024) locked.  */
+   TEST_COMPARE (lseek64 (temp_fd, 0, SEEK_SET), 0);
+-  TEST_COMPARE (lockf64 (temp_fd, F_TLOCK, 1024), -1);
++  TEST_COMPARE (LOCKF64 (temp_fd, F_TLOCK, 1024), -1);
+   TEST_COMPARE (errno, EAGAIN);
+-  TEST_COMPARE (lockf64 (temp_fd, F_TEST, 1024), -1);
++  TEST_COMPARE (LOCKF64 (temp_fd, F_TEST, 1024), -1);
+   TEST_COMPARE (errno, EACCES);
+   /* Also Check if parent has last 1024 bytes locked.  */
+   TEST_COMPARE (lseek64 (temp_fd, INT32_MAX-1024, SEEK_SET), INT32_MAX-1024);
+-  TEST_COMPARE (lockf64 (temp_fd, F_TEST, 1024), -1);
++  TEST_COMPARE (LOCKF64 (temp_fd, F_TEST, 1024), -1);
+ 
+   /* And try to lock [1024, 2048).  */
+   TEST_COMPARE (lseek64 (temp_fd, 1024, SEEK_SET), 1024);
+-  TEST_COMPARE (lockf64 (temp_fd, F_LOCK, 1024), 0);
++  TEST_COMPARE (LOCKF64 (temp_fd, F_LOCK, 1024), 0);
+ 
+   /* And also [INT32_MAX, INT32_MAX+1024).  */
+   {
+     off64_t off = (off64_t)INT32_MAX;
+     TEST_COMPARE (lseek64 (temp_fd, off, SEEK_SET), off);
+-    TEST_COMPARE (lockf64 (temp_fd, F_LOCK, 1024), 0);
++    TEST_COMPARE (LOCKF64 (temp_fd, F_LOCK, 1024), 0);
+   }
+ 
+   /* Check if [INT32_MAX+1024, INT64_MAX) is locked.  */
+   {
+     off64_t off = (off64_t)INT32_MAX+1024;
+     TEST_COMPARE (lseek64 (temp_fd, off, SEEK_SET), off);
+-    TEST_COMPARE (lockf64 (temp_fd, F_TLOCK, 1024), -1);
++    TEST_COMPARE (LOCKF64 (temp_fd, F_TLOCK, 1024), -1);
+     TEST_COMPARE (errno, EAGAIN);
+-    TEST_COMPARE (lockf64 (temp_fd, F_TEST, 1024), -1);
++    TEST_COMPARE (LOCKF64 (temp_fd, F_TEST, 1024), -1);
+     TEST_COMPARE (errno, EACCES);
+   }
+ }
+@@ -97,38 +107,38 @@ static int
+ do_test (void)
+ {
+   /* Basic tests to check if a lock can be obtained and checked.  */
+-  TEST_COMPARE (lockf (temp_fd, F_LOCK, 1024), 0);
+-  TEST_COMPARE (lockf (temp_fd, F_LOCK, INT32_MAX), 0);
+-  TEST_COMPARE (lockf (temp_fd, F_TLOCK, 1024), 0);
+-  TEST_COMPARE (lockf (temp_fd, F_TEST, 1024), 0);
++  TEST_COMPARE (LOCKF (temp_fd, F_LOCK, 1024), 0);
++  TEST_COMPARE (LOCKF (temp_fd, F_LOCK, INT32_MAX), 0);
++  TEST_COMPARE (LOCKF (temp_fd, F_TLOCK, 1024), 0);
++  TEST_COMPARE (LOCKF (temp_fd, F_TEST, 1024), 0);
+   TEST_COMPARE (lseek (temp_fd, 1024, SEEK_SET), 1024);
+-  TEST_COMPARE (lockf (temp_fd, F_ULOCK, 1024), 0);
++  TEST_COMPARE (LOCKF (temp_fd, F_ULOCK, 1024), 0);
+   /* Parent process should have ([0, 1024), [2048, INT32_MAX)) ranges locked. 
 */
+ 
+   {
+     struct support_capture_subprocess result;
+     result = support_capture_subprocess (do_test_child_lockf, NULL);
+-    support_capture_subprocess_check (&result, "lockf", 0, sc_allow_none);
++    support_capture_subprocess_check (&result, "LOCKF", 0, sc_allow_none);
+   }
+ 
+   if (sizeof (off_t) != sizeof (off64_t))
+     {
+       /* Check if previously locked regions with LFS symbol.  */
+       TEST_COMPARE (lseek (temp_fd, 0, SEEK_SET), 0);
+-      TEST_COMPARE (lockf64 (temp_fd, F_LOCK, 1024), 0);
+-      TEST_COMPARE (lockf64 (temp_fd, F_TLOCK, 1024), 0);
+-      TEST_COMPARE (lockf64 (temp_fd, F_TEST, 1024), 0);
++      TEST_COMPARE (LOCKF64 (temp_fd, F_LOCK, 1024), 0);
++      TEST_COMPARE (LOCKF64 (temp_fd, F_TLOCK, 1024), 0);
++      TEST_COMPARE (LOCKF64 (temp_fd, F_TEST, 1024), 0);
+       /* Lock region [INT32_MAX+1024, INT64_MAX).  */
+       off64_t off = (off64_t)INT32_MAX + 1024;
+       TEST_COMPARE (lseek64 (temp_fd, off, SEEK_SET), off);
+-      TEST_COMPARE (lockf64 (temp_fd, F_LOCK, 1024), 0);
++      TEST_COMPARE (LOCKF64 (temp_fd, F_LOCK, 1024), 0);
+       /* Parent process should have ([0, 1024), [2048, INT32_MAX),
+        [INT32_MAX+1024, INT64_MAX)) ranges locked.  */
+ 
+       {
+       struct support_capture_subprocess result;
+       result = support_capture_subprocess (do_test_child_lockf64, NULL);
+-      support_capture_subprocess_check (&result, "lockf", 0, sc_allow_none);
++      support_capture_subprocess_check (&result, "LOCKF", 0, sc_allow_none);
+       }
+     }
+ 
 diff --git a/locale/weight.h b/locale/weight.h
 index 8be2d220f8..4a4d5aa6b2 100644
 --- a/locale/weight.h
@@ -956,6 +1952,37 @@ index fd30dd3114..916d2b6f12 100644
  __fortify_function void
  vsyslog (int __pri, const char *__fmt, __gnuc_va_list __ap)
  {
+diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
+index f525f67547..294e633335 100644
+--- a/misc/sys/cdefs.h
++++ b/misc/sys/cdefs.h
+@@ -152,6 +152,7 @@
+ # define __glibc_objsize(__o) __bos (__o)
+ #endif
+ 
++#if __USE_FORTIFY_LEVEL > 0
+ /* Compile time conditions to choose between the regular, _chk and _chk_warn
+    variants.  These conditions should get evaluated to constant and optimized
+    away.  */
+@@ -187,7 +188,7 @@
+    ? __ ## f ## _alias (__VA_ARGS__)                                        \
+    : (__glibc_unsafe_len (__l, __s, __osz)                                  \
+       ? __ ## f ## _chk_warn (__VA_ARGS__, __osz)                           \
+-      : __ ## f ## _chk (__VA_ARGS__, __osz)))                              \
++      : __ ## f ## _chk (__VA_ARGS__, __osz)))
+ 
+ /* Fortify function f, where object size argument passed to f is the number of
+    elements and not total size.  */
+@@ -197,7 +198,8 @@
+    ? __ ## f ## _alias (__VA_ARGS__)                                        \
+    : (__glibc_unsafe_len (__l, __s, __osz)                                  \
+       ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s))                 \
+-      : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s))))                    \
++      : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s))))
++#endif
+ 
+ #if __GNUC_PREREQ (4,3)
+ # define __warnattr(msg) __attribute__((__warning__ (msg)))
 diff --git a/misc/sys/syslog.h b/misc/sys/syslog.h
 index d933fea104..3888153ed2 100644
 --- a/misc/sys/syslog.h
@@ -5250,6 +6277,18 @@ index 0000000000..68c96d3c9d
 +}
 +
 +#include <support/test-driver.c>
+diff --git a/stdlib/Makefile b/stdlib/Makefile
+index f7b25c1981..3d49c4941a 100644
+--- a/stdlib/Makefile
++++ b/stdlib/Makefile
+@@ -171,6 +171,7 @@ tests := \
+   test-a64l \
+   test-at_quick_exit-race \
+   test-atexit-race \
++  test-atexit-recursive \
+   test-bz22786 \
+   test-canon \
+   test-canon2 \
 diff --git a/stdlib/arc4random.c b/stdlib/arc4random.c
 index e417ef624d..960a38f295 100644
 --- a/stdlib/arc4random.c
@@ -5263,6 +6302,31 @@ index e417ef624d..960a38f295 100644
    int fd;
  
    if (n == 0)
+diff --git a/stdlib/exit.c b/stdlib/exit.c
+index bc46109f3e..dc12e212bc 100644
+--- a/stdlib/exit.c
++++ b/stdlib/exit.c
+@@ -53,7 +53,10 @@ __run_exit_handlers (int status, struct exit_function_list 
**listp,
+      exit (). */
+   while (true)
+     {
+-      struct exit_function_list *cur = *listp;
++      struct exit_function_list *cur;
++
++    restart:
++      cur = *listp;
+ 
+       if (cur == NULL)
+       {
+@@ -118,7 +121,7 @@ __run_exit_handlers (int status, struct exit_function_list 
**listp,
+         if (__glibc_unlikely (new_exitfn_called != __new_exitfn_called))
+           /* The last exit function, or another thread, has registered
+              more exit functions.  Start the loop over.  */
+-            continue;
++          goto restart;
+       }
+ 
+       *listp = cur->next;
 diff --git a/stdlib/longlong.h b/stdlib/longlong.h
 index 9b89469ac2..d8f76a43b5 100644
 --- a/stdlib/longlong.h
@@ -5286,6 +6350,138 @@ index 9b89469ac2..d8f76a43b5 100644
  #if defined (__M32R__) && W_TYPE_SIZE == 32
  #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
    /* The cmp clears the condition bit.  */ \
+diff --git a/stdlib/test-atexit-recursive.c b/stdlib/test-atexit-recursive.c
+new file mode 100644
+index 0000000000..0596b9763b
+--- /dev/null
++++ b/stdlib/test-atexit-recursive.c
+@@ -0,0 +1,75 @@
++/* Support file for atexit/exit, etc. race tests (BZ #27749).
++   Copyright (C) 2023 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/>.  */
++
++/* Check that atexit handler registed from another handler still called. */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <support/check.h>
++#include <support/xunistd.h>
++#include <sys/wait.h>
++#include <unistd.h>
++
++static void
++atexit_cb (void)
++{
++}
++
++static void
++atexit_last (void)
++{
++  _exit (1);
++}
++
++static void
++atexit_recursive (void)
++{
++  atexit (&atexit_cb);
++  atexit (&atexit_last);
++}
++
++_Noreturn static void
++test_and_exit (int count)
++{
++  for (int i = 0; i < count; ++i)
++    atexit (&atexit_cb);
++  atexit (&atexit_recursive);
++  exit (0);
++}
++
++static int
++do_test (void)
++{
++  for (int i = 0; i < 100; ++i)
++    if (xfork () == 0)
++      test_and_exit (i);
++
++  for (int i = 0; i < 100; ++i)
++    {
++      int status;
++      xwaitpid (0, &status, 0);
++      if (!WIFEXITED (status))
++      FAIL_EXIT1 ("Failed iterations %d", i);
++      TEST_COMPARE (WEXITSTATUS (status), 1);
++    }
++
++  return 0;
++}
++
++#define TEST_FUNCTION do_test
++#include <support/test-driver.c>
+diff --git a/stdlib/tst-system.c b/stdlib/tst-system.c
+index f7fa74b2a6..5e0c79475f 100644
+--- a/stdlib/tst-system.c
++++ b/stdlib/tst-system.c
+@@ -25,6 +25,7 @@
+ #include <support/check.h>
+ #include <support/temp_file.h>
+ #include <support/support.h>
++#include <support/xthread.h>
+ #include <support/xunistd.h>
+ 
+ static char *tmpdir;
+@@ -71,6 +72,20 @@ call_system (void *closure)
+     }
+ }
+ 
++static void *
++sleep_and_check_sigchld (void *closure)
++{
++  double *seconds = (double *) closure;
++  char cmd[namemax];
++  sprintf (cmd, "sleep %lf" , *seconds);
++  TEST_COMPARE (system (cmd), 0);
++
++  sigset_t blocked = {0};
++  TEST_COMPARE (sigprocmask (SIG_BLOCK, NULL, &blocked), 0);
++  TEST_COMPARE (sigismember (&blocked, SIGCHLD), 0);
++  return NULL;
++}
++
+ static int
+ do_test (void)
+ {
+@@ -154,6 +169,17 @@ do_test (void)
+     xchmod (_PATH_BSHELL, st.st_mode);
+   }
+ 
++  {
++    pthread_t long_sleep_thread = xpthread_create (NULL,
++                                                   sleep_and_check_sigchld,
++                                                   &(double) { 0.2 });
++    pthread_t short_sleep_thread = xpthread_create (NULL,
++                                                    sleep_and_check_sigchld,
++                                                    &(double) { 0.1 });
++    xpthread_join (short_sleep_thread);
++    xpthread_join (long_sleep_thread);
++  }
++
+   TEST_COMPARE (system (""), 0);
+ 
+   return 0;
 diff --git a/string/test-strnlen.c b/string/test-strnlen.c
 index 4a9375112a..5cbaf4b734 100644
 --- a/string/test-strnlen.c
@@ -5403,6 +6599,183 @@ index bf7f0b81c4..c1d1c43e50 100644
    i = strlen (netname);
    if (netname[i - 1] == '.')
      netname[i - 1] = '\0';
+diff --git a/support/Makefile b/support/Makefile
+index 9b50eac117..2b661a7eb8 100644
+--- a/support/Makefile
++++ b/support/Makefile
+@@ -32,6 +32,8 @@ libsupport-routines = \
+   check_hostent \
+   check_netent \
+   delayed_exit \
++  dtotimespec \
++  dtotimespec-time64 \
+   ignore_stderr \
+   next_to_fault \
+   oom_error \
+diff --git a/support/dtotimespec-time64.c b/support/dtotimespec-time64.c
+new file mode 100644
+index 0000000000..b3d5e351e3
+--- /dev/null
++++ b/support/dtotimespec-time64.c
+@@ -0,0 +1,27 @@
++/* Convert double to timespec.  64-bit time support.
++   Copyright (C) 2011-2023 Free Software Foundation, Inc.
++   This file is part of the GNU C Library and is also part of gnulib.
++   Patches to this file should be submitted to both projects.
++
++   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 <time.h>
++
++#if __TIMESIZE != 64
++# define timespec      __timespec64
++# define time_t        __time64_t
++# define dtotimespec   dtotimespec_time64
++# include "dtotimespec.c"
++#endif
+diff --git a/support/dtotimespec.c b/support/dtotimespec.c
+new file mode 100644
+index 0000000000..cde5b4d74c
+--- /dev/null
++++ b/support/dtotimespec.c
+@@ -0,0 +1,50 @@
++/* Convert double to timespec.
++   Copyright (C) 2011-2023 Free Software Foundation, Inc.
++   This file is part of the GNU C Library and is also part of gnulib.
++   Patches to this file should be submitted to both projects.
++
++   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/>.  */
++
++/* Convert the double value SEC to a struct timespec.  Round toward
++   positive infinity.  On overflow, return an extremal value.  */
++
++#include <support/timespec.h>
++#include <intprops.h>
++
++struct timespec
++dtotimespec (double sec)
++{
++  if (sec <= TYPE_MINIMUM (time_t))
++    return make_timespec (TYPE_MINIMUM (time_t), 0);
++  else if (sec >= 1.0 + TYPE_MAXIMUM (time_t))
++    return make_timespec (TYPE_MAXIMUM (time_t), TIMESPEC_HZ - 1);
++  else
++    {
++      time_t s = sec;
++      double frac = TIMESPEC_HZ * (sec - s);
++      long ns = frac;
++      ns += ns < frac;
++      s += ns / TIMESPEC_HZ;
++      ns %= TIMESPEC_HZ;
++
++      if (ns < 0)
++        {
++          s--;
++          ns += TIMESPEC_HZ;
++        }
++
++      return make_timespec (s, ns);
++    }
++}
+diff --git a/support/shell-container.c b/support/shell-container.c
+index 1c73666f0a..6698061b9b 100644
+--- a/support/shell-container.c
++++ b/support/shell-container.c
+@@ -39,6 +39,7 @@
+ #include <error.h>
+ 
+ #include <support/support.h>
++#include <support/timespec.h>
+ 
+ /* Design considerations
+ 
+@@ -171,6 +172,32 @@ kill_func (char **argv)
+   return 0;
+ }
+ 
++/* Emulate the "/bin/sleep" command.  No suffix support.  Options are
++   ignored.  */
++static int
++sleep_func (char **argv)
++{
++  if (argv[0] == NULL)
++    {
++      fprintf (stderr, "sleep: missing operand\n");
++      return 1;
++    }
++  char *endptr = NULL;
++  double sec = strtod (argv[0], &endptr);
++  if (endptr == argv[0] || errno == ERANGE || sec < 0)
++    {
++      fprintf (stderr, "sleep: invalid time interval '%s'\n", argv[0]);
++      return 1;
++    }
++  struct timespec ts = dtotimespec (sec);
++  if (nanosleep (&ts, NULL) < 0)
++    {
++      fprintf (stderr, "sleep: failed to nanosleep: %s\n", strerror (errno));
++      return 1;
++    }
++  return 0;
++}
++
+ /* This is a list of all the built-in commands we understand.  */
+ static struct {
+   const char *name;
+@@ -181,6 +208,7 @@ static struct {
+   { "cp", copy_func },
+   { "exit", exit_func },
+   { "kill", kill_func },
++  { "sleep", sleep_func },
+   { NULL, NULL }
+ };
+ 
+diff --git a/support/timespec.h b/support/timespec.h
+index 4d2ac2737d..1bba3a6837 100644
+--- a/support/timespec.h
++++ b/support/timespec.h
+@@ -57,6 +57,8 @@ int support_timespec_check_in_range (struct timespec 
expected,
+                                    struct timespec observed,
+                                    double lower_bound, double upper_bound);
+ 
++struct timespec dtotimespec (double sec) __attribute__((const));
++
+ #else
+ struct timespec __REDIRECT (timespec_add, (struct timespec, struct timespec),
+                           timespec_add_time64);
+@@ -82,6 +84,8 @@ int __REDIRECT (support_timespec_check_in_range, (struct 
timespec expected,
+                                                 double lower_bound,
+                                                 double upper_bound),
+               support_timespec_check_in_range_time64);
++
++struct timespec __REDIRECT (dtotimespec, (double sec), dtotimespec_time64);
+ #endif
+ 
+ /* Check that the timespec on the left represents a time before the
 diff --git a/sysdeps/aarch64/dl-trampoline.S b/sysdeps/aarch64/dl-trampoline.S
 index 909b208578..d66f0b9c45 100644
 --- a/sysdeps/aarch64/dl-trampoline.S
@@ -5741,6 +7114,30 @@ index bcff909b2f..5cda9bb072 100644
            res->got_ipv6 = true;
        }
        at[count].next = at + count + 1;
+diff --git a/sysdeps/posix/system.c b/sysdeps/posix/system.c
+index 8014f63355..20c9420dd4 100644
+--- a/sysdeps/posix/system.c
++++ b/sysdeps/posix/system.c
+@@ -179,16 +179,16 @@ do_system (const char *line)
+       as if the shell had terminated using _exit(127).  */
+    status = W_EXITCODE (127, 0);
+ 
++  /* sigaction can not fail with SIGINT/SIGQUIT used with old
++     disposition.  Same applies for sigprocmask.  */
+   DO_LOCK ();
+   if (SUB_REF () == 0)
+     {
+-      /* sigaction can not fail with SIGINT/SIGQUIT used with old
+-       disposition.  Same applies for sigprocmask.  */
+       __sigaction (SIGINT, &intr, NULL);
+       __sigaction (SIGQUIT, &quit, NULL);
+-      __sigprocmask (SIG_SETMASK, &omask, NULL);
+     }
+   DO_UNLOCK ();
++  __sigprocmask (SIG_SETMASK, &omask, NULL);
+ 
+   if (ret != 0)
+     __set_errno (ret);
 diff --git a/sysdeps/powerpc/mod-tlsopt-powerpc.c 
b/sysdeps/powerpc/mod-tlsopt-powerpc.c
 index 2a82e53baf..d941024963 100644
 --- a/sysdeps/powerpc/mod-tlsopt-powerpc.c
@@ -5759,7 +7156,7 @@ index 2a82e53baf..d941024963 100644
    register unsigned long thread_pointer __asm__ ("r2");
    asm ("bcl 20,31,1f\n1:\t"
 diff --git a/sysdeps/unix/sysv/linux/Makefile 
b/sysdeps/unix/sysv/linux/Makefile
-index a139a16532..3ceda9fdbf 100644
+index a139a16532..d5d9af4de2 100644
 --- a/sysdeps/unix/sysv/linux/Makefile
 +++ b/sysdeps/unix/sysv/linux/Makefile
 @@ -265,6 +265,14 @@ $(objpfx)tst-mount-consts.out: 
../sysdeps/unix/sysv/linux/tst-mount-consts.py
@@ -5777,6 +7174,15 @@ index a139a16532..3ceda9fdbf 100644
  tst-rseq-disable-ENV = GLIBC_TUNABLES=glibc.pthread.rseq=0
  
  endif # $(subdir) == misc
+@@ -354,6 +362,8 @@ sysdep_headers += netinet/if_fddi.h netinet/if_tr.h \
+                 netrom/netrom.h netpacket/packet.h netrose/rose.h \
+                 neteconet/ec.h netiucv/iucv.h
+ sysdep_routines += netlink_assert_response
++
++CFLAGS-check_pf.c += -fexceptions
+ endif
+ 
+ # Don't compile the ctype glue code, since there is no old non-GNU C library.
 diff --git a/sysdeps/unix/sysv/linux/alpha/brk_call.h 
b/sysdeps/unix/sysv/linux/alpha/brk_call.h
 index b8088cf13f..0b851b6c86 100644
 --- a/sysdeps/unix/sysv/linux/alpha/brk_call.h
@@ -5938,6 +7344,19 @@ index 0000000000..30ee6279d2
 +
 +
 +#endif /* _BITS_STRUCT_STAT_H  */
+diff --git a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h 
b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h
+index 33ff88ce59..bfc674235d 100644
+--- a/sysdeps/unix/sysv/linux/bits/fcntl-linux.h
++++ b/sysdeps/unix/sysv/linux/bits/fcntl-linux.h
+@@ -101,7 +101,7 @@
+ #endif
+ 
+ #ifndef F_GETLK
+-# ifndef __USE_FILE_OFFSET64
++# if !defined __USE_FILE_OFFSET64 && __TIMESIZE != 64
+ #  define F_GETLK     5       /* Get record locking info.  */
+ #  define F_SETLK     6       /* Set record locking info (non-blocking).  */
+ #  define F_SETLKW    7       /* Set record locking info (blocking).  */
 diff --git a/sysdeps/unix/sysv/linux/bits/socket.h 
b/sysdeps/unix/sysv/linux/bits/socket.h
 index 4f1f810ea1..539b8d7716 100644
 --- a/sysdeps/unix/sysv/linux/bits/socket.h
@@ -6166,6 +7585,46 @@ index 25bd6cb638..fb11a3fba4 100644
  
 -
  #endif /* _BITS_STRUCT_STAT_H  */
+diff --git a/sysdeps/unix/sysv/linux/check_pf.c 
b/sysdeps/unix/sysv/linux/check_pf.c
+index fe73fe3ba8..ca20043408 100644
+--- a/sysdeps/unix/sysv/linux/check_pf.c
++++ b/sysdeps/unix/sysv/linux/check_pf.c
+@@ -292,6 +292,14 @@ make_request (int fd, pid_t pid)
+   return NULL;
+ }
+ 
++#ifdef __EXCEPTIONS
++static void
++cancel_handler (void *arg __attribute__((unused)))
++{
++  /* Release the lock.  */
++  __libc_lock_unlock (lock);
++}
++#endif
+ 
+ void
+ attribute_hidden
+@@ -304,6 +312,10 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6,
+   struct cached_data *olddata = NULL;
+   struct cached_data *data = NULL;
+ 
++#ifdef __EXCEPTIONS
++  /* Make sure that lock is released when the thread is cancelled.  */
++  __libc_cleanup_push (cancel_handler, NULL);
++#endif
+   __libc_lock_lock (lock);
+ 
+   if (cache_valid_p ())
+@@ -338,6 +350,9 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6,
+       }
+     }
+ 
++#ifdef __EXCEPTIONS
++  __libc_cleanup_pop (0);
++#endif
+   __libc_lock_unlock (lock);
+ 
+   if (data != NULL)
 diff --git a/sysdeps/unix/sysv/linux/cmsg_nxthdr.c 
b/sysdeps/unix/sysv/linux/cmsg_nxthdr.c
 index 15b7a3a925..24f72b797a 100644
 --- a/sysdeps/unix/sysv/linux/cmsg_nxthdr.c
@@ -6987,6 +8446,23 @@ index a263d294b1..cf35c8bfc9 100644
  __getrandom_nocancel (void *buf, size_t buflen, unsigned int flags)
  {
    return INLINE_SYSCALL_CALL (getrandom, buf, buflen, flags);
+diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h 
b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
+index d7cf158b33..49c8fac0fb 100644
+--- a/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
++++ b/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
+@@ -33,6 +33,12 @@
+ # define __O_LARGEFILE        0200000
+ #endif
+ 
++#if __WORDSIZE == 64
++# define F_GETLK      5
++# define F_SETLK      6
++# define F_SETLKW     7
++#endif
++
+ struct flock
+   {
+     short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.  */
 diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h 
b/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
 index bf4be80f8d..202520ee25 100644
 --- a/sysdeps/unix/sysv/linux/riscv/rv32/arch-syscall.h
@@ -7621,6 +9097,57 @@ index 037af22290..5711d1c312 100644
      TEST_VERIFY (fd > 0);
  
      char *path = xasprintf ("/proc/%d/fd/%d", pid, remote_fd);
+diff --git a/sysdeps/x86/dl-cacheinfo.h b/sysdeps/x86/dl-cacheinfo.h
+index e9f3382108..637b5a022d 100644
+--- a/sysdeps/x86/dl-cacheinfo.h
++++ b/sysdeps/x86/dl-cacheinfo.h
+@@ -861,6 +861,18 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
+      share of the cache, it has a substantial risk of negatively
+      impacting the performance of other threads running on the chip. */
+   unsigned long int non_temporal_threshold = shared * 3 / 4;
++  /* SIZE_MAX >> 4 because memmove-vec-unaligned-erms right-shifts the value 
of
++     'x86_non_temporal_threshold' by `LOG_4X_MEMCPY_THRESH` (4) and it is best
++     if that operation cannot overflow. Minimum of 0x4040 (16448) because the
++     L(large_memset_4x) loops need 64-byte to cache align and enough space for
++     at least 1 iteration of 4x PAGE_SIZE unrolled loop.  Both values are
++     reflected in the manual.  */
++  unsigned long int maximum_non_temporal_threshold = SIZE_MAX >> 4;
++  unsigned long int minimum_non_temporal_threshold = 0x4040;
++  if (non_temporal_threshold < minimum_non_temporal_threshold)
++    non_temporal_threshold = minimum_non_temporal_threshold;
++  else if (non_temporal_threshold > maximum_non_temporal_threshold)
++    non_temporal_threshold = maximum_non_temporal_threshold;
+ 
+ #if HAVE_TUNABLES
+   /* NB: The REP MOVSB threshold must be greater than VEC_SIZE * 8.  */
+@@ -915,8 +927,8 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
+     shared = tunable_size;
+ 
+   tunable_size = TUNABLE_GET (x86_non_temporal_threshold, long int, NULL);
+-  /* NB: Ignore the default value 0.  */
+-  if (tunable_size != 0)
++  if (tunable_size > minimum_non_temporal_threshold
++      && tunable_size <= maximum_non_temporal_threshold)
+     non_temporal_threshold = tunable_size;
+ 
+   tunable_size = TUNABLE_GET (x86_rep_movsb_threshold, long int, NULL);
+@@ -931,14 +943,9 @@ dl_init_cacheinfo (struct cpu_features *cpu_features)
+ 
+   TUNABLE_SET_WITH_BOUNDS (x86_data_cache_size, data, 0, SIZE_MAX);
+   TUNABLE_SET_WITH_BOUNDS (x86_shared_cache_size, shared, 0, SIZE_MAX);
+-  /* SIZE_MAX >> 4 because memmove-vec-unaligned-erms right-shifts the value 
of
+-     'x86_non_temporal_threshold' by `LOG_4X_MEMCPY_THRESH` (4) and it is best
+-     if that operation cannot overflow. Minimum of 0x4040 (16448) because the
+-     L(large_memset_4x) loops need 64-byte to cache align and enough space for
+-     at least 1 iteration of 4x PAGE_SIZE unrolled loop.  Both values are
+-     reflected in the manual.  */
+   TUNABLE_SET_WITH_BOUNDS (x86_non_temporal_threshold, non_temporal_threshold,
+-                         0x4040, SIZE_MAX >> 4);
++                         minimum_non_temporal_threshold,
++                         maximum_non_temporal_threshold);
+   TUNABLE_SET_WITH_BOUNDS (x86_rep_movsb_threshold, rep_movsb_threshold,
+                          minimum_rep_movsb_threshold, SIZE_MAX);
+   TUNABLE_SET_WITH_BOUNDS (x86_rep_stosb_threshold, rep_stosb_threshold, 1,
 diff --git a/sysdeps/x86/get-isa-level.h b/sysdeps/x86/get-isa-level.h
 index 1ade78ab73..5b4dd5f062 100644
 --- a/sysdeps/x86/get-isa-level.h
@@ -7648,6 +9175,28 @@ index 3c4480aba7..06f6c9663e 100644
  #define MOVBE_X86_ISA_LEVEL 3
  
  /* ISA level >= 2 guaranteed includes.  */
+diff --git a/sysdeps/x86_64/fpu/fraiseexcpt.c 
b/sysdeps/x86_64/fpu/fraiseexcpt.c
+index 864f4777a2..23446ff4ac 100644
+--- a/sysdeps/x86_64/fpu/fraiseexcpt.c
++++ b/sysdeps/x86_64/fpu/fraiseexcpt.c
+@@ -33,7 +33,7 @@ __feraiseexcept (int excepts)
+       /* One example of an invalid operation is 0.0 / 0.0.  */
+       float f = 0.0;
+ 
+-      __asm__ __volatile__ ("divss %0, %0 " : : "x" (f));
++      __asm__ __volatile__ ("divss %0, %0 " : "+x" (f));
+       (void) &f;
+     }
+ 
+@@ -43,7 +43,7 @@ __feraiseexcept (int excepts)
+       float f = 1.0;
+       float g = 0.0;
+ 
+-      __asm__ __volatile__ ("divss %1, %0" : : "x" (f), "x" (g));
++      __asm__ __volatile__ ("divss %1, %0" : "+x" (f) : "x" (g));
+       (void) &f;
+     }
+ 
 diff --git a/sysdeps/x86_64/multiarch/ifunc-avx2.h 
b/sysdeps/x86_64/multiarch/ifunc-avx2.h
 index a57a9952f3..f2f5e8a211 100644
 --- a/sysdeps/x86_64/multiarch/ifunc-avx2.h
@@ -8027,6 +9576,27 @@ index 4ebe4bde30..c4f8b6bbb5 100644
        return OPTIMIZE (evex);
  
        if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
+diff --git a/time/Makefile b/time/Makefile
+index 470275b90c..2f4aa2d528 100644
+--- a/time/Makefile
++++ b/time/Makefile
+@@ -50,7 +50,7 @@ tests        := test_time clocktest tst-posixtz tst-strptime 
tst_wcsftime \
+          tst-clock tst-clock2 tst-clock_nanosleep tst-cpuclock1 \
+          tst-adjtime tst-ctime tst-difftime tst-mktime4 tst-clock_settime \
+          tst-settimeofday tst-itimer tst-gmtime tst-timegm \
+-         tst-timespec_get tst-timespec_getres
++         tst-timespec_get tst-timespec_getres tst-strftime4
+ 
+ tests-time64 := \
+   tst-adjtime-time64 \
+@@ -65,6 +65,7 @@ tests-time64 := \
+   tst-itimer-time64 \
+   tst-mktime4-time64 \
+   tst-settimeofday-time64 \
++  tst-strftime4-time64 \
+   tst-timegm-time64 \
+   tst-timespec_get-time64 \
+   tst-timespec_getres-time64 \
 diff --git a/time/mktime.c b/time/mktime.c
 index 494c89bf54..e9a6006710 100644
 --- a/time/mktime.c
@@ -8080,6 +9650,102 @@ index 494c89bf54..e9a6006710 100644
        __set_errno (EOVERFLOW);
        return -1;
      }
+diff --git a/time/strftime_l.c b/time/strftime_l.c
+index 75554fee7c..4d7c4ea828 100644
+--- a/time/strftime_l.c
++++ b/time/strftime_l.c
+@@ -159,6 +159,10 @@ extern char *tzname[];
+ #ifdef _LIBC
+ # define tzname __tzname
+ # define tzset __tzset
++
++# define time_t __time64_t
++# define __gmtime_r(t, tp) __gmtime64_r (t, tp)
++# define mktime(tp) __mktime64 (tp)
+ #endif
+ 
+ #if !HAVE_TM_GMTOFF
+diff --git a/time/strptime_l.c b/time/strptime_l.c
+index a3c5681fc2..f927448204 100644
+--- a/time/strptime_l.c
++++ b/time/strptime_l.c
+@@ -30,8 +30,10 @@
+ #ifdef _LIBC
+ # define HAVE_LOCALTIME_R 0
+ # include "../locale/localeinfo.h"
+-#endif
+ 
++# define time_t __time64_t
++# define __localtime_r(t, tp) __localtime64_r (t, tp)
++#endif
+ 
+ #if ! HAVE_LOCALTIME_R && ! defined localtime_r
+ # ifdef _LIBC
+diff --git a/time/tst-strftime4-time64.c b/time/tst-strftime4-time64.c
+new file mode 100644
+index 0000000000..4d47ee7d79
+--- /dev/null
++++ b/time/tst-strftime4-time64.c
+@@ -0,0 +1 @@
++#include "tst-strftime4.c"
+diff --git a/time/tst-strftime4.c b/time/tst-strftime4.c
+new file mode 100644
+index 0000000000..659716d0fa
+--- /dev/null
++++ b/time/tst-strftime4.c
+@@ -0,0 +1,52 @@
++/* Test strftime and strptime after 2038-01-19 03:14:07 UTC (bug 30053).
++   Copyright (C) 2023 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 <time.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <string.h>
++#include <support/check.h>
++
++static int
++do_test (void)
++{
++  TEST_VERIFY_EXIT (setenv ("TZ", "UTC0", 1) == 0);
++  tzset ();
++  if (sizeof (time_t) > 4)
++    {
++      time_t wrap = (time_t) 2147483648LL;
++      char buf[80];
++      struct tm *tm = gmtime (&wrap);
++      TEST_VERIFY_EXIT (tm != NULL);
++      TEST_VERIFY_EXIT (strftime (buf, sizeof buf, "%s", tm) > 0);
++      puts (buf);
++      TEST_VERIFY (strcmp (buf, "2147483648") == 0);
++
++      struct tm tm2;
++      char *p = strptime (buf, "%s", &tm2);
++      TEST_VERIFY_EXIT (p != NULL && *p == '\0');
++      time_t t = mktime (&tm2);
++      printf ("%lld\n", (long long) t);
++      TEST_VERIFY (t == wrap);
++    }
++  else
++    FAIL_UNSUPPORTED ("32-bit time_t");
++  return 0;
++}
++
++#include <support/test-driver.c>
 diff --git a/time/tzfile.c b/time/tzfile.c
 index dd75848ba9..8bba4e5b8d 100644
 --- a/time/tzfile.c
diff --git a/debian/po/sk.po b/debian/po/sk.po
index 94997be8..3afd580b 100644
--- a/debian/po/sk.po
+++ b/debian/po/sk.po
@@ -9,7 +9,7 @@ msgstr ""
 "Report-Msgid-Bugs-To: gl...@packages.debian.org\n"
 "POT-Creation-Date: 2023-01-03 21:34+0100\n"
 "PO-Revision-Date: 2012-06-17 20:43+0100\n"
-"Last-Translator: Marek Sýkora <marek.sykor...@gmail.com>\n"
+"Last-Translator: Andrej Shadura <andre...@debian.org>\n"
 "Language-Team: Slovak <debian-l10n-slo...@lists.debian.org>\n"
 "Language: sk\n"
 "MIME-Version: 1.0\n"
@@ -60,7 +60,7 @@ msgstr "žiadne"
 #. Description
 #: ../debhelper.in/locales.templates:2002
 msgid "Default locale for the system environment:"
-msgstr "Štandarné locale systémového prostredia:"
+msgstr "Štandardné locale systémového prostredia:"
 
 #. Type: select
 #. Description
@@ -83,7 +83,7 @@ msgid ""
 "language, they will experience difficulties."
 msgstr ""
 "Týmto vyberiete štandardný jazyk pre celý systém. Ak je toto "
-"viacpoužívateľský systém, kde nie všetci používatelia hovoria štandarným "
+"viacpoužívateľský systém, kde nie všetci používatelia hovoria štandardným "
 "jazykom, môžu mať ťažkosti."
 
 #. Type: boolean
@@ -254,9 +254,9 @@ msgid ""
 "later.  Please upgrade your kernel and reboot before installing glibc. You "
 "may need to use \"apt -f install\" after reboot to solve dependencies."
 msgstr ""
-"Táto verzia GNU libc vyžduje verziu kernelu ${kernel_ver} alebo "
+"Táto verzia GNU libc vyžaduje verziu kernelu ${kernel_ver} alebo "
 "neskoršiu. Aktualizujte prosím Váš kernel a reštartujte systém pred 
inštaláciou glibc. V prípade "
-"chíbajúcich závisostí po reštarte, použite príkaz \"apt -f install\"."
+"chýbajúcich závislostí po reštarte, použite príkaz \"apt -f install\"."
 
 #. Type: note
 #. Description
@@ -272,6 +272,6 @@ msgid ""
 "later.  Older versions might work but are not officially supported by "
 "Debian.  Please consider upgrading your kernel."
 msgstr ""
-"Táto verzia GNU libc vyžduje verziu kernelu ${kernel_ver} alebo "
+"Táto verzia GNU libc vyžaduje verziu kernelu ${kernel_ver} alebo "
 "neskoršiu. Staršia verzia môže fungovať, ale nie je oficiálne podporovaná "
-"Debianom. Zvážte prosím aktualizáciu vašeho kernelu. "
+"Debianom. Zvážte prosím aktualizáciu vášho kernelu. "

Reply via email to