From 315fcab4e827e2c652e35099f858779aaeb41ee5 Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Mon, 14 Nov 2022 17:04:18 +0100 Subject: [PATCH] Sync with upstream branch release/2.34/master Upstream commit: 75b0edb7ef338084e53925139ae81fb0dfc07dd4 - Update NEWS file in the right place - Linux: Support __IPC_64 in sysvctl *ctl command arguments (bug 29771) - io: Fix use-after-free in ftw [BZ #26779] - io: Fix ftw internal realloc buffer (BZ #28126) - regex: fix buffer read overrun in search [BZ#28470] - regex: copy back from Gnulib - Allow #pragma GCC in headers in conformtest - Fix memmove call in vfprintf-internal.c:group_number - mktime: improve heuristic for ca-1986 Indiana DST - Makerules: fix MAKEFLAGS assignment for upcoming make-4.4 [BZ# 29564] - linux: Fix generic struct_stat for 64 bit time (BZ# 29657) - elf: Do not completely clear reused namespace in dlmopen (bug 29600) - nss: Use shared prefix in IPv4 address in tst-reload1 - nss: Fix tst-nss-files-hosts-long on single-stack hosts (bug 24816) - nss: Implement --no-addrconfig option for getent --- glibc-upstream-2.34-346.patch | 55 +++ glibc-upstream-2.34-347.patch | 38 ++ glibc-upstream-2.34-348.patch | 47 ++ glibc-upstream-2.34-349.patch | 92 ++++ glibc-upstream-2.34-350.patch | 861 ++++++++++++++++++++++++++++++++++ glibc-upstream-2.34-351.patch | 107 +++++ glibc-upstream-2.34-352.patch | 73 +++ glibc-upstream-2.34-353.patch | 86 ++++ glibc-upstream-2.34-354.patch | 35 ++ glibc-upstream-2.34-355.patch | 629 +++++++++++++++++++++++++ glibc-upstream-2.34-356.patch | 30 ++ glibc-upstream-2.34-357.patch | 203 ++++++++ glibc-upstream-2.34-358.patch | 25 + glibc-upstream-2.34-359.patch | 221 +++++++++ glibc.spec | 36 +- 15 files changed, 2537 insertions(+), 1 deletion(-) create mode 100644 glibc-upstream-2.34-346.patch create mode 100644 glibc-upstream-2.34-347.patch create mode 100644 glibc-upstream-2.34-348.patch create mode 100644 glibc-upstream-2.34-349.patch create mode 100644 glibc-upstream-2.34-350.patch create mode 100644 glibc-upstream-2.34-351.patch create mode 100644 glibc-upstream-2.34-352.patch create mode 100644 glibc-upstream-2.34-353.patch create mode 100644 glibc-upstream-2.34-354.patch create mode 100644 glibc-upstream-2.34-355.patch create mode 100644 glibc-upstream-2.34-356.patch create mode 100644 glibc-upstream-2.34-357.patch create mode 100644 glibc-upstream-2.34-358.patch create mode 100644 glibc-upstream-2.34-359.patch diff --git a/glibc-upstream-2.34-346.patch b/glibc-upstream-2.34-346.patch new file mode 100644 index 0000000..a0fe300 --- /dev/null +++ b/glibc-upstream-2.34-346.patch @@ -0,0 +1,55 @@ +commit c95ef423d78d9a2ec0a8e4141c78165434685c6f +Author: Florian Weimer +Date: Tue Sep 13 16:10:20 2022 +0200 + + nss: Implement --no-addrconfig option for getent + + The ahosts, ahostsv4, ahostsv6 commands unconditionally pass + AI_ADDRCONFIG to getaddrinfo, which is not always desired. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit a623f13adfac47c8634a7288e08f821a846bc650) + +diff --git a/nss/getent.c b/nss/getent.c +index ec48ba4bf1f5f788..0f4d549b05da73ac 100644 +--- a/nss/getent.c ++++ b/nss/getent.c +@@ -59,6 +59,8 @@ static const struct argp_option args_options[] = + { + { "service", 's', N_("CONFIG"), 0, N_("Service configuration to be used") }, + { "no-idn", 'i', NULL, 0, N_("disable IDN encoding") }, ++ { "no-addrconfig", 'A', NULL, 0, ++ N_("do not filter out unsupported IPv4/IPv6 addresses (with ahosts*)") }, + { NULL, 0, NULL, 0, NULL }, + }; + +@@ -80,6 +82,9 @@ static struct argp argp = + /* Additional getaddrinfo flags for IDN encoding. */ + static int idn_flags = AI_IDN | AI_CANONIDN; + ++/* Set to 0 by --no-addrconfig. */ ++static int addrconfig_flags = AI_ADDRCONFIG; ++ + /* Print the version information. */ + static void + print_version (FILE *stream, struct argp_state *state) +@@ -347,7 +352,7 @@ ahosts_keys_int (int af, int xflags, int number, char *key[]) + + struct addrinfo hint; + memset (&hint, '\0', sizeof (hint)); +- hint.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME ++ hint.ai_flags = (AI_V4MAPPED | addrconfig_flags | AI_CANONNAME + | idn_flags | xflags); + hint.ai_family = af; + +@@ -906,6 +911,10 @@ parse_option (int key, char *arg, struct argp_state *state) + idn_flags = 0; + break; + ++ case 'A': ++ addrconfig_flags = 0; ++ break; ++ + default: + return ARGP_ERR_UNKNOWN; + } diff --git a/glibc-upstream-2.34-347.patch b/glibc-upstream-2.34-347.patch new file mode 100644 index 0000000..408e38f --- /dev/null +++ b/glibc-upstream-2.34-347.patch @@ -0,0 +1,38 @@ +commit 16c7ed6e68c13e5a5efd8ab464ebf9d07b4b0bb3 +Author: Florian Weimer +Date: Tue Sep 13 16:11:40 2022 +0200 + + nss: Fix tst-nss-files-hosts-long on single-stack hosts (bug 24816) + + getent implicitly passes AI_ADDRCONFIG to getaddrinfo by default. + Use --no-addrconfig to suppress that, so that both IPv4 and IPv6 + lookups succeed even if the address family is not supported by the + host. + + Reviewed-by: Carlos O'Donell + (cherry picked from commit c75d20b5b27b0a60f0678236f51a4d3b0b058c00) + +diff --git a/nss/tst-nss-files-hosts-long.c b/nss/tst-nss-files-hosts-long.c +index 00f8bea409e0b4cb..42676ba4056dbde2 100644 +--- a/nss/tst-nss-files-hosts-long.c ++++ b/nss/tst-nss-files-hosts-long.c +@@ -28,14 +28,15 @@ do_test (void) + { + int ret; + +- /* Run getent to fetch the IPv4 address for host test4. +- This forces /etc/hosts to be parsed. */ +- ret = system("getent ahostsv4 test4"); ++ /* Run getent to fetch the IPv4 address for host test4. This forces ++ /etc/hosts to be parsed. Use --no-addrconfig to return addresses ++ even in an IPv6-only environment. */ ++ ret = system("getent --no-addrconfig ahostsv4 test4"); + if (ret != 0) + FAIL_EXIT1("ahostsv4 failed"); + + /* Likewise for IPv6. */ +- ret = system("getent ahostsv6 test6"); ++ ret = system("getent --no-addrconfig ahostsv6 test6"); + if (ret != 0) + FAIL_EXIT1("ahostsv6 failed"); + diff --git a/glibc-upstream-2.34-348.patch b/glibc-upstream-2.34-348.patch new file mode 100644 index 0000000..c33b026 --- /dev/null +++ b/glibc-upstream-2.34-348.patch @@ -0,0 +1,47 @@ +commit d5313bcb7e56cd949ca920bb0c741a1d1d4093cf +Author: Florian Weimer +Date: Fri Sep 23 19:30:57 2022 +0200 + + nss: Use shared prefix in IPv4 address in tst-reload1 + + Otherwise, sorting based on the longest-matching prefix in + getaddrinfo can reorder the addresses in ways the test does not + expect, depending on the IPv4 address of the host. + + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit c02e29a0ba47d636281e1a026444a1a0a254aa12) + +diff --git a/nss/tst-reload1.c b/nss/tst-reload1.c +index 27a18ed9c37607bb..844cfcddc5e0f638 100644 +--- a/nss/tst-reload1.c ++++ b/nss/tst-reload1.c +@@ -43,12 +43,12 @@ static struct passwd pwd_table_1[] = { + + static const char *hostaddr_5[] = + { +- "ABCD", "abcd", "1234", NULL ++ "ABCd", "ABCD", "ABC4", NULL + }; + + static const char *hostaddr_15[] = + { +- "4321", "ghij", NULL ++ "4321", "4322", NULL + }; + + static const char *hostaddr_25[] = +@@ -86,12 +86,12 @@ static const char *hostaddr_6[] = + + static const char *hostaddr_16[] = + { +- "7890", "a1b2", NULL ++ "7890", "7891", NULL + }; + + static const char *hostaddr_26[] = + { +- "qwer", "tyui", NULL ++ "qwer", "qweR", NULL + }; + + static struct hostent host_table_2[] = { diff --git a/glibc-upstream-2.34-349.patch b/glibc-upstream-2.34-349.patch new file mode 100644 index 0000000..0b05961 --- /dev/null +++ b/glibc-upstream-2.34-349.patch @@ -0,0 +1,92 @@ +commit 9f55d2e7c42e6ca862a25d3ee3eb2b367811c30d +Author: Florian Weimer +Date: Fri Oct 14 12:43:07 2022 +0200 + + elf: Do not completely clear reused namespace in dlmopen (bug 29600) + + The data in the _ns_debug member must be preserved, otherwise + _dl_debug_initialize enters an infinite loop. To be conservative, + only clear the libc_map member for now, to fix bug 29528. + + Fixes commit d0e357ff45a75553dee3b17ed7d303bfa544f6fe + ("elf: Call __libc_early_init for reused namespaces (bug 29528)"), + by reverting most of it. + + Reviewed-by: Carlos O'Donell + Tested-by: Carlos O'Donell + (cherry picked from commit 2c42257314536b94cc8d52edede86e94e98c1436) + (Conflict in elf/dl-open.c due to missing _r_debug namespace support.) + +diff --git a/elf/dl-open.c b/elf/dl-open.c +index 1ab3c7b5ac2fbc45..633b047ad2497296 100644 +--- a/elf/dl-open.c ++++ b/elf/dl-open.c +@@ -839,15 +839,13 @@ _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, + _dl_signal_error (EINVAL, file, NULL, N_("\ + no more namespaces available for dlmopen()")); + } ++ else if (nsid == GL(dl_nns)) ++ { ++ __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock); ++ ++GL(dl_nns); ++ } + +- if (nsid == GL(dl_nns)) +- ++GL(dl_nns); +- +- /* Initialize the new namespace. Most members are +- zero-initialized, only the lock needs special treatment. */ +- memset (&GL(dl_ns)[nsid], 0, sizeof (GL(dl_ns)[nsid])); +- __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock); +- ++ GL(dl_ns)[nsid].libc_map = NULL; + _dl_debug_initialize (0, nsid)->r_state = RT_CONSISTENT; + } + /* Never allow loading a DSO in a namespace which is empty. Such +diff --git a/elf/tst-dlmopen-twice.c b/elf/tst-dlmopen-twice.c +index 449f3c8fa9f2aa01..70c71fe19c7d0bf9 100644 +--- a/elf/tst-dlmopen-twice.c ++++ b/elf/tst-dlmopen-twice.c +@@ -16,18 +16,38 @@ + License along with the GNU C Library; if not, see + . */ + +-#include ++#include + #include ++#include + +-static int +-do_test (void) ++/* Run the test multiple times, to check finding a new namespace while ++ another namespace is already in use. This used to trigger bug 29600. */ ++static void ++recurse (int depth) + { +- void *handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod1.so", RTLD_NOW); ++ if (depth == 0) ++ return; ++ ++ printf ("info: running at depth %d\n", depth); ++ void *handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod1.so", ++ RTLD_NOW); + xdlclose (handle); + handle = xdlmopen (LM_ID_NEWLM, "tst-dlmopen-twice-mod2.so", RTLD_NOW); + int (*run_check) (void) = xdlsym (handle, "run_check"); + TEST_COMPARE (run_check (), 0); ++ recurse (depth - 1); + xdlclose (handle); ++} ++ ++static int ++do_test (void) ++{ ++ /* First run the test without nesting. */ ++ recurse (1); ++ ++ /* Then with nesting. The constant needs to be less than the ++ internal DL_NNS namespace constant. */ ++ recurse (10); + return 0; + } + diff --git a/glibc-upstream-2.34-350.patch b/glibc-upstream-2.34-350.patch new file mode 100644 index 0000000..7ab515b --- /dev/null +++ b/glibc-upstream-2.34-350.patch @@ -0,0 +1,861 @@ +commit ca5df795459b9242cd7d787ebf71a09be2244577 +Author: Adhemerval Zanella +Date: Wed Oct 19 19:14:04 2022 -0300 + + linux: Fix generic struct_stat for 64 bit time (BZ# 29657) + + The generic Linux struct_stat misses the conditionals to use + bits/struct_stat_time64_helper.h in the __USE_TIME_BITS64 for + architecture that uses __TIMESIZE == 32 (currently csky and nios2). + + Since newer ports should not support 32 bit time_t, the generic + implementation should be used as default. + + For arm, hppa, and sh a copy of default struct_stat is added, + while for csky and nios a new one based on generic is used, along + with conditionals to use bits/struct_stat_time64_helper.h. + + The default struct_stat is also replaced with the generic one. + + Checked on aarch64-linux-gnu and arm-linux-gnueabihf. + + (cherry picked from commit 7a6ca82f8007ddbd43e2b8fce806ba7101ee47f5) + +diff --git a/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h b/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h +new file mode 100644 +index 0000000000000000..30ee6279d2701242 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/arm/bits/struct_stat.h +@@ -0,0 +1,139 @@ ++/* Definition for struct stat. Linux/arm version. ++ Copyright (C) 2020-2022 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 ++ . */ ++ ++#if !defined _SYS_STAT_H && !defined _FCNTL_H ++# error "Never include directly; use instead." ++#endif ++ ++#ifndef _BITS_STRUCT_STAT_H ++#define _BITS_STRUCT_STAT_H 1 ++ ++#include ++#include ++ ++struct stat ++ { ++#ifdef __USE_TIME_BITS64 ++# include ++#else ++ __dev_t st_dev; /* Device. */ ++ unsigned short int __pad1; ++# ifndef __USE_FILE_OFFSET64 ++ __ino_t st_ino; /* File serial number. */ ++# else ++ __ino_t __st_ino; /* 32bit file serial number. */ ++# endif ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ unsigned short int __pad2; ++# ifndef __USE_FILE_OFFSET64 ++ __off_t st_size; /* Size of file, in bytes. */ ++# else ++ __off64_t st_size; /* Size of file, in bytes. */ ++# endif ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ ++# ifndef __USE_FILE_OFFSET64 ++ __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */ ++# else ++ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ ++# endif ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++# ifndef __USE_FILE_OFFSET64 ++ unsigned long int __glibc_reserved4; ++ unsigned long int __glibc_reserved5; ++# else ++ __ino64_t st_ino; /* File serial number. */ ++# endif ++#endif /* __USE_TIME_BITS64 */ ++ }; ++ ++#ifdef __USE_LARGEFILE64 ++struct stat64 ++ { ++# ifdef __USE_TIME_BITS64 ++# include ++# else ++ __dev_t st_dev; /* Device. */ ++ unsigned int __pad1; ++ ++ __ino_t __st_ino; /* 32bit file serial number. */ ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ unsigned int __pad2; ++ __off64_t st_size; /* Size of file, in bytes. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ ++ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++ __ino64_t st_ino; /* File serial number. */ ++# endif /* __USE_TIME_BITS64 */ ++ }; ++#endif ++ ++/* Tell code we have these members. */ ++#define _STATBUF_ST_BLKSIZE ++#define _STATBUF_ST_RDEV ++/* Nanosecond resolution time values are supported. */ ++#define _STATBUF_ST_NSEC ++ ++ ++#endif /* _BITS_STRUCT_STAT_H */ +diff --git a/sysdeps/unix/sysv/linux/bits/struct_stat.h b/sysdeps/unix/sysv/linux/bits/struct_stat.h +index 298418966f4d6e0b..32ef511ae5728276 100644 +--- a/sysdeps/unix/sysv/linux/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/bits/struct_stat.h +@@ -26,37 +26,36 @@ + #include + #include + +-struct stat +- { +-#ifdef __USE_TIME_BITS64 +-# include +-#else +- __dev_t st_dev; /* Device. */ +- unsigned short int __pad1; +-# ifndef __USE_FILE_OFFSET64 +- __ino_t st_ino; /* File serial number. */ +-# else +- __ino_t __st_ino; /* 32bit file serial number. */ ++#if defined __USE_FILE_OFFSET64 ++# define __field64(type, type64, name) type64 name ++#elif __WORDSIZE == 64 || defined __INO_T_MATCHES_INO64_T ++# if defined __INO_T_MATCHES_INO64_T && !defined __OFF_T_MATCHES_OFF64_T ++# error "ino_t and off_t must both be the same type" + # endif +- __mode_t st_mode; /* File mode. */ +- __nlink_t st_nlink; /* Link count. */ +- __uid_t st_uid; /* User ID of the file's owner. */ +- __gid_t st_gid; /* Group ID of the file's group.*/ +- __dev_t st_rdev; /* Device number, if device. */ +- unsigned short int __pad2; +-# ifndef __USE_FILE_OFFSET64 +- __off_t st_size; /* Size of file, in bytes. */ +-# else +- __off64_t st_size; /* Size of file, in bytes. */ +-# endif +- __blksize_t st_blksize; /* Optimal block size for I/O. */ ++# define __field64(type, type64, name) type name ++#elif __BYTE_ORDER == __LITTLE_ENDIAN ++# define __field64(type, type64, name) \ ++ type name __attribute__((__aligned__ (__alignof__ (type64)))); int __##name##_pad ++#else ++# define __field64(type, type64, name) \ ++ int __##name##_pad __attribute__((__aligned__ (__alignof__ (type64)))); type name ++#endif + +-# ifndef __USE_FILE_OFFSET64 +- __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */ +-# else +- __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ +-# endif +-# ifdef __USE_XOPEN2K8 ++struct stat ++ { ++ __dev_t st_dev; /* Device. */ ++ __field64(__ino_t, __ino64_t, st_ino); /* File serial number. */ ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ __dev_t __pad1; ++ __field64(__off_t, __off64_t, st_size); /* Size of file, in bytes. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ int __pad2; ++ __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */ ++#ifdef __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the +@@ -66,47 +65,38 @@ struct stat + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +-# define st_atime st_atim.tv_sec /* Backward compatibility. */ +-# define st_mtime st_mtim.tv_sec +-# define st_ctime st_ctim.tv_sec +-# else ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++#else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +-# endif +-# ifndef __USE_FILE_OFFSET64 +- unsigned long int __glibc_reserved4; +- unsigned long int __glibc_reserved5; +-# else +- __ino64_t st_ino; /* File serial number. */ +-# endif +-#endif /* __USE_TIME_BITS64 */ ++#endif ++ int __glibc_reserved[2]; + }; + ++#undef __field64 ++ + #ifdef __USE_LARGEFILE64 + struct stat64 + { +-# ifdef __USE_TIME_BITS64 +-# include +-# else +- __dev_t st_dev; /* Device. */ +- unsigned int __pad1; +- +- __ino_t __st_ino; /* 32bit file serial number. */ +- __mode_t st_mode; /* File mode. */ +- __nlink_t st_nlink; /* Link count. */ +- __uid_t st_uid; /* User ID of the file's owner. */ +- __gid_t st_gid; /* Group ID of the file's group.*/ +- __dev_t st_rdev; /* Device number, if device. */ +- unsigned int __pad2; +- __off64_t st_size; /* Size of file, in bytes. */ +- __blksize_t st_blksize; /* Optimal block size for I/O. */ +- +- __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ +-# ifdef __USE_XOPEN2K8 ++ __dev_t st_dev; /* Device. */ ++ __ino64_t st_ino; /* File serial number. */ ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ __dev_t __pad1; ++ __off64_t st_size; /* Size of file, in bytes. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ int __pad2; ++ __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */ ++#ifdef __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the +@@ -116,16 +106,15 @@ struct stat64 + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +-# else ++#else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +-# endif +- __ino64_t st_ino; /* File serial number. */ +-# endif /* __USE_TIME_BITS64 */ ++#endif ++ int __glibc_reserved[2]; + }; + #endif + +@@ -135,5 +124,4 @@ struct stat64 + /* Nanosecond resolution time values are supported. */ + #define _STATBUF_ST_NSEC + +- + #endif /* _BITS_STRUCT_STAT_H */ +diff --git a/sysdeps/unix/sysv/linux/generic/bits/struct_stat.h b/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h +similarity index 91% +rename from sysdeps/unix/sysv/linux/generic/bits/struct_stat.h +rename to sysdeps/unix/sysv/linux/csky/bits/struct_stat.h +index 32ef511ae5728276..f0ee455748d3ee41 100644 +--- a/sysdeps/unix/sysv/linux/generic/bits/struct_stat.h ++++ b/sysdeps/unix/sysv/linux/csky/bits/struct_stat.h +@@ -1,5 +1,5 @@ +-/* Definition for struct stat. +- Copyright (C) 2020-2021 Free Software Foundation, Inc. ++/* Definition for struct stat. Linux/csky version. ++ Copyright (C) 2020-2022 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 +@@ -43,6 +43,9 @@ + + struct stat + { ++#ifdef __USE_TIME_BITS64 ++# include ++#else + __dev_t st_dev; /* Device. */ + __field64(__ino_t, __ino64_t, st_ino); /* File serial number. */ + __mode_t st_mode; /* File mode. */ +@@ -55,7 +58,7 @@ struct stat + __blksize_t st_blksize; /* Optimal block size for I/O. */ + int __pad2; + __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */ +-#ifdef __USE_XOPEN2K8 ++# ifdef __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the +@@ -65,18 +68,19 @@ struct stat + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +-# define st_atime st_atim.tv_sec /* Backward compatibility. */ +-# define st_mtime st_mtim.tv_sec +-# define st_ctime st_ctim.tv_sec +-#else ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++# else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +-#endif ++# endif + int __glibc_reserved[2]; ++#endif + }; + + #undef __field64 +@@ -84,6 +88,9 @@ struct stat + #ifdef __USE_LARGEFILE64 + struct stat64 + { ++# ifdef __USE_TIME_BITS64 ++# include ++# else + __dev_t st_dev; /* Device. */ + __ino64_t st_ino; /* File serial number. */ + __mode_t st_mode; /* File mode. */ +@@ -96,7 +103,7 @@ struct stat64 + __blksize_t st_blksize; /* Optimal block size for I/O. */ + int __pad2; + __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */ +-#ifdef __USE_XOPEN2K8 ++# ifdef __USE_XOPEN2K8 + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the +@@ -106,15 +113,16 @@ struct stat64 + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +-#else ++# else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +-#endif ++# endif + int __glibc_reserved[2]; ++# endif + }; + #endif + +diff --git a/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h b/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h +new file mode 100644 +index 0000000000000000..38b6e13e68890c29 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/hppa/bits/struct_stat.h +@@ -0,0 +1,139 @@ ++/* Definition for struct stat. Linux/hppa version. ++ Copyright (C) 2020-2022 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 ++ . */ ++ ++#if !defined _SYS_STAT_H && !defined _FCNTL_H ++# error "Never include directly; use instead." ++#endif ++ ++#ifndef _BITS_STRUCT_STAT_H ++#define _BITS_STRUCT_STAT_H 1 ++ ++#include ++#include ++ ++struct stat ++ { ++#ifdef __USE_TIME_BITS64 ++# include ++#else ++ __dev_t st_dev; /* Device. */ ++ unsigned short int __pad1; ++# ifndef __USE_FILE_OFFSET64 ++ __ino_t st_ino; /* File serial number. */ ++# else ++ __ino_t __st_ino; /* 32bit file serial number. */ ++# endif ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ unsigned short int __pad2; ++# ifndef __USE_FILE_OFFSET64 ++ __off_t st_size; /* Size of file, in bytes. */ ++# else ++ __off64_t st_size; /* Size of file, in bytes. */ ++# endif ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ ++# ifndef __USE_FILE_OFFSET64 ++ __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */ ++# else ++ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ ++# endif ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++# ifndef __USE_FILE_OFFSET64 ++ unsigned long int __glibc_reserved4; ++ unsigned long int __glibc_reserved5; ++# else ++ __ino64_t st_ino; /* File serial number. */ ++# endif ++#endif /* __USE_TIME_BITS64 */ ++ }; ++ ++#ifdef __USE_LARGEFILE64 ++struct stat64 ++ { ++# ifdef __USE_TIME_BITS64 ++# include ++# else ++ __dev_t st_dev; /* Device. */ ++ unsigned int __pad1; ++ ++ __ino_t __st_ino; /* 32bit file serial number. */ ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ unsigned int __pad2; ++ __off64_t st_size; /* Size of file, in bytes. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ ++ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++ __ino64_t st_ino; /* File serial number. */ ++# endif /* __USE_TIME_BITS64 */ ++ }; ++#endif ++ ++/* Tell code we have these members. */ ++#define _STATBUF_ST_BLKSIZE ++#define _STATBUF_ST_RDEV ++/* Nanosecond resolution time values are supported. */ ++#define _STATBUF_ST_NSEC ++ ++ ++#endif /* _BITS_STRUCT_STAT_H */ +diff --git a/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h b/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h +new file mode 100644 +index 0000000000000000..e00e71173e184b48 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/nios2/bits/struct_stat.h +@@ -0,0 +1,135 @@ ++/* Definition for struct stat. Linux/nios2 version. ++ Copyright (C) 2020-2022 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 ++ . */ ++ ++#if !defined _SYS_STAT_H && !defined _FCNTL_H ++# error "Never include directly; use instead." ++#endif ++ ++#ifndef _BITS_STRUCT_STAT_H ++#define _BITS_STRUCT_STAT_H 1 ++ ++#include ++#include ++ ++#if defined __USE_FILE_OFFSET64 ++# define __field64(type, type64, name) type64 name ++#elif __WORDSIZE == 64 || defined __INO_T_MATCHES_INO64_T ++# if defined __INO_T_MATCHES_INO64_T && !defined __OFF_T_MATCHES_OFF64_T ++# error "ino_t and off_t must both be the same type" ++# endif ++# define __field64(type, type64, name) type name ++#elif __BYTE_ORDER == __LITTLE_ENDIAN ++# define __field64(type, type64, name) \ ++ type name __attribute__((__aligned__ (__alignof__ (type64)))); int __##name##_pad ++#else ++# define __field64(type, type64, name) \ ++ int __##name##_pad __attribute__((__aligned__ (__alignof__ (type64)))); type name ++#endif ++ ++struct stat ++ { ++#ifdef __USE_TIME_BITS64 ++# include ++#else ++ __dev_t st_dev; /* Device. */ ++ __field64(__ino_t, __ino64_t, st_ino); /* File serial number. */ ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ __dev_t __pad1; ++ __field64(__off_t, __off64_t, st_size); /* Size of file, in bytes. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ int __pad2; ++ __field64(__blkcnt_t, __blkcnt64_t, st_blocks); /* 512-byte blocks */ ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++ int __glibc_reserved[2]; ++#endif ++ }; ++ ++#undef __field64 ++ ++#ifdef __USE_LARGEFILE64 ++struct stat64 ++ { ++# ifdef __USE_TIME_BITS64 ++# include ++# else ++ __dev_t st_dev; /* Device. */ ++ __ino64_t st_ino; /* File serial number. */ ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ __dev_t __pad1; ++ __off64_t st_size; /* Size of file, in bytes. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ int __pad2; ++ __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */ ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++ int __glibc_reserved[2]; ++# endif ++ }; ++#endif ++ ++/* Tell code we have these members. */ ++#define _STATBUF_ST_BLKSIZE ++#define _STATBUF_ST_RDEV ++/* Nanosecond resolution time values are supported. */ ++#define _STATBUF_ST_NSEC ++ ++#endif /* _BITS_STRUCT_STAT_H */ +diff --git a/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h b/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h +new file mode 100644 +index 0000000000000000..0f7c9cdc89ebf686 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/sh/bits/struct_stat.h +@@ -0,0 +1,139 @@ ++/* Definition for struct stat. Linux/sh version. ++ Copyright (C) 2020-2022 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 ++ . */ ++ ++#if !defined _SYS_STAT_H && !defined _FCNTL_H ++# error "Never include directly; use instead." ++#endif ++ ++#ifndef _BITS_STRUCT_STAT_H ++#define _BITS_STRUCT_STAT_H 1 ++ ++#include ++#include ++ ++struct stat ++ { ++#ifdef __USE_TIME_BITS64 ++# include ++#else ++ __dev_t st_dev; /* Device. */ ++ unsigned short int __pad1; ++# ifndef __USE_FILE_OFFSET64 ++ __ino_t st_ino; /* File serial number. */ ++# else ++ __ino_t __st_ino; /* 32bit file serial number. */ ++# endif ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ unsigned short int __pad2; ++# ifndef __USE_FILE_OFFSET64 ++ __off_t st_size; /* Size of file, in bytes. */ ++# else ++ __off64_t st_size; /* Size of file, in bytes. */ ++# endif ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ ++# ifndef __USE_FILE_OFFSET64 ++ __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */ ++# else ++ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ ++# endif ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# define st_atime st_atim.tv_sec /* Backward compatibility. */ ++# define st_mtime st_mtim.tv_sec ++# define st_ctime st_ctim.tv_sec ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++# ifndef __USE_FILE_OFFSET64 ++ unsigned long int __glibc_reserved4; ++ unsigned long int __glibc_reserved5; ++# else ++ __ino64_t st_ino; /* File serial number. */ ++# endif ++#endif /* __USE_TIME_BITS64 */ ++ }; ++ ++#ifdef __USE_LARGEFILE64 ++struct stat64 ++ { ++# ifdef __USE_TIME_BITS64 ++# include ++# else ++ __dev_t st_dev; /* Device. */ ++ unsigned int __pad1; ++ ++ __ino_t __st_ino; /* 32bit file serial number. */ ++ __mode_t st_mode; /* File mode. */ ++ __nlink_t st_nlink; /* Link count. */ ++ __uid_t st_uid; /* User ID of the file's owner. */ ++ __gid_t st_gid; /* Group ID of the file's group.*/ ++ __dev_t st_rdev; /* Device number, if device. */ ++ unsigned int __pad2; ++ __off64_t st_size; /* Size of file, in bytes. */ ++ __blksize_t st_blksize; /* Optimal block size for I/O. */ ++ ++ __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ ++# ifdef __USE_XOPEN2K8 ++ /* Nanosecond resolution timestamps are stored in a format ++ equivalent to 'struct timespec'. This is the type used ++ whenever possible but the Unix namespace rules do not allow the ++ identifier 'timespec' to appear in the header. ++ Therefore we have to handle the use of this header in strictly ++ standard-compliant sources special. */ ++ struct timespec st_atim; /* Time of last access. */ ++ struct timespec st_mtim; /* Time of last modification. */ ++ struct timespec st_ctim; /* Time of last status change. */ ++# else ++ __time_t st_atime; /* Time of last access. */ ++ unsigned long int st_atimensec; /* Nscecs of last access. */ ++ __time_t st_mtime; /* Time of last modification. */ ++ unsigned long int st_mtimensec; /* Nsecs of last modification. */ ++ __time_t st_ctime; /* Time of last status change. */ ++ unsigned long int st_ctimensec; /* Nsecs of last status change. */ ++# endif ++ __ino64_t st_ino; /* File serial number. */ ++# endif /* __USE_TIME_BITS64 */ ++ }; ++#endif ++ ++/* Tell code we have these members. */ ++#define _STATBUF_ST_BLKSIZE ++#define _STATBUF_ST_RDEV ++/* Nanosecond resolution time values are supported. */ ++#define _STATBUF_ST_NSEC ++ ++ ++#endif /* _BITS_STRUCT_STAT_H */ diff --git a/glibc-upstream-2.34-351.patch b/glibc-upstream-2.34-351.patch new file mode 100644 index 0000000..91141b0 --- /dev/null +++ b/glibc-upstream-2.34-351.patch @@ -0,0 +1,107 @@ +commit f42d871b22f7eb5330e77ed9bccbb447c44e7101 +Author: Sergei Trofimovich +Date: Tue Sep 13 13:39:13 2022 -0400 + + Makerules: fix MAKEFLAGS assignment for upcoming make-4.4 [BZ# 29564] + + make-4.4 will add long flags to MAKEFLAGS variable: + + * WARNING: Backward-incompatibility! + Previously only simple (one-letter) options were added to the MAKEFLAGS + variable that was visible while parsing makefiles. Now, all options + are available in MAKEFLAGS. + + This causes locale builds to fail when long options are used: + + $ make --shuffle + ... + make -C localedata install-locales + make: invalid shuffle mode: '1662724426r' + + The change fixes it by passing eash option via whitespace and dashes. + That way option is appended to both single-word form and whitespace + separated form. + + While at it fixed --silent mode detection in $(MAKEFLAGS) by filtering + out --long-options. Otherwise options like --shuffle flag enable silent + mode unintentionally. $(silent-make) variable consolidates the checks. + + Resolves: BZ# 29564 + + CC: Paul Smith + CC: Siddhesh Poyarekar + Signed-off-by: Sergei Trofimovich + Reviewed-by: Siddhesh Poyarekar + (cherry picked from commit 2d7ed98add14f75041499ac189696c9bd3d757fe) + +diff --git a/Makeconfig b/Makeconfig +index 99898a632a64be91..4e04dafb76a1e1a1 100644 +--- a/Makeconfig ++++ b/Makeconfig +@@ -43,6 +43,22 @@ else + $(error objdir must be defined by the build-directory Makefile) + endif + ++# Did we request 'make -s' run? "yes" or "no". ++# Starting from make-4.4 MAKEFLAGS now contains long ++# options like '--shuffle'. To detect presence of 's' ++# we pick first word with short options. Long options ++# are guaranteed to come after whitespace. We use '-' ++# prefix to always have a word before long options ++# even if no short options were passed. ++# Typical MAKEFLAGS values to watch for: ++# "rs --shuffle=42" (silent) ++# " --shuffle" (not silent) ++ifeq ($(findstring s, $(firstword -$(MAKEFLAGS))),) ++silent-make := no ++else ++silent-make := yes ++endif ++ + # Root of the sysdeps tree. + sysdep_dir := $(..)sysdeps + export sysdep_dir := $(sysdep_dir) +@@ -918,7 +934,7 @@ endif + # umpteen zillion filenames along with it (we use `...' instead) + # but we don't want this echoing done when the user has said + # he doesn't want to see commands echoed by using -s. +-ifneq "$(findstring s,$(MAKEFLAGS))" "" # if -s ++ifeq ($(silent-make),yes) # if -s + +cmdecho := echo >/dev/null + else # not -s + +cmdecho := echo +diff --git a/Makerules b/Makerules +index 7fbe85719aacc230..e5916f29fa0d4593 100644 +--- a/Makerules ++++ b/Makerules +@@ -810,7 +810,7 @@ endif + # Maximize efficiency by minimizing the number of rules. + .SUFFIXES: # Clear the suffix list. We don't use suffix rules. + # Don't define any builtin rules. +-MAKEFLAGS := $(MAKEFLAGS)r ++MAKEFLAGS := $(MAKEFLAGS) -r + + # Generic rule for making directories. + %/: +@@ -827,7 +827,7 @@ MAKEFLAGS := $(MAKEFLAGS)r + .PRECIOUS: $(foreach l,$(libtypes),$(patsubst %,$(common-objpfx)$l,c)) + + # Use the verbose option of ar and tar when not running silently. +-ifeq "$(findstring s,$(MAKEFLAGS))" "" # if not -s ++ifeq ($(silent-make),no) # if not -s + verbose := v + else # -s + verbose := +diff --git a/elf/rtld-Rules b/elf/rtld-Rules +index 10de81918c07670f..a452536d39b5c198 100644 +--- a/elf/rtld-Rules ++++ b/elf/rtld-Rules +@@ -52,7 +52,7 @@ $(objpfx)rtld-libc.a: $(foreach dir,$(rtld-subdirs),\ + mv -f $@T $@ + + # Use the verbose option of ar and tar when not running silently. +-ifeq "$(findstring s,$(MAKEFLAGS))" "" # if not -s ++ifeq ($(silent-make),no) # if not -s + verbose := v + else # -s + verbose := diff --git a/glibc-upstream-2.34-352.patch b/glibc-upstream-2.34-352.patch new file mode 100644 index 0000000..5c4006e --- /dev/null +++ b/glibc-upstream-2.34-352.patch @@ -0,0 +1,73 @@ +commit 675ba1f361ea424626b48a40cfd24d113dfc1b65 +Author: Paul Eggert +Date: Thu Sep 8 20:08:32 2022 -0500 + + mktime: improve heuristic for ca-1986 Indiana DST + + This patch syncs mktime.c from Gnulib, fixing a + problem reported by Mark Krenz , + and it should fix BZ#29035 too. + * time/mktime.c (__mktime_internal): Be more generous about + accepting arguments with the wrong value of tm_isdst, by falling + back to a one-hour DST difference if we find no nearby DST that is + unusual. This fixes a problem where "1986-04-28 00:00 EDT" was + rejected when TZ="America/Indianapolis" because the nearest DST + timestamp occurred in 1970, a temporal distance too great for the + old heuristic. This also also narrows the search a bit, which + is a minor performance win. + + (cherry picked from commit 83859e1115269cf56d21669361d4ddbe2687831c) + +diff --git a/time/mktime.c b/time/mktime.c +index 8e78006eea7e693b..74d9bbaa5b375723 100644 +--- a/time/mktime.c ++++ b/time/mktime.c +@@ -429,8 +429,13 @@ __mktime_internal (struct tm *tp, + time with the right value, and use its UTC offset. + + Heuristic: probe the adjacent timestamps in both directions, +- looking for the desired isdst. This should work for all real +- time zone histories in the tz database. */ ++ looking for the desired isdst. If none is found within a ++ reasonable duration bound, assume a one-hour DST difference. ++ This should work for all real time zone histories in the tz ++ database. */ ++ ++ /* +1 if we wanted standard time but got DST, -1 if the reverse. */ ++ int dst_difference = (isdst == 0) - (tm.tm_isdst == 0); + + /* Distance between probes when looking for a DST boundary. In + tzdata2003a, the shortest period of DST is 601200 seconds +@@ -441,12 +446,14 @@ __mktime_internal (struct tm *tp, + periods when probing. */ + int stride = 601200; + +- /* The longest period of DST in tzdata2003a is 536454000 seconds +- (e.g., America/Jujuy starting 1946-10-01 01:00). The longest +- period of non-DST is much longer, but it makes no real sense +- to search for more than a year of non-DST, so use the DST +- max. */ +- int duration_max = 536454000; ++ /* In TZDB 2021e, the longest period of DST (or of non-DST), in ++ which the DST (or adjacent DST) difference is not one hour, ++ is 457243209 seconds: e.g., America/Cambridge_Bay with leap ++ seconds, starting 1965-10-31 00:00 in a switch from ++ double-daylight time (-05) to standard time (-07), and ++ continuing to 1980-04-27 02:00 in a switch from standard time ++ (-07) to daylight time (-06). */ ++ int duration_max = 457243209; + + /* Search in both directions, so the maximum distance is half + the duration; add the stride to avoid off-by-1 problems. */ +@@ -483,6 +490,11 @@ __mktime_internal (struct tm *tp, + } + } + ++ /* No unusual DST offset was found nearby. Assume one-hour DST. */ ++ t += 60 * 60 * dst_difference; ++ if (mktime_min <= t && t <= mktime_max && convert_time (convert, t, &tm)) ++ goto offset_found; ++ + __set_errno (EOVERFLOW); + return -1; + } diff --git a/glibc-upstream-2.34-353.patch b/glibc-upstream-2.34-353.patch new file mode 100644 index 0000000..2bf6250 --- /dev/null +++ b/glibc-upstream-2.34-353.patch @@ -0,0 +1,86 @@ +commit 6e8044e910600f71f4802dba2d105007af8428c3 +Author: Joseph Myers +Date: Mon Nov 8 19:11:51 2021 +0000 + + Fix memmove call in vfprintf-internal.c:group_number + + A recent GCC mainline change introduces errors of the form: + + vfprintf-internal.c: In function 'group_number': + vfprintf-internal.c:2093:15: error: 'memmove' specified bound between 9223372036854775808 and 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Werror=stringop-overflow=] + 2093 | memmove (w, s, (front_ptr -s) * sizeof (CHAR_T)); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + This is a genuine bug in the glibc code: s > front_ptr is always true + at this point in the code, and the intent is clearly for the + subtraction to be the other way round. The other arguments to the + memmove call here also appear to be wrong; w and s point just *after* + the destination and source for copying the rest of the number, so the + size needs to be subtracted to get appropriate pointers for the + copying. Adjust the memmove call to conform to the apparent intent of + the code, so fixing the -Wstringop-overflow error. + + Now, if the original code were ever executed, a buffer overrun would + result. However, I believe this code (introduced in commit + edc1686af0c0fc2eb535f1d38cdf63c1a5a03675, "vfprintf: Reuse work_buffer + in group_number", so in glibc 2.26) is unreachable in prior glibc + releases (so there is no need for a bug in Bugzilla, no need to + consider any backports unless someone wants to build older glibc + releases with GCC 12 and no possibility of this buffer overrun + resulting in a security issue). + + work_buffer is 1000 bytes / 250 wide characters. This case is only + reachable if an initial part of the number, plus a grouped copy of the + rest of the number, fail to fit in that space; that is, if the grouped + number fails to fit in the space. In the wide character case, + grouping is always one wide character, so even with a locale (of which + there aren't any in glibc) grouping every digit, a number would need + to occupy at least 125 wide characters to overflow, and a 64-bit + integer occupies at most 23 characters in octal including a leading 0. + In the narrow character case, the multibyte encoding of the grouping + separator would need to be at least 42 bytes to overflow, again + supposing grouping every digit, but MB_LEN_MAX is 16. So even if we + admit the case of artificially constructed locales not shipped with + glibc, given that such a locale would need to use one of the character + sets supported by glibc, this code cannot be reached at present. (And + POSIX only actually specifies the ' flag for grouping for decimal + output, though glibc acts on it for other bases as well.) + + With binary output (if you consider use of grouping there to be + valid), you'd need a 15-byte multibyte character for overflow; I don't + know if any supported character set has such a character (if, again, + we admit constructed locales using grouping every digit and a grouping + separator chosen to have a multibyte encoding as long as possible, as + well as accepting use of grouping with binary), but given that we have + this code at all (clearly it's not *correct*, or in accordance with + the principle of avoiding arbitrary limits, to skip grouping on + running out of internal space like that), I don't think it should need + any further changes for binary printf support to go in. + + On the other hand, support for large sizes of _BitInt in printf (see + the N2858 proposal) *would* require something to be done about such + arbitrary limits (presumably using dynamic allocation in printf again, + for sufficiently large _BitInt arguments only - currently only + floating-point uses dynamic allocation, and, as previously discussed, + that could actually be replaced by bounded allocation given smarter + code). + + Tested with build-many-glibcs.py for aarch64-linux-gnu (GCC mainline). + Also tested natively for x86_64. + + (cherry picked from commit db6c4935fae6005d46af413b32aa92f4f6059dce) + +diff --git a/stdio-common/vfprintf-internal.c b/stdio-common/vfprintf-internal.c +index 3f3d1e148a8e7fda..53d93b2f07ecb261 100644 +--- a/stdio-common/vfprintf-internal.c ++++ b/stdio-common/vfprintf-internal.c +@@ -2154,7 +2154,8 @@ group_number (CHAR_T *front_ptr, CHAR_T *w, CHAR_T *rear_ptr, + copy_rest: + /* No further grouping to be done. Copy the rest of the + number. */ +- memmove (w, s, (front_ptr -s) * sizeof (CHAR_T)); ++ w -= s - front_ptr; ++ memmove (w, front_ptr, (s - front_ptr) * sizeof (CHAR_T)); + break; + } + else if (*grouping != '\0') diff --git a/glibc-upstream-2.34-354.patch b/glibc-upstream-2.34-354.patch new file mode 100644 index 0000000..0ac8827 --- /dev/null +++ b/glibc-upstream-2.34-354.patch @@ -0,0 +1,35 @@ +commit 291d4402067760edb7c0f339f9e451787a25e20a +Author: Joseph Myers +Date: Fri Aug 27 17:47:46 2021 +0000 + + Allow #pragma GCC in headers in conformtest + + No "#pragma GCC" pragma allows macro-expansion of its arguments, so no + namespace issues arise from use of such pragmas in installed headers. + Ignore them in conformtest tests of header namespace. + + Tested for x86_64, in conjunction with Paul's patch + + adding use of such pragmas to installed headers shared with gnulib. + + (cherry picked from commit 6090a4a1b32fd7859d0ad5b7e9b240bd5fa04b3f) + +diff --git a/conform/conformtest.py b/conform/conformtest.py +index 4898e16c9fb96503..164cf2917d464aa1 100644 +--- a/conform/conformtest.py ++++ b/conform/conformtest.py +@@ -631,6 +631,14 @@ class HeaderTests(object): + continue + if re.match(r'# [1-9]', line): + continue ++ if line.startswith('#pragma GCC '): ++ # No GCC pragma uses macro expansion, so no ++ # namespace issues arise from such pragmas. (Some ++ # pragmas not in the GCC namespace do macro-expand ++ # their arguments and so could be affected by ++ # macros defined by user code including the ++ # header.) ++ continue + match = re.match(r'#define (.*)', line) + if match: + self.check_token(bad_tokens, match.group(1)) diff --git a/glibc-upstream-2.34-355.patch b/glibc-upstream-2.34-355.patch new file mode 100644 index 0000000..4ba03a0 --- /dev/null +++ b/glibc-upstream-2.34-355.patch @@ -0,0 +1,629 @@ +commit 86a701a20479dfbc23540b3143fd5b28660a2447 +Author: Paul Eggert +Date: Tue Sep 21 07:47:45 2021 -0700 + + regex: copy back from Gnulib + + Copy regex-related files back from Gnulib, to fix a problem with + static checking of regex calls noted by Martin Sebor. This merges the + following changes: + + * New macro __attribute_nonnull__ in misc/sys/cdefs.h, for use later + when copying other files back from Gnulib. + + * Use __GNULIB_CDEFS instead of __GLIBC__ when deciding + whether to include bits/wordsize.h etc. + + * Avoid duplicate entries in epsilon closure table. + + * New regex.h macro _REGEX_NELTS to let regexec say that its pmatch + arg should contain nmatch elts. Use that for regexec, instead of + __attr_access (which is incorrect). + + * New regex.h macro _Attr_access_ which is like __attr_access except + portable to non-glibc platforms. + + * Add some DEBUG_ASSERTs to pacify gcc -fanalyzer and to catch + recently-fixed performance bugs if they recur. + + * Add Gnulib-specific stuff to port the dynarray- and lock-using parts + of regex code to non-glibc platforms. + + * Fix glibc bug 11053. + + * Avoid some undefined behavior when popping an empty fail stack. + + (cherry picked from commit 0b5ca7c3e551e5502f3be3b06453324fe8604e82) + +diff --git a/include/intprops.h b/include/intprops.h +index 967e32ea0cbedd56..9d10028a5966c1c6 100644 +--- a/include/intprops.h ++++ b/include/intprops.h +@@ -133,7 +133,8 @@ + operators might not yield numerically correct answers due to + arithmetic overflow. They do not rely on undefined or + implementation-defined behavior. Their implementations are simple +- and straightforward, but they are a bit harder to use than the ++ and straightforward, but they are harder to use and may be less ++ efficient than the INT__WRAPV, INT__OK, and + INT__OVERFLOW macros described below. + + Example usage: +@@ -158,6 +159,9 @@ + must have minimum value MIN and maximum MAX. Unsigned types should + use a zero MIN of the proper type. + ++ Because all arguments are subject to integer promotions, these ++ macros typically do not work on types narrower than 'int'. ++ + These macros are tuned for constant MIN and MAX. For commutative + operations such as A + B, they are also tuned for constant B. */ + +@@ -339,9 +343,15 @@ + arguments should not have side effects. + + The WRAPV macros are not constant expressions. They support only +- +, binary -, and *. Because the WRAPV macros convert the result, +- they report overflow in different circumstances than the OVERFLOW +- macros do. ++ +, binary -, and *. ++ ++ Because the WRAPV macros convert the result, they report overflow ++ in different circumstances than the OVERFLOW macros do. For ++ example, in the typical case with 16-bit 'short' and 32-bit 'int', ++ if A, B and R are all of type 'short' then INT_ADD_OVERFLOW (A, B) ++ returns false because the addition cannot overflow after A and B ++ are converted to 'int', whereas INT_ADD_WRAPV (A, B, &R) returns ++ true or false depending on whether the sum fits into 'short'. + + These macros are tuned for their last input argument being a constant. + +diff --git a/include/regex.h b/include/regex.h +index 24eca2c297bb6043..34fb67d85536bcb9 100644 +--- a/include/regex.h ++++ b/include/regex.h +@@ -37,7 +37,8 @@ extern int __regcomp (regex_t *__preg, const char *__pattern, int __cflags); + libc_hidden_proto (__regcomp) + + extern int __regexec (const regex_t *__preg, const char *__string, +- size_t __nmatch, regmatch_t __pmatch[], int __eflags); ++ size_t __nmatch, regmatch_t __pmatch[__nmatch], ++ int __eflags); + libc_hidden_proto (__regexec) + + extern size_t __regerror (int __errcode, const regex_t *__preg, +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index e0ecd9147ee3ce48..b166f3d209fe361f 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -366,16 +366,18 @@ + #endif + + /* The nonnull function attribute marks pointer parameters that +- must not be NULL. */ +-#ifndef __nonnull ++ must not be NULL. This has the name __nonnull in glibc, ++ and __attribute_nonnull__ in files shared with Gnulib to avoid ++ collision with a different __nonnull in DragonFlyBSD 5.9. */ ++#ifndef __attribute_nonnull__ + # if __GNUC_PREREQ (3,3) || __glibc_has_attribute (__nonnull__) +-# define __nonnull(params) __attribute__ ((__nonnull__ params)) ++# define __attribute_nonnull__(params) __attribute__ ((__nonnull__ params)) + # else +-# define __nonnull(params) ++# define __attribute_nonnull__(params) + # endif +-#elif !defined __GLIBC__ +-# undef __nonnull +-# define __nonnull(params) _GL_ATTRIBUTE_NONNULL (params) ++#endif ++#ifndef __nonnull ++# define __nonnull(params) __attribute_nonnull__ (params) + #endif + + /* The returns_nonnull function attribute marks the return type of the function +@@ -541,9 +543,9 @@ + [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })] + #endif + +-/* The #ifndef lets Gnulib avoid including these on non-glibc +- platforms, where the includes typically do not exist. */ +-#ifdef __GLIBC__ ++/* Gnulib avoids including these, as they don't work on non-glibc or ++ older glibc platforms. */ ++#ifndef __GNULIB_CDEFS + # include + # include + #endif +diff --git a/posix/regcomp.c b/posix/regcomp.c +index d93698ae78447b46..887e5b50684e22f5 100644 +--- a/posix/regcomp.c ++++ b/posix/regcomp.c +@@ -1695,12 +1695,14 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) + reg_errcode_t err; + Idx i; + re_node_set eclosure; +- bool ok; + bool incomplete = false; + err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1); + if (__glibc_unlikely (err != REG_NOERROR)) + return err; + ++ /* An epsilon closure includes itself. */ ++ eclosure.elems[eclosure.nelem++] = node; ++ + /* This indicates that we are calculating this node now. + We reference this value to avoid infinite loop. */ + dfa->eclosures[node].nelem = -1; +@@ -1753,10 +1755,6 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) + } + } + +- /* An epsilon closure includes itself. */ +- ok = re_node_set_insert (&eclosure, node); +- if (__glibc_unlikely (! ok)) +- return REG_ESPACE; + if (incomplete && !root) + dfa->eclosures[node].nelem = 0; + else +diff --git a/posix/regex.c b/posix/regex.c +index 7296be0f08da88d8..d32863972c7bcdcf 100644 +--- a/posix/regex.c ++++ b/posix/regex.c +@@ -24,6 +24,7 @@ + + # if __GNUC_PREREQ (4, 6) + # pragma GCC diagnostic ignored "-Wsuggest-attribute=pure" ++# pragma GCC diagnostic ignored "-Wvla" + # endif + # if __GNUC_PREREQ (4, 3) + # pragma GCC diagnostic ignored "-Wold-style-definition" +diff --git a/posix/regex.h b/posix/regex.h +index 14fb1d8364a11d29..adb69768ee520554 100644 +--- a/posix/regex.h ++++ b/posix/regex.h +@@ -522,6 +522,30 @@ typedef struct + + /* Declarations for routines. */ + ++#ifndef _REGEX_NELTS ++# if (defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__ \ ++ && !defined __STDC_NO_VLA__) ++# define _REGEX_NELTS(n) n ++# else ++# define _REGEX_NELTS(n) ++# endif ++#endif ++ ++#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__) ++# pragma GCC diagnostic push ++# pragma GCC diagnostic ignored "-Wvla" ++#endif ++ ++#ifndef _Attr_access_ ++# ifdef __attr_access ++# define _Attr_access_(arg) __attr_access (arg) ++# elif defined __GNUC__ && 10 <= __GNUC__ ++# define _Attr_access_(x) __attribute__ ((__access__ x)) ++# else ++# define _Attr_access_(x) ++# endif ++#endif ++ + #ifdef __USE_GNU + /* Sets the current default syntax to SYNTAX, and return the old syntax. + You can also simply assign to the 're_syntax_options' variable. */ +@@ -537,7 +561,7 @@ extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax); + 'regfree'. */ + extern const char *re_compile_pattern (const char *__pattern, size_t __length, + struct re_pattern_buffer *__buffer) +- __attr_access ((__read_only__, 1, 2)); ++ _Attr_access_ ((__read_only__, 1, 2)); + + + /* Compile a fastmap for the compiled pattern in BUFFER; used to +@@ -555,7 +579,7 @@ extern regoff_t re_search (struct re_pattern_buffer *__buffer, + const char *__String, regoff_t __length, + regoff_t __start, regoff_t __range, + struct re_registers *__regs) +- __attr_access ((__read_only__, 2, 3)); ++ _Attr_access_ ((__read_only__, 2, 3)); + + + /* Like 're_search', but search in the concatenation of STRING1 and +@@ -566,8 +590,8 @@ extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer, + regoff_t __start, regoff_t __range, + struct re_registers *__regs, + regoff_t __stop) +- __attr_access ((__read_only__, 2, 3)) +- __attr_access ((__read_only__, 4, 5)); ++ _Attr_access_ ((__read_only__, 2, 3)) ++ _Attr_access_ ((__read_only__, 4, 5)); + + + /* Like 're_search', but return how many characters in STRING the regexp +@@ -575,7 +599,7 @@ extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer, + extern regoff_t re_match (struct re_pattern_buffer *__buffer, + const char *__String, regoff_t __length, + regoff_t __start, struct re_registers *__regs) +- __attr_access ((__read_only__, 2, 3)); ++ _Attr_access_ ((__read_only__, 2, 3)); + + + /* Relates to 're_match' as 're_search_2' relates to 're_search'. */ +@@ -584,8 +608,8 @@ extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer, + const char *__string2, regoff_t __length2, + regoff_t __start, struct re_registers *__regs, + regoff_t __stop) +- __attr_access ((__read_only__, 2, 3)) +- __attr_access ((__read_only__, 4, 5)); ++ _Attr_access_ ((__read_only__, 2, 3)) ++ _Attr_access_ ((__read_only__, 4, 5)); + + + /* Set REGS to hold NUM_REGS registers, storing them in STARTS and +@@ -654,16 +678,19 @@ extern int regcomp (regex_t *_Restrict_ __preg, + + extern int regexec (const regex_t *_Restrict_ __preg, + const char *_Restrict_ __String, size_t __nmatch, +- regmatch_t __pmatch[_Restrict_arr_], +- int __eflags) +- __attr_access ((__write_only__, 4, 3)); ++ regmatch_t __pmatch[_Restrict_arr_ ++ _REGEX_NELTS (__nmatch)], ++ int __eflags); + + extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg, + char *_Restrict_ __errbuf, size_t __errbuf_size) +- __attr_access ((__write_only__, 3, 4)); ++ _Attr_access_ ((__write_only__, 3, 4)); + + extern void regfree (regex_t *__preg); + ++#if defined __GNUC__ && 4 < __GNUC__ + (6 <= __GNUC_MINOR__) ++# pragma GCC diagnostic pop ++#endif + + #ifdef __cplusplus + } +diff --git a/posix/regex_internal.c b/posix/regex_internal.c +index 9dd387ef85d64e62..aefcfa2f52e68c6a 100644 +--- a/posix/regex_internal.c ++++ b/posix/regex_internal.c +@@ -1211,6 +1211,10 @@ re_node_set_merge (re_node_set *dest, const re_node_set *src) + + if (__glibc_unlikely (dest->nelem == 0)) + { ++ /* Although we already guaranteed above that dest->alloc != 0 and ++ therefore dest->elems != NULL, add a debug assertion to pacify ++ GCC 11.2.1's -fanalyzer. */ ++ DEBUG_ASSERT (dest->elems); + dest->nelem = src->nelem; + memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx)); + return REG_NOERROR; +@@ -1286,7 +1290,10 @@ re_node_set_insert (re_node_set *set, Idx elem) + + if (__glibc_unlikely (set->nelem) == 0) + { +- /* We already guaranteed above that set->alloc != 0. */ ++ /* Although we already guaranteed above that set->alloc != 0 and ++ therefore set->elems != NULL, add a debug assertion to pacify ++ GCC 11.2 -fanalyzer. */ ++ DEBUG_ASSERT (set->elems); + set->elems[0] = elem; + ++set->nelem; + return true; +@@ -1314,6 +1321,7 @@ re_node_set_insert (re_node_set *set, Idx elem) + { + for (idx = set->nelem; set->elems[idx - 1] > elem; idx--) + set->elems[idx] = set->elems[idx - 1]; ++ DEBUG_ASSERT (set->elems[idx - 1] < elem); + } + + /* Insert the new element. */ +diff --git a/posix/regex_internal.h b/posix/regex_internal.h +index edcdc07e999694ac..1245e782ffc69086 100644 +--- a/posix/regex_internal.h ++++ b/posix/regex_internal.h +@@ -32,6 +32,10 @@ + #include + #include + ++#ifndef _LIBC ++# include ++#endif ++ + #include + #include + +@@ -49,14 +53,14 @@ + # define lock_fini(lock) ((void) 0) + # define lock_lock(lock) __libc_lock_lock (lock) + # define lock_unlock(lock) __libc_lock_unlock (lock) +-#elif defined GNULIB_LOCK && !defined USE_UNLOCKED_IO ++#elif defined GNULIB_LOCK && !defined GNULIB_REGEX_SINGLE_THREAD + # include "glthread/lock.h" + # define lock_define(name) gl_lock_define (, name) + # define lock_init(lock) glthread_lock_init (&(lock)) + # define lock_fini(lock) glthread_lock_destroy (&(lock)) + # define lock_lock(lock) glthread_lock_lock (&(lock)) + # define lock_unlock(lock) glthread_lock_unlock (&(lock)) +-#elif defined GNULIB_PTHREAD && !defined USE_UNLOCKED_IO ++#elif defined GNULIB_PTHREAD && !defined GNULIB_REGEX_SINGLE_THREAD + # include + # define lock_define(name) pthread_mutex_t name; + # define lock_init(lock) pthread_mutex_init (&(lock), 0) +diff --git a/posix/regexec.c b/posix/regexec.c +index f7b4f9cfc3f030df..83e9aaf8cad956a2 100644 +--- a/posix/regexec.c ++++ b/posix/regexec.c +@@ -59,7 +59,7 @@ static void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, + Idx cur_idx, Idx nmatch); + static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs, + Idx str_idx, Idx dest_node, Idx nregs, +- regmatch_t *regs, ++ regmatch_t *regs, regmatch_t *prevregs, + re_node_set *eps_via_nodes); + static reg_errcode_t set_regs (const regex_t *preg, + const re_match_context_t *mctx, +@@ -186,11 +186,12 @@ static reg_errcode_t extend_buffers (re_match_context_t *mctx, int min_len); + REG_NOTBOL is set, then ^ does not match at the beginning of the + string; if REG_NOTEOL is set, then $ does not match at the end. + +- We return 0 if we find a match and REG_NOMATCH if not. */ ++ Return 0 if a match is found, REG_NOMATCH if not, REG_BADPAT if ++ EFLAGS is invalid. */ + + int + regexec (const regex_t *__restrict preg, const char *__restrict string, +- size_t nmatch, regmatch_t pmatch[], int eflags) ++ size_t nmatch, regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags) + { + reg_errcode_t err; + Idx start, length; +@@ -234,7 +235,7 @@ int + attribute_compat_text_section + __compat_regexec (const regex_t *__restrict preg, + const char *__restrict string, size_t nmatch, +- regmatch_t pmatch[], int eflags) ++ regmatch_t pmatch[_REGEX_NELTS (nmatch)], int eflags) + { + return regexec (preg, string, nmatch, pmatch, + eflags & (REG_NOTBOL | REG_NOTEOL)); +@@ -269,8 +270,8 @@ compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0); + strings.) + + On success, re_match* functions return the length of the match, re_search* +- return the position of the start of the match. Return value -1 means no +- match was found and -2 indicates an internal error. */ ++ return the position of the start of the match. They return -1 on ++ match failure, -2 on error. */ + + regoff_t + re_match (struct re_pattern_buffer *bufp, const char *string, Idx length, +@@ -1206,27 +1207,30 @@ check_halt_state_context (const re_match_context_t *mctx, + /* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA + corresponding to the DFA). + Return the destination node, and update EPS_VIA_NODES; +- return -1 in case of errors. */ ++ return -1 on match failure, -2 on error. */ + + static Idx + proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, ++ regmatch_t *prevregs, + Idx *pidx, Idx node, re_node_set *eps_via_nodes, + struct re_fail_stack_t *fs) + { + const re_dfa_t *const dfa = mctx->dfa; +- Idx i; +- bool ok; + if (IS_EPSILON_NODE (dfa->nodes[node].type)) + { + re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes; + re_node_set *edests = &dfa->edests[node]; +- Idx dest_node; +- ok = re_node_set_insert (eps_via_nodes, node); +- if (__glibc_unlikely (! ok)) +- return -2; +- /* Pick up a valid destination, or return -1 if none +- is found. */ +- for (dest_node = -1, i = 0; i < edests->nelem; ++i) ++ ++ if (! re_node_set_contains (eps_via_nodes, node)) ++ { ++ bool ok = re_node_set_insert (eps_via_nodes, node); ++ if (__glibc_unlikely (! ok)) ++ return -2; ++ } ++ ++ /* Pick a valid destination, or return -1 if none is found. */ ++ Idx dest_node = -1; ++ for (Idx i = 0; i < edests->nelem; i++) + { + Idx candidate = edests->elems[i]; + if (!re_node_set_contains (cur_nodes, candidate)) +@@ -1244,7 +1248,7 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, + /* Otherwise, push the second epsilon-transition on the fail stack. */ + else if (fs != NULL + && push_fail_stack (fs, *pidx, candidate, nregs, regs, +- eps_via_nodes)) ++ prevregs, eps_via_nodes)) + return -2; + + /* We know we are going to exit. */ +@@ -1288,7 +1292,7 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, + if (naccepted == 0) + { + Idx dest_node; +- ok = re_node_set_insert (eps_via_nodes, node); ++ bool ok = re_node_set_insert (eps_via_nodes, node); + if (__glibc_unlikely (! ok)) + return -2; + dest_node = dfa->edests[node].elems[0]; +@@ -1317,7 +1321,8 @@ proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs, + static reg_errcode_t + __attribute_warn_unused_result__ + push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node, +- Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes) ++ Idx nregs, regmatch_t *regs, regmatch_t *prevregs, ++ re_node_set *eps_via_nodes) + { + reg_errcode_t err; + Idx num = fs->num++; +@@ -1333,25 +1338,30 @@ push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node, + } + fs->stack[num].idx = str_idx; + fs->stack[num].node = dest_node; +- fs->stack[num].regs = re_malloc (regmatch_t, nregs); ++ fs->stack[num].regs = re_malloc (regmatch_t, 2 * nregs); + if (fs->stack[num].regs == NULL) + return REG_ESPACE; + memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs); ++ memcpy (fs->stack[num].regs + nregs, prevregs, sizeof (regmatch_t) * nregs); + err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes); + return err; + } + + static Idx + pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs, +- regmatch_t *regs, re_node_set *eps_via_nodes) ++ regmatch_t *regs, regmatch_t *prevregs, ++ re_node_set *eps_via_nodes) + { ++ if (fs == NULL || fs->num == 0) ++ return -1; + Idx num = --fs->num; +- DEBUG_ASSERT (num >= 0); + *pidx = fs->stack[num].idx; + memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs); ++ memcpy (prevregs, fs->stack[num].regs + nregs, sizeof (regmatch_t) * nregs); + re_node_set_free (eps_via_nodes); + re_free (fs->stack[num].regs); + *eps_via_nodes = fs->stack[num].eps_via_nodes; ++ DEBUG_ASSERT (0 <= fs->stack[num].node); + return fs->stack[num].node; + } + +@@ -1407,33 +1417,32 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, + { + update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch); + +- if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node) ++ if ((idx == pmatch[0].rm_eo && cur_node == mctx->last_node) ++ || (fs && re_node_set_contains (&eps_via_nodes, cur_node))) + { + Idx reg_idx; ++ cur_node = -1; + if (fs) + { + for (reg_idx = 0; reg_idx < nmatch; ++reg_idx) + if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1) +- break; +- if (reg_idx == nmatch) +- { +- re_node_set_free (&eps_via_nodes); +- regmatch_list_free (&prev_match); +- return free_fail_stack_return (fs); +- } +- cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, +- &eps_via_nodes); ++ { ++ cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, ++ prev_idx_match, &eps_via_nodes); ++ break; ++ } + } +- else ++ if (cur_node < 0) + { + re_node_set_free (&eps_via_nodes); + regmatch_list_free (&prev_match); +- return REG_NOERROR; ++ return free_fail_stack_return (fs); + } + } + + /* Proceed to next node. */ +- cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node, ++ cur_node = proceed_next_node (mctx, nmatch, pmatch, prev_idx_match, ++ &idx, cur_node, + &eps_via_nodes, fs); + + if (__glibc_unlikely (cur_node < 0)) +@@ -1445,13 +1454,13 @@ set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, + free_fail_stack_return (fs); + return REG_ESPACE; + } +- if (fs) +- cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, +- &eps_via_nodes); +- else ++ cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, ++ prev_idx_match, &eps_via_nodes); ++ if (cur_node < 0) + { + re_node_set_free (&eps_via_nodes); + regmatch_list_free (&prev_match); ++ free_fail_stack_return (fs); + return REG_NOMATCH; + } + } +@@ -1495,10 +1504,10 @@ update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, + } + else if (type == OP_CLOSE_SUBEXP) + { ++ /* We are at the last node of this sub expression. */ + Idx reg_num = dfa->nodes[cur_node].opr.idx + 1; + if (reg_num < nmatch) + { +- /* We are at the last node of this sub expression. */ + if (pmatch[reg_num].rm_so < cur_idx) + { + pmatch[reg_num].rm_eo = cur_idx; +@@ -2195,6 +2204,7 @@ sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx, + + /* Return the next state to which the current state STATE will transit by + accepting the current input byte, and update STATE_LOG if necessary. ++ Return NULL on failure. + If STATE can accept a multibyte char/collating element/back reference + update the destination of STATE_LOG. */ + +@@ -2395,7 +2405,7 @@ check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes, + + #if 0 + /* Return the next state to which the current state STATE will transit by +- accepting the current input byte. */ ++ accepting the current input byte. Return NULL on failure. */ + + static re_dfastate_t * + transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx, +@@ -2817,7 +2827,8 @@ find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, + /* Check whether the node TOP_NODE at TOP_STR can arrive to the node + LAST_NODE at LAST_STR. We record the path onto PATH since it will be + heavily reused. +- Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise. */ ++ Return REG_NOERROR if it can arrive, REG_NOMATCH if it cannot, ++ REG_ESPACE if memory is exhausted. */ + + static reg_errcode_t + __attribute_warn_unused_result__ +@@ -3433,7 +3444,8 @@ build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) + /* Group all nodes belonging to STATE into several destinations. + Then for all destinations, set the nodes belonging to the destination + to DESTS_NODE[i] and set the characters accepted by the destination +- to DEST_CH[i]. This function return the number of destinations. */ ++ to DEST_CH[i]. Return the number of destinations if successful, ++ -1 on internal error. */ + + static Idx + group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, +@@ -4211,7 +4223,8 @@ match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx) + } + + /* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches +- at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP. */ ++ at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP. ++ Return the new entry if successful, NULL if memory is exhausted. */ + + static re_sub_match_last_t * + match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx) diff --git a/glibc-upstream-2.34-356.patch b/glibc-upstream-2.34-356.patch new file mode 100644 index 0000000..fcaa4ad --- /dev/null +++ b/glibc-upstream-2.34-356.patch @@ -0,0 +1,30 @@ +commit fa5044f1e38f4f6515253449b6ca77fd14f53b8e +Author: Paul Eggert +Date: Wed Nov 24 14:16:09 2021 -0800 + + regex: fix buffer read overrun in search [BZ#28470] + + Problem reported by Benno Schulenberg in: + https://lists.gnu.org/r/bug-gnulib/2021-10/msg00035.html + * posix/regexec.c (re_search_internal): Use better bounds check. + + (cherry picked from commit c52ef24829f95a819965214eeae28e3289a91a61) + +diff --git a/posix/regexec.c b/posix/regexec.c +index 83e9aaf8cad956a2..6aeba3c0b4da23cc 100644 +--- a/posix/regexec.c ++++ b/posix/regexec.c +@@ -758,10 +758,9 @@ re_search_internal (const regex_t *preg, const char *string, Idx length, + + offset = match_first - mctx.input.raw_mbs_idx; + } +- /* If MATCH_FIRST is out of the buffer, leave it as '\0'. +- Note that MATCH_FIRST must not be smaller than 0. */ +- ch = (match_first >= length +- ? 0 : re_string_byte_at (&mctx.input, offset)); ++ /* Use buffer byte if OFFSET is in buffer, otherwise '\0'. */ ++ ch = (offset < mctx.input.valid_len ++ ? re_string_byte_at (&mctx.input, offset) : 0); + if (fastmap[ch]) + break; + match_first += incr; diff --git a/glibc-upstream-2.34-357.patch b/glibc-upstream-2.34-357.patch new file mode 100644 index 0000000..732e8af --- /dev/null +++ b/glibc-upstream-2.34-357.patch @@ -0,0 +1,203 @@ +commit 06afa5e09fbd984ed45ae6fc6ca050d544aba780 +Author: Adhemerval Zanella +Date: Wed Aug 25 11:17:06 2021 -0300 + + io: Fix ftw internal realloc buffer (BZ #28126) + + The 106ff08526d3ca did not take in consideration the buffer might be + reallocated if the total path is larger than PATH_MAX. The realloc + uses 'dirbuf', where 'dirstreams' is the allocated buffer. + + Checked on x86_64-linux-gnu. + + Reviewed-by: H.J. Lu + (cherry picked from commit 1836bb2ebf62bd9a3588f2ed2d851c8ae810097a) + +diff --git a/io/Makefile b/io/Makefile +index 01968b81042e01e4..5284a1282dd07e3d 100644 +--- a/io/Makefile ++++ b/io/Makefile +@@ -79,6 +79,7 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \ + tst-futimens \ + tst-utimensat \ + tst-closefrom \ ++ tst-ftw-bz28126 + + tests-time64 := \ + tst-fcntl-time64 \ +diff --git a/io/ftw.c b/io/ftw.c +index ce1c6a14a306152a..cf08d9f101657df0 100644 +--- a/io/ftw.c ++++ b/io/ftw.c +@@ -204,6 +204,20 @@ struct ftw_data + void *known_objects; + }; + ++static bool ++ftw_allocate (struct ftw_data *data, size_t newsize) ++{ ++ void *newp = realloc (data->dirstreams, data->maxdir ++ * sizeof (struct dir_data *) ++ + newsize); ++ if (newp == NULL) ++ return false; ++ data->dirstreams = newp; ++ data->dirbufsize = newsize; ++ data->dirbuf = (char *) data->dirstreams ++ + data->maxdir * sizeof (struct dir_data *); ++ return true; ++} + + /* Internally we use the FTW_* constants used for `nftw'. When invoked + as `ftw', map each flag to the subset of values used by `ftw'. */ +@@ -389,17 +403,9 @@ process_entry (struct ftw_data *data, struct dir_data *dir, const char *name, + return 0; + + new_buflen = data->ftw.base + namlen + 2; +- if (data->dirbufsize < new_buflen) +- { +- /* Enlarge the buffer. */ +- char *newp; +- +- data->dirbufsize = 2 * new_buflen; +- newp = (char *) realloc (data->dirbuf, data->dirbufsize); +- if (newp == NULL) +- return -1; +- data->dirbuf = newp; +- } ++ if (data->dirbufsize < new_buflen ++ && !ftw_allocate (data, 2 * new_buflen)) ++ return -1; + + *((char *) __mempcpy (data->dirbuf + data->ftw.base, name, namlen)) = '\0'; + +@@ -629,7 +635,7 @@ __attribute ((noinline)) + ftw_startup (const char *dir, int is_nftw, void *func, int descriptors, + int flags) + { +- struct ftw_data data; ++ struct ftw_data data = { .dirstreams = NULL }; + struct STRUCT_STAT st; + int result = 0; + int save_err; +@@ -647,16 +653,9 @@ ftw_startup (const char *dir, int is_nftw, void *func, int descriptors, + data.maxdir = descriptors < 1 ? 1 : descriptors; + data.actdir = 0; + /* PATH_MAX is always defined when we get here. */ +- data.dirbufsize = MAX (2 * strlen (dir), PATH_MAX); +- data.dirstreams = malloc (data.maxdir * sizeof (struct dir_data *) +- + data.dirbufsize); +- if (data.dirstreams == NULL) ++ if (!ftw_allocate (&data, MAX (2 * strlen (dir), PATH_MAX))) + return -1; +- + memset (data.dirstreams, '\0', data.maxdir * sizeof (struct dir_data *)); +- +- data.dirbuf = (char *) data.dirstreams +- + data.maxdir * sizeof (struct dir_data *); + cp = __stpcpy (data.dirbuf, dir); + /* Strip trailing slashes. */ + while (cp > data.dirbuf + 1 && cp[-1] == '/') +diff --git a/io/tst-ftw-bz28126.c b/io/tst-ftw-bz28126.c +new file mode 100644 +index 0000000000000000..94044ab9d1d0275b +--- /dev/null ++++ b/io/tst-ftw-bz28126.c +@@ -0,0 +1,97 @@ ++/* Check if internal buffer reallocation work for large paths (BZ #28126) ++ Copyright (C) 2021 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 ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++my_func (const char *file, const struct stat *sb, int flag) ++{ ++ return 0; ++} ++ ++static const char folder[NAME_MAX] = { [0 ... 253] = 'a', [254] = '\0' }; ++ ++#define NSUBFOLDERS 16 ++static int nsubfolders; ++ ++static void ++do_cleanup (void) ++{ ++ xchdir (".."); ++ for (int i = 0; i < nsubfolders; i++) ++ { ++ remove (folder); ++ xchdir (".."); ++ } ++ remove (folder); ++} ++#define CLEANUP_HANDLER do_cleanup ++ ++static void ++check_mkdir (const char *path) ++{ ++ int r = mkdir (path, 0777); ++ /* Some filesystem such as overlayfs does not support larger path required ++ to trigger the internal buffer reallocation. */ ++ if (r != 0) ++ { ++ if (errno == ENAMETOOLONG) ++ FAIL_UNSUPPORTED ("the filesystem does not support the required" ++ "large path"); ++ else ++ FAIL_EXIT1 ("mkdir (\"%s\", 0%o): %m", folder, 0777); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ char *tempdir = support_create_temp_directory ("tst-bz28126"); ++ ++ /* Create path with various subfolders to force an internal buffer ++ reallocation within ntfw. */ ++ char *path = xasprintf ("%s/%s", tempdir, folder); ++ check_mkdir (path); ++ xchdir (path); ++ free (path); ++ for (int i = 0; i < NSUBFOLDERS - 1; i++) ++ { ++ check_mkdir (folder); ++ xchdir (folder); ++ nsubfolders++; ++ } ++ ++ TEST_COMPARE (ftw (tempdir, my_func, 20), 0); ++ ++ free (tempdir); ++ ++ do_cleanup (); ++ ++ return 0; ++} ++ ++#include diff --git a/glibc-upstream-2.34-358.patch b/glibc-upstream-2.34-358.patch new file mode 100644 index 0000000..fb4f91e --- /dev/null +++ b/glibc-upstream-2.34-358.patch @@ -0,0 +1,25 @@ +commit deea6ab1bcb2696be514e579f3263c234ecc1683 +Author: Martin Sebor +Date: Tue Jan 25 17:39:02 2022 -0700 + + io: Fix use-after-free in ftw [BZ #26779] + + Reviewed-by: Carlos O'Donell + (cherry picked from commit ee52ab25ba875f458981fce22c54e3c04c7a17d3) + +diff --git a/io/ftw.c b/io/ftw.c +index cf08d9f101657df0..91a4e8e6de151ca1 100644 +--- a/io/ftw.c ++++ b/io/ftw.c +@@ -324,8 +324,9 @@ open_dir_stream (int *dfdp, struct ftw_data *data, struct dir_data *dirp) + buf[actsize++] = '\0'; + + /* Shrink the buffer to what we actually need. */ +- data->dirstreams[data->actdir]->content = realloc (buf, actsize); +- if (data->dirstreams[data->actdir]->content == NULL) ++ void *content = realloc (buf, actsize); ++ data->dirstreams[data->actdir]->content = content; ++ if (content == NULL) + { + int save_err = errno; + free (buf); diff --git a/glibc-upstream-2.34-359.patch b/glibc-upstream-2.34-359.patch new file mode 100644 index 0000000..25fdf9f --- /dev/null +++ b/glibc-upstream-2.34-359.patch @@ -0,0 +1,221 @@ +commit d57cdc1b5a52b5468b9259c0b9a215e22a1fa1f6 +Author: Florian Weimer +Date: Tue Nov 8 14:15:02 2022 +0100 + + Linux: Support __IPC_64 in sysvctl *ctl command arguments (bug 29771) + + Old applications pass __IPC_64 as part of the command argument because + old glibc did not check for unknown commands, and passed through the + arguments directly to the kernel, without adding __IPC_64. + Applications need to continue doing that for old glibc compatibility, + so this commit enables this approach in current glibc. + + For msgctl and shmctl, if no translation is required, make + direct system calls, as we did before the time64 changes. If + translation is required, mask __IPC_64 from the command argument. + + For semctl, the union-in-vararg argument handling means that + translation is needed on all architectures. + + Reviewed-by: Adhemerval Zanella + (cherry picked from commit 22a46dee24351fd5f4f188ad80554cad79c82524) + +diff --git a/sysdeps/unix/sysv/linux/ipc_priv.h b/sysdeps/unix/sysv/linux/ipc_priv.h +index f9852367a466cea9..d4efb9f3483daa9f 100644 +--- a/sysdeps/unix/sysv/linux/ipc_priv.h ++++ b/sysdeps/unix/sysv/linux/ipc_priv.h +@@ -63,4 +63,10 @@ struct __old_ipc_perm + # define __IPC_TIME64 0 + #endif + ++#if __IPC_TIME64 || defined __ASSUME_SYSVIPC_BROKEN_MODE_T ++# define IPC_CTL_NEED_TRANSLATION 1 ++#else ++# define IPC_CTL_NEED_TRANSLATION 0 ++#endif ++ + #include +diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c +index 9f38c06d53936390..ba7b94c22d17bc7f 100644 +--- a/sysdeps/unix/sysv/linux/msgctl.c ++++ b/sysdeps/unix/sysv/linux/msgctl.c +@@ -86,11 +86,19 @@ msgctl_syscall (int msqid, int cmd, msgctl_arg_t *buf) + int + __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf) + { +-#if __IPC_TIME64 ++#if IPC_CTL_NEED_TRANSLATION ++# if __IPC_TIME64 + struct kernel_msqid64_ds ksemid, *arg = NULL; +-#else ++# else + msgctl_arg_t *arg; +-#endif ++# endif ++ ++ /* Some applications pass the __IPC_64 flag in cmd, to invoke ++ previously unsupported commands back when there was no EINVAL ++ error checking in glibc. Mask the flag for the switch statements ++ below. msgctl_syscall adds back the __IPC_64 flag for the actual ++ system call. */ ++ cmd &= ~__IPC_64; + + switch (cmd) + { +@@ -102,19 +110,19 @@ __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf) + case IPC_STAT: + case MSG_STAT: + case MSG_STAT_ANY: +-#if __IPC_TIME64 ++# if __IPC_TIME64 + if (buf != NULL) + { + msqid64_to_kmsqid64 (buf, &ksemid); + arg = &ksemid; + } +-# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T ++# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T + if (cmd == IPC_SET) + arg->msg_perm.mode *= 0x10000U; +-# endif +-#else ++# endif ++# else + arg = buf; +-#endif ++# endif + break; + + case IPC_INFO: +@@ -138,21 +146,25 @@ __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf) + case IPC_STAT: + case MSG_STAT: + case MSG_STAT_ANY: +-#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T ++# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T + arg->msg_perm.mode >>= 16; +-#else ++# else + /* Old Linux kernel versions might not clear the mode padding. */ + if (sizeof ((struct msqid_ds){0}.msg_perm.mode) + != sizeof (__kernel_mode_t)) + arg->msg_perm.mode &= 0xFFFF; +-#endif ++# endif + +-#if __IPC_TIME64 ++# if __IPC_TIME64 + kmsqid64_to_msqid64 (arg, buf); +-#endif ++# endif + } + + return ret; ++ ++#else /* !IPC_CTL_NEED_TRANSLATION */ ++ return msgctl_syscall (msqid, cmd, buf); ++#endif + } + #if __TIMESIZE != 64 + libc_hidden_def (__msgctl64) +diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c +index bb2690d30f80bb22..97fa411547fdd81e 100644 +--- a/sysdeps/unix/sysv/linux/semctl.c ++++ b/sysdeps/unix/sysv/linux/semctl.c +@@ -141,6 +141,13 @@ __semctl64 (int semid, int semnum, int cmd, ...) + union semun64 arg64 = { 0 }; + va_list ap; + ++ /* Some applications pass the __IPC_64 flag in cmd, to invoke ++ previously unsupported commands back when there was no EINVAL ++ error checking in glibc. Mask the flag for the switch statements ++ below. semctl_syscall adds back the __IPC_64 flag for the actual ++ system call. */ ++ cmd &= ~__IPC_64; ++ + /* Get the argument only if required. */ + switch (cmd) + { +diff --git a/sysdeps/unix/sysv/linux/shmctl.c b/sysdeps/unix/sysv/linux/shmctl.c +index f52018bfae4b3364..c44cbd6e4ac890a5 100644 +--- a/sysdeps/unix/sysv/linux/shmctl.c ++++ b/sysdeps/unix/sysv/linux/shmctl.c +@@ -86,11 +86,19 @@ shmctl_syscall (int shmid, int cmd, shmctl_arg_t *buf) + int + __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf) + { +-#if __IPC_TIME64 ++#if IPC_CTL_NEED_TRANSLATION ++# if __IPC_TIME64 + struct kernel_shmid64_ds kshmid, *arg = NULL; +-#else ++# else + shmctl_arg_t *arg; +-#endif ++# endif ++ ++ /* Some applications pass the __IPC_64 flag in cmd, to invoke ++ previously unsupported commands back when there was no EINVAL ++ error checking in glibc. Mask the flag for the switch statements ++ below. shmctl_syscall adds back the __IPC_64 flag for the actual ++ system call. */ ++ cmd &= ~__IPC_64; + + switch (cmd) + { +@@ -104,19 +112,19 @@ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf) + case IPC_STAT: + case SHM_STAT: + case SHM_STAT_ANY: +-#if __IPC_TIME64 ++# if __IPC_TIME64 + if (buf != NULL) + { + shmid64_to_kshmid64 (buf, &kshmid); + arg = &kshmid; + } +-# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T ++# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T + if (cmd == IPC_SET) + arg->shm_perm.mode *= 0x10000U; +-# endif +-#else ++# endif ++# else + arg = buf; +-#endif ++# endif + break; + + case IPC_INFO: +@@ -141,21 +149,25 @@ __shmctl64 (int shmid, int cmd, struct __shmid64_ds *buf) + case IPC_STAT: + case SHM_STAT: + case SHM_STAT_ANY: +-#ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T ++# ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T + arg->shm_perm.mode >>= 16; +-#else ++# else + /* Old Linux kernel versions might not clear the mode padding. */ + if (sizeof ((struct shmid_ds){0}.shm_perm.mode) + != sizeof (__kernel_mode_t)) + arg->shm_perm.mode &= 0xFFFF; +-#endif ++# endif + +-#if __IPC_TIME64 ++# if __IPC_TIME64 + kshmid64_to_shmid64 (arg, buf); +-#endif ++# endif + } + + return ret; ++ ++#else /* !IPC_CTL_NEED_TRANSLATION */ ++ return shmctl_syscall (shmid, cmd, buf); ++#endif + } + #if __TIMESIZE != 64 + libc_hidden_def (__shmctl64) diff --git a/glibc.spec b/glibc.spec index 428a3b6..d5bf422 100644 --- a/glibc.spec +++ b/glibc.spec @@ -148,7 +148,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: 48%{?dist} +Release: 49%{?dist} # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -634,6 +634,21 @@ Patch423: glibc-upstream-2.34-342.patch Patch424: glibc-upstream-2.34-343.patch Patch425: glibc-upstream-2.34-344.patch Patch426: glibc-upstream-2.34-345.patch +Patch427: glibc-upstream-2.34-346.patch +Patch428: glibc-upstream-2.34-347.patch +Patch429: glibc-upstream-2.34-348.patch +Patch430: glibc-upstream-2.34-349.patch +Patch431: glibc-upstream-2.34-350.patch +Patch432: glibc-upstream-2.34-351.patch +Patch433: glibc-upstream-2.34-352.patch +Patch434: glibc-upstream-2.34-353.patch +Patch435: glibc-upstream-2.34-354.patch +Patch436: glibc-upstream-2.34-355.patch +Patch437: glibc-upstream-2.34-356.patch +Patch438: glibc-upstream-2.34-357.patch +Patch439: glibc-upstream-2.34-358.patch +Patch440: glibc-upstream-2.34-359.patch +# glibc-2.34-360-g75b0edb7ef only changes NEWS. ############################################################################## # Continued list of core "glibc" package information: @@ -2690,6 +2705,25 @@ fi %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared %changelog +* Mon Nov 14 2022 Arjun Shankar - 2.34-49 +- Sync with upstream branch release/2.34/master, + commit: 75b0edb7ef338084e53925139ae81fb0dfc07dd4: +- Update NEWS file in the right place +- Linux: Support __IPC_64 in sysvctl *ctl command arguments (bug 29771) +- io: Fix use-after-free in ftw [BZ #26779] +- io: Fix ftw internal realloc buffer (BZ #28126) +- regex: fix buffer read overrun in search [BZ#28470] +- regex: copy back from Gnulib +- Allow #pragma GCC in headers in conformtest +- Fix memmove call in vfprintf-internal.c:group_number +- mktime: improve heuristic for ca-1986 Indiana DST +- Makerules: fix MAKEFLAGS assignment for upcoming make-4.4 [BZ# 29564] +- linux: Fix generic struct_stat for 64 bit time (BZ# 29657) +- elf: Do not completely clear reused namespace in dlmopen (bug 29600) +- nss: Use shared prefix in IPv4 address in tst-reload1 +- nss: Fix tst-nss-files-hosts-long on single-stack hosts (bug 24816) +- nss: Implement --no-addrconfig option for getent + * Thu Oct 13 2022 Arjun Shankar - 2.34-48 - Handle non-hostname CNAME aliases during name resolution (#2129005) - Sync with upstream branch release/2.34/master,