From 6e489a733fb827bd60ee55967c946bf87ecd6144 Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Thu, 6 Mar 2025 17:10:59 +0100 Subject: [PATCH] Make __rseq_size useful for feature detection (RHEL-65280) Resolves: RHEL-65280 --- glibc-RHEL-65280-1.patch | 29 +++++++ glibc-RHEL-65280-2.patch | 152 +++++++++++++++++++++++++++++++++++++ glibc-RHEL-65280-3.patch | 136 +++++++++++++++++++++++++++++++++ glibc-RHEL-65280-4.patch | 54 +++++++++++++ glibc-RHEL-65280-5.patch | 28 +++++++ glibc-RHEL-65280-6.patch | 158 +++++++++++++++++++++++++++++++++++++++ glibc.spec | 11 ++- 7 files changed, 567 insertions(+), 1 deletion(-) create mode 100644 glibc-RHEL-65280-1.patch create mode 100644 glibc-RHEL-65280-2.patch create mode 100644 glibc-RHEL-65280-3.patch create mode 100644 glibc-RHEL-65280-4.patch create mode 100644 glibc-RHEL-65280-5.patch create mode 100644 glibc-RHEL-65280-6.patch diff --git a/glibc-RHEL-65280-1.patch b/glibc-RHEL-65280-1.patch new file mode 100644 index 0000000..e596d78 --- /dev/null +++ b/glibc-RHEL-65280-1.patch @@ -0,0 +1,29 @@ +commit 8754a4133e154ca853e6765a3fe5c7a904c77626 +Author: Joseph Myers +Date: Fri May 26 15:03:31 2023 +0000 + + Add AT_RSEQ_* from Linux 6.3 to elf.h + + Linux 6.3 adds constants AT_RSEQ_FEATURE_SIZE and AT_RSEQ_ALIGN; add + them to glibc's elf.h. (Recall that, although elf.h is a + system-independent header, so far we've put AT_* constants there even + if Linux-specific, as discussed in bug 15794. So rather than making + any attempt to fix that issue, the new constants are just added there + alongside the existing ones.) + + Tested for x86_64. + +diff --git a/elf/elf.h b/elf/elf.h +index 4738dfa28f6549fc..076d8e3f696c58f7 100644 +--- a/elf/elf.h ++++ b/elf/elf.h +@@ -1205,6 +1205,9 @@ typedef struct + #define AT_HWCAP2 26 /* More machine-dependent hints about + processor capabilities. */ + ++#define AT_RSEQ_FEATURE_SIZE 27 /* rseq supported feature size. */ ++#define AT_RSEQ_ALIGN 28 /* rseq allocation alignment. */ ++ + #define AT_EXECFN 31 /* Filename of executable. */ + + /* Pointer to the global system page used for system calls and other diff --git a/glibc-RHEL-65280-2.patch b/glibc-RHEL-65280-2.patch new file mode 100644 index 0000000..4172c7d --- /dev/null +++ b/glibc-RHEL-65280-2.patch @@ -0,0 +1,152 @@ +commit 2b92982e2369d292560793bee8e730f695f48ff3 +Author: Michael Jeanson +Date: Wed Jul 3 12:35:34 2024 -0400 + + nptl: fix potential merge of __rseq_* relro symbols + + While working on a patch to add support for the extensible rseq ABI, we + came across an issue where a new 'const' variable would be merged with + the existing '__rseq_size' variable. We tracked this to the use of + '-fmerge-all-constants' which allows the compiler to merge identical + constant variables. This means that all 'const' variables in a compile + unit that are of the same size and are initialized to the same value can + be merged. + + In this specific case, on 32 bit systems 'unsigned int' and 'ptrdiff_t' + are both 4 bytes and initialized to 0 which should trigger the merge. + However for reasons we haven't delved into when the attribute 'section + (".data.rel.ro")' is added to the mix, only variables of the same exact + types are merged. As far as we know this behavior is not specified + anywhere and could change with a new compiler version, hence this patch. + + Move the definitions of these variables into an assembler file and add + hidden writable aliases for internal use. This has the added bonus of + removing the asm workaround to set the values on rseq registration. + + Tested on Debian 12 with GCC 12.2. + + Signed-off-by: Michael Jeanson + Reviewed-by: Mathieu Desnoyers + Reviewed-by: Florian Weimer + +diff --git a/elf/Makefile b/elf/Makefile +index e0a86a305c4dc2ed..ec0d67b1549823ad 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -69,6 +69,7 @@ dl-routines = \ + dl-printf \ + dl-profile \ + dl-reloc \ ++ dl-rseq-symbols \ + dl-runtime \ + dl-scope \ + dl-setup_hash \ +diff --git a/elf/dl-rseq-symbols.S b/elf/dl-rseq-symbols.S +new file mode 100644 +index 0000000000000000..b4bba06a99b0a486 +--- /dev/null ++++ b/elf/dl-rseq-symbols.S +@@ -0,0 +1,64 @@ ++/* Define symbols used by rseq. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#if __WORDSIZE == 64 ++#define RSEQ_OFFSET_SIZE 8 ++#else ++#define RSEQ_OFFSET_SIZE 4 ++#endif ++ ++/* Some targets define a macro to denote the zero register. */ ++#undef zero ++ ++/* Define 2 symbols: '__rseq_size' is public const and '_rseq_size' (an ++ alias of '__rseq_size') is hidden and writable for internal use by the ++ dynamic linker which will initialize the value both symbols point to ++ before copy relocations take place. */ ++ ++ .globl __rseq_size ++ .type __rseq_size, %object ++ .size __rseq_size, 4 ++ .hidden _rseq_size ++ .globl _rseq_size ++ .type _rseq_size, %object ++ .size _rseq_size, 4 ++ .section .data.rel.ro ++ .balign 4 ++__rseq_size: ++_rseq_size: ++ .zero 4 ++ ++/* Define 2 symbols: '__rseq_offset' is public const and '_rseq_offset' (an ++ alias of '__rseq_offset') is hidden and writable for internal use by the ++ dynamic linker which will initialize the value both symbols point to ++ before copy relocations take place. */ ++ ++ .globl __rseq_offset ++ .type __rseq_offset, %object ++ .size __rseq_offset, RSEQ_OFFSET_SIZE ++ .hidden _rseq_offset ++ .globl _rseq_offset ++ .type _rseq_offset, %object ++ .size _rseq_offset, RSEQ_OFFSET_SIZE ++ .section .data.rel.ro ++ .balign RSEQ_OFFSET_SIZE ++__rseq_offset: ++_rseq_offset: ++ .zero RSEQ_OFFSET_SIZE +diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c +index d5f2587f1348441c..039080d7110f5064 100644 +--- a/sysdeps/nptl/dl-tls_init_tp.c ++++ b/sysdeps/nptl/dl-tls_init_tp.c +@@ -45,8 +45,10 @@ rtld_mutex_dummy (pthread_mutex_t *lock) + #endif + + const unsigned int __rseq_flags; +-const unsigned int __rseq_size attribute_relro; +-const ptrdiff_t __rseq_offset attribute_relro; ++ ++/* The variables are in .data.relro but are not yet write-protected. */ ++extern unsigned int _rseq_size attribute_hidden; ++extern ptrdiff_t _rseq_offset attribute_hidden; + + void + __tls_pre_init_tp (void) +@@ -107,10 +109,7 @@ __tls_init_tp (void) + #endif + if (rseq_register_current_thread (pd, do_rseq)) + { +- /* We need a writable view of the variables. They are in +- .data.relro and are not yet write-protected. */ +- extern unsigned int size __asm__ ("__rseq_size"); +- size = sizeof (pd->rseq_area); ++ _rseq_size = sizeof (pd->rseq_area); + } + + #ifdef RSEQ_SIG +@@ -119,8 +118,7 @@ __tls_init_tp (void) + all targets support __thread_pointer, so set __rseq_offset only + if thre rseq registration may have happened because RSEQ_SIG is + defined. */ +- extern ptrdiff_t offset __asm__ ("__rseq_offset"); +- offset = (char *) &pd->rseq_area - (char *) __thread_pointer (); ++ _rseq_offset = (char *) &pd->rseq_area - (char *) __thread_pointer (); + #endif + } + diff --git a/glibc-RHEL-65280-3.patch b/glibc-RHEL-65280-3.patch new file mode 100644 index 0000000..4e969df --- /dev/null +++ b/glibc-RHEL-65280-3.patch @@ -0,0 +1,136 @@ +commit 2e456ccf0c34a056e3ccafac4a0c7effef14d918 +Author: Florian Weimer +Date: Mon Jul 8 21:14:00 2024 +0200 + + Linux: Make __rseq_size useful for feature detection (bug 31965) + + The __rseq_size value is now the active area of struct rseq + (so 20 initially), not the full struct size including padding + at the end (32 initially). + + Update misc/tst-rseq to print some additional diagnostics. + + Reviewed-by: Michael Jeanson + Reviewed-by: Mathieu Desnoyers + +diff --git a/manual/threads.texi b/manual/threads.texi +index 3fd307e69a8029fa..42e824fcdbec60f6 100644 +--- a/manual/threads.texi ++++ b/manual/threads.texi +@@ -1007,8 +1007,12 @@ This variable is either zero (if restartable sequence registration + failed or has been disabled) or the size of the restartable sequence + registration. This can be different from the size of @code{struct rseq} + if the kernel has extended the size of the registration. If +-registration is successful, @code{__rseq_size} is at least 32 (the +-initial size of @code{struct rseq}). ++registration is successful, @code{__rseq_size} is at least 20 (the ++initially active size of @code{struct rseq}). ++ ++Previous versions of @theglibc{} set this to 32 even if the kernel only ++supported the initial area of 20 bytes because the value included unused ++padding at the end of the restartable sequence area. + @end deftypevar + + @deftypevar {unsigned int} __rseq_flags +diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c +index 039080d7110f5064..2f56281a02246a09 100644 +--- a/sysdeps/nptl/dl-tls_init_tp.c ++++ b/sysdeps/nptl/dl-tls_init_tp.c +@@ -46,10 +46,6 @@ rtld_mutex_dummy (pthread_mutex_t *lock) + + const unsigned int __rseq_flags; + +-/* The variables are in .data.relro but are not yet write-protected. */ +-extern unsigned int _rseq_size attribute_hidden; +-extern ptrdiff_t _rseq_offset attribute_hidden; +- + void + __tls_pre_init_tp (void) + { +@@ -108,9 +104,7 @@ __tls_init_tp (void) + do_rseq = TUNABLE_GET (rseq, int, NULL); + #endif + if (rseq_register_current_thread (pd, do_rseq)) +- { +- _rseq_size = sizeof (pd->rseq_area); +- } ++ _rseq_size = RSEQ_AREA_SIZE_INITIAL_USED; + + #ifdef RSEQ_SIG + /* This should be a compile-time constant, but the current +diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h +index 9e8f99fd51a063b1..ccb16640133fa9e3 100644 +--- a/sysdeps/unix/sysv/linux/rseq-internal.h ++++ b/sysdeps/unix/sysv/linux/rseq-internal.h +@@ -25,15 +25,34 @@ + #include + #include + ++/* 32 is the initially required value for the area size. The ++ actually used rseq size may be less (20 bytes initially). */ ++#define RSEQ_AREA_SIZE_INITIAL 32 ++#define RSEQ_AREA_SIZE_INITIAL_USED 20 ++ ++/* The variables are in .data.relro but are not yet write-protected. */ ++extern unsigned int _rseq_size attribute_hidden; ++extern ptrdiff_t _rseq_offset attribute_hidden; ++ + #ifdef RSEQ_SIG + static inline bool + rseq_register_current_thread (struct pthread *self, bool do_rseq) + { + if (do_rseq) + { ++ unsigned int size; ++#if IS_IN (rtld) ++ /* Use the hidden symbol in ld.so. */ ++ size = _rseq_size; ++#else ++ size = __rseq_size; ++#endif ++ if (size < RSEQ_AREA_SIZE_INITIAL) ++ /* The initial implementation used only 20 bytes out of 32, ++ but still expected size 32. */ ++ size = RSEQ_AREA_SIZE_INITIAL; + int ret = INTERNAL_SYSCALL_CALL (rseq, &self->rseq_area, +- sizeof (self->rseq_area), +- 0, RSEQ_SIG); ++ size, 0, RSEQ_SIG); + if (!INTERNAL_SYSCALL_ERROR_P (ret)) + return true; + } +diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c +index 572c11166f8b6533..1d404db610c08fdf 100644 +--- a/sysdeps/unix/sysv/linux/tst-rseq.c ++++ b/sysdeps/unix/sysv/linux/tst-rseq.c +@@ -29,6 +29,7 @@ + # include + # include + # include ++# include + # include + # include + # include "tst-rseq.h" +@@ -42,7 +43,8 @@ do_rseq_main_test (void) + TEST_COMPARE (__rseq_flags, 0); + TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset + == (char *) &pd->rseq_area); +- TEST_COMPARE (__rseq_size, sizeof (pd->rseq_area)); ++ /* The current implementation only supports the initial size. */ ++ TEST_COMPARE (__rseq_size, 20); + } + + static void +@@ -52,6 +54,12 @@ do_rseq_test (void) + { + FAIL_UNSUPPORTED ("kernel does not support rseq, skipping test"); + } ++ printf ("info: __rseq_size: %u\n", __rseq_size); ++ printf ("info: __rseq_offset: %td\n", __rseq_offset); ++ printf ("info: __rseq_flags: %u\n", __rseq_flags); ++ printf ("info: getauxval (AT_RSEQ_FEATURE_SIZE): %ld\n", ++ getauxval (AT_RSEQ_FEATURE_SIZE)); ++ printf ("info: getauxval (AT_RSEQ_ALIGN): %ld\n", getauxval (AT_RSEQ_ALIGN)); + do_rseq_main_test (); + } + #else /* RSEQ_SIG */ diff --git a/glibc-RHEL-65280-4.patch b/glibc-RHEL-65280-4.patch new file mode 100644 index 0000000..55bd8f0 --- /dev/null +++ b/glibc-RHEL-65280-4.patch @@ -0,0 +1,54 @@ +commit 97f60abd25628425971f07e9b0e7f8eec0741235 +Author: Michael Jeanson +Date: Thu Nov 7 22:23:49 2024 +0100 + + nptl: initialize rseq area prior to registration + + Per the rseq syscall documentation, 3 fields are required to be + initialized by userspace prior to registration, they are 'cpu_id', + 'rseq_cs' and 'flags'. Since we have no guarantee that 'struct pthread' + is cleared on all architectures, explicitly set those 3 fields prior to + registration. + + Signed-off-by: Michael Jeanson + Reviewed-by: Florian Weimer + +diff --git a/nptl/descr.h b/nptl/descr.h +index 6484e3703f9a0a97..c08c5149c7239e7c 100644 +--- a/nptl/descr.h ++++ b/nptl/descr.h +@@ -424,6 +424,8 @@ struct pthread + { + uint32_t cpu_id_start; + uint32_t cpu_id; ++ uint64_t rseq_cs; ++ uint32_t flags; + }; + char pad[32]; /* Original rseq area size. */ + } rseq_area __attribute__ ((aligned (32))); +diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h +index ccb16640133fa9e3..7e70ae7ebdee4917 100644 +--- a/sysdeps/unix/sysv/linux/rseq-internal.h ++++ b/sysdeps/unix/sysv/linux/rseq-internal.h +@@ -51,11 +51,21 @@ rseq_register_current_thread (struct pthread *self, bool do_rseq) + /* The initial implementation used only 20 bytes out of 32, + but still expected size 32. */ + size = RSEQ_AREA_SIZE_INITIAL; ++ ++ /* Initialize the rseq fields that are read by the kernel on ++ registration, there is no guarantee that struct pthread is ++ cleared on all architectures. */ ++ THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_UNINITIALIZED); ++ THREAD_SETMEM (self, rseq_area.rseq_cs, 0); ++ THREAD_SETMEM (self, rseq_area.flags, 0); ++ + int ret = INTERNAL_SYSCALL_CALL (rseq, &self->rseq_area, + size, 0, RSEQ_SIG); + if (!INTERNAL_SYSCALL_ERROR_P (ret)) + return true; + } ++ /* When rseq is disabled by tunables or the registration fails, inform ++ userspace by setting 'cpu_id' to RSEQ_CPU_ID_REGISTRATION_FAILED. */ + THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_REGISTRATION_FAILED); + return false; + } diff --git a/glibc-RHEL-65280-5.patch b/glibc-RHEL-65280-5.patch new file mode 100644 index 0000000..8265f04 --- /dev/null +++ b/glibc-RHEL-65280-5.patch @@ -0,0 +1,28 @@ +commit d9f40387d3305d97e30a8cf8724218c42a63680a +Author: Michael Jeanson +Date: Wed Nov 20 14:15:42 2024 -0500 + + nptl: initialize cpu_id_start prior to rseq registration + + When adding explicit initialization of rseq fields prior to + registration, I glossed over the fact that 'cpu_id_start' is also + documented as initialized by user-space. + + While current kernels don't validate the content of this field on + registration, future ones could. + + Signed-off-by: Michael Jeanson + Reviewed-by: Mathieu Desnoyers + +diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h +index 7e70ae7ebdee4917..c108a12a6227eeac 100644 +--- a/sysdeps/unix/sysv/linux/rseq-internal.h ++++ b/sysdeps/unix/sysv/linux/rseq-internal.h +@@ -56,6 +56,7 @@ rseq_register_current_thread (struct pthread *self, bool do_rseq) + registration, there is no guarantee that struct pthread is + cleared on all architectures. */ + THREAD_SETMEM (self, rseq_area.cpu_id, RSEQ_CPU_ID_UNINITIALIZED); ++ THREAD_SETMEM (self, rseq_area.cpu_id_start, 0); + THREAD_SETMEM (self, rseq_area.rseq_cs, 0); + THREAD_SETMEM (self, rseq_area.flags, 0); + diff --git a/glibc-RHEL-65280-6.patch b/glibc-RHEL-65280-6.patch new file mode 100644 index 0000000..80d354a --- /dev/null +++ b/glibc-RHEL-65280-6.patch @@ -0,0 +1,158 @@ +commit c813c1490d5d8640a94fced10fc7674a48737b96 +Author: Michael Jeanson +Date: Wed Jul 10 15:37:28 2024 -0400 + + nptl: Add rseq auxvals + + Get the rseq feature size and alignment requirement from the auxiliary + vector for use inside the dynamic loader. Use '__rseq_size' directly to + store the feature size. If the main thread registration fails or is + disabled by tunable, reset the value to 0. + + This will be used in the TLS block allocator to compute the size and + alignment of the rseq area block for the extended ABI support. + + Signed-off-by: Michael Jeanson + Reviewed-by: Mathieu Desnoyers + Reviewed-by: Florian Weimer + +Conflicts: + sysdeps/nptl/dl-tls_init_tp.c: Adjust for skipped commit: + 33237fe83d553dff (Remove --enable-tunables configure option) + +diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c +index 2f56281a02246a09..20552b11843148fb 100644 +--- a/sysdeps/nptl/dl-tls_init_tp.c ++++ b/sysdeps/nptl/dl-tls_init_tp.c +@@ -46,6 +46,8 @@ rtld_mutex_dummy (pthread_mutex_t *lock) + + const unsigned int __rseq_flags; + ++size_t _rseq_align attribute_hidden; ++ + void + __tls_pre_init_tp (void) + { +@@ -99,12 +101,17 @@ __tls_init_tp (void) + } + + { ++ /* If the registration fails or is disabled by tunable, the public ++ '__rseq_size' will be set to '0' regardless of the feature size of the ++ allocated rseq area. An rseq area of at least 32 bytes is always ++ allocated since application code is allowed to check the status of the ++ rseq registration by reading the content of the 'cpu_id' field. */ + bool do_rseq = true; + #if HAVE_TUNABLES + do_rseq = TUNABLE_GET (rseq, int, NULL); + #endif +- if (rseq_register_current_thread (pd, do_rseq)) +- _rseq_size = RSEQ_AREA_SIZE_INITIAL_USED; ++ if (!rseq_register_current_thread (pd, do_rseq)) ++ _rseq_size = 0; + + #ifdef RSEQ_SIG + /* This should be a compile-time constant, but the current +diff --git a/sysdeps/unix/sysv/linux/dl-parse_auxv.h b/sysdeps/unix/sysv/linux/dl-parse_auxv.h +index bf9374371eb217fc..44c135c56570134e 100644 +--- a/sysdeps/unix/sysv/linux/dl-parse_auxv.h ++++ b/sysdeps/unix/sysv/linux/dl-parse_auxv.h +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + typedef ElfW(Addr) dl_parse_auxv_t[AT_MINSIGSTKSZ + 1]; + +@@ -57,5 +58,17 @@ void _dl_parse_auxv (ElfW(auxv_t) *av, dl_parse_auxv_t auxv_values) + GLRO(dl_sysinfo) = auxv_values[AT_SYSINFO]; + #endif + ++ /* Get the rseq feature size, with a minimum of RSEQ_AREA_SIZE_INITIAL_USED ++ (20) for kernels that don't have AT_RSEQ_FEATURE_SIZE. Limit the feature ++ size to RSEQ_AREA_SIZE_MAX_USED (28) which fits the rseq area in 'struct ++ pthread' and represents the maximum feature size of currently released ++ kernels. Since no kernels currently cross the 32 bytes of the original ++ ABI, the semantics of a feature size of 32 or more are still undetermined. ++ */ ++ _rseq_size = MIN (MAX (auxv_values[AT_RSEQ_FEATURE_SIZE], ++ RSEQ_AREA_SIZE_INITIAL_USED), ++ RSEQ_AREA_SIZE_MAX_USED); ++ _rseq_align = MAX (auxv_values[AT_RSEQ_ALIGN], RSEQ_MIN_ALIGN); ++ + DL_PLATFORM_AUXV + } +diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h +index c108a12a6227eeac..f4027b09519a652b 100644 +--- a/sysdeps/unix/sysv/linux/rseq-internal.h ++++ b/sysdeps/unix/sysv/linux/rseq-internal.h +@@ -25,13 +25,31 @@ + #include + #include + +-/* 32 is the initially required value for the area size. The +- actually used rseq size may be less (20 bytes initially). */ ++/* Minimum size of the rseq area allocation required by the syscall. The ++ actually used rseq feature size may be less (20 bytes initially). */ + #define RSEQ_AREA_SIZE_INITIAL 32 ++ ++/* Minimum used feature size of the rseq area. */ + #define RSEQ_AREA_SIZE_INITIAL_USED 20 + +-/* The variables are in .data.relro but are not yet write-protected. */ ++/* Maximum currently used feature size of the rseq area. */ ++#define RSEQ_AREA_SIZE_MAX_USED 28 ++ ++/* Minimum alignment of the rseq area. */ ++#define RSEQ_MIN_ALIGN 32 ++ ++/* Alignment requirement of the rseq area. ++ Populated from the auxiliary vector with a minimum of '32'. ++ In .data.relro but not yet write-protected. */ ++extern size_t _rseq_align attribute_hidden; ++ ++/* Size of the active features in the rseq area. ++ Populated from the auxiliary vector with a minimum of '20'. ++ In .data.relro but not yet write-protected. */ + extern unsigned int _rseq_size attribute_hidden; ++ ++/* Offset from the thread pointer to the rseq area. ++ In .data.relro but not yet write-protected. */ + extern ptrdiff_t _rseq_offset attribute_hidden; + + #ifdef RSEQ_SIG +diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c +index 1d404db610c08fdf..5946db73d9b079c3 100644 +--- a/sysdeps/unix/sysv/linux/tst-rseq.c ++++ b/sysdeps/unix/sysv/linux/tst-rseq.c +@@ -38,13 +38,15 @@ static void + do_rseq_main_test (void) + { + struct pthread *pd = THREAD_SELF; ++ size_t rseq_feature_size = MIN (MAX (getauxval (AT_RSEQ_FEATURE_SIZE), ++ RSEQ_AREA_SIZE_INITIAL_USED), ++ RSEQ_AREA_SIZE_MAX_USED); + + TEST_VERIFY_EXIT (rseq_thread_registered ()); + TEST_COMPARE (__rseq_flags, 0); + TEST_VERIFY ((char *) __thread_pointer () + __rseq_offset + == (char *) &pd->rseq_area); +- /* The current implementation only supports the initial size. */ +- TEST_COMPARE (__rseq_size, 20); ++ TEST_COMPARE (__rseq_size, rseq_feature_size); + } + + static void +diff --git a/sysdeps/unix/sysv/linux/tst-rseq.h b/sysdeps/unix/sysv/linux/tst-rseq.h +index a476c316fc2671a0..86cf50fbeff32384 100644 +--- a/sysdeps/unix/sysv/linux/tst-rseq.h ++++ b/sysdeps/unix/sysv/linux/tst-rseq.h +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + static inline bool + rseq_thread_registered (void) diff --git a/glibc.spec b/glibc.spec index a3764f6..d107e00 100644 --- a/glibc.spec +++ b/glibc.spec @@ -157,7 +157,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: 172%{?dist} +Release: 173%{?dist} # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -1123,6 +1123,12 @@ Patch815: glibc-RHEL-67593.patch Patch816: glibc-RHEL-46729.patch Patch817: glibc-RHEL-61569-1.patch Patch818: glibc-RHEL-61569-2.patch +Patch819: glibc-RHEL-65280-1.patch +Patch820: glibc-RHEL-65280-2.patch +Patch821: glibc-RHEL-65280-3.patch +Patch822: glibc-RHEL-65280-4.patch +Patch823: glibc-RHEL-65280-5.patch +Patch824: glibc-RHEL-65280-6.patch ############################################################################## # Continued list of core "glibc" package information: @@ -3116,6 +3122,9 @@ update_gconv_modules_cache () %endif %changelog +* Thu Mar 06 2025 Arjun Shankar - 2.34-173 +- Make __rseq_size useful for feature detection (RHEL-65280) + * Mon Mar 03 2025 Frederic Berat - 2.34-172 - Backport: support: Add support_next_to_fault_before support function (RHEL-61569)