Make __rseq_size useful for feature detection (RHEL-65280)
Resolves: RHEL-65280
This commit is contained in:
parent
025c5d4ac2
commit
6e489a733f
29
glibc-RHEL-65280-1.patch
Normal file
29
glibc-RHEL-65280-1.patch
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
commit 8754a4133e154ca853e6765a3fe5c7a904c77626
|
||||||
|
Author: Joseph Myers <joseph@codesourcery.com>
|
||||||
|
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
|
152
glibc-RHEL-65280-2.patch
Normal file
152
glibc-RHEL-65280-2.patch
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
commit 2b92982e2369d292560793bee8e730f695f48ff3
|
||||||
|
Author: Michael Jeanson <mjeanson@efficios.com>
|
||||||
|
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 <mjeanson@efficios.com>
|
||||||
|
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
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
|
||||||
|
+ <https://www.gnu.org/licenses/>. */
|
||||||
|
+
|
||||||
|
+#include <sysdep.h>
|
||||||
|
+
|
||||||
|
+#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
|
||||||
|
}
|
||||||
|
|
136
glibc-RHEL-65280-3.patch
Normal file
136
glibc-RHEL-65280-3.patch
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
commit 2e456ccf0c34a056e3ccafac4a0c7effef14d918
|
||||||
|
Author: Florian Weimer <fweimer@redhat.com>
|
||||||
|
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 <mjeanson@efficios.com>
|
||||||
|
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||||
|
|
||||||
|
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 <stdio.h>
|
||||||
|
#include <sys/rseq.h>
|
||||||
|
|
||||||
|
+/* 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 <stdlib.h>
|
||||||
|
# include <string.h>
|
||||||
|
# include <syscall.h>
|
||||||
|
+# include <sys/auxv.h>
|
||||||
|
# include <thread_pointer.h>
|
||||||
|
# include <tls.h>
|
||||||
|
# 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 */
|
54
glibc-RHEL-65280-4.patch
Normal file
54
glibc-RHEL-65280-4.patch
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
commit 97f60abd25628425971f07e9b0e7f8eec0741235
|
||||||
|
Author: Michael Jeanson <mjeanson@efficios.com>
|
||||||
|
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 <mjeanson@efficios.com>
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
28
glibc-RHEL-65280-5.patch
Normal file
28
glibc-RHEL-65280-5.patch
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
commit d9f40387d3305d97e30a8cf8724218c42a63680a
|
||||||
|
Author: Michael Jeanson <mjeanson@efficios.com>
|
||||||
|
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 <mjeanson@efficios.com>
|
||||||
|
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
158
glibc-RHEL-65280-6.patch
Normal file
158
glibc-RHEL-65280-6.patch
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
commit c813c1490d5d8640a94fced10fc7674a48737b96
|
||||||
|
Author: Michael Jeanson <mjeanson@efficios.com>
|
||||||
|
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 <mjeanson@efficios.com>
|
||||||
|
Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||||
|
Reviewed-by: Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
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 <fpu_control.h>
|
||||||
|
#include <ldsodefs.h>
|
||||||
|
#include <link.h>
|
||||||
|
+#include <rseq-internal.h>
|
||||||
|
|
||||||
|
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 <stdio.h>
|
||||||
|
#include <sys/rseq.h>
|
||||||
|
|
||||||
|
-/* 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 <syscall.h>
|
||||||
|
#include <sys/rseq.h>
|
||||||
|
#include <tls.h>
|
||||||
|
+#include <rseq-internal.h>
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
rseq_thread_registered (void)
|
11
glibc.spec
11
glibc.spec
@ -157,7 +157,7 @@ end \
|
|||||||
Summary: The GNU libc libraries
|
Summary: The GNU libc libraries
|
||||||
Name: glibc
|
Name: glibc
|
||||||
Version: %{glibcversion}
|
Version: %{glibcversion}
|
||||||
Release: 172%{?dist}
|
Release: 173%{?dist}
|
||||||
|
|
||||||
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
|
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
|
||||||
# libraries.
|
# libraries.
|
||||||
@ -1123,6 +1123,12 @@ Patch815: glibc-RHEL-67593.patch
|
|||||||
Patch816: glibc-RHEL-46729.patch
|
Patch816: glibc-RHEL-46729.patch
|
||||||
Patch817: glibc-RHEL-61569-1.patch
|
Patch817: glibc-RHEL-61569-1.patch
|
||||||
Patch818: glibc-RHEL-61569-2.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:
|
# Continued list of core "glibc" package information:
|
||||||
@ -3116,6 +3122,9 @@ update_gconv_modules_cache ()
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Mar 06 2025 Arjun Shankar <arjun@redhat.com> - 2.34-173
|
||||||
|
- Make __rseq_size useful for feature detection (RHEL-65280)
|
||||||
|
|
||||||
* Mon Mar 03 2025 Frederic Berat <fberat@redhat.com> - 2.34-172
|
* Mon Mar 03 2025 Frederic Berat <fberat@redhat.com> - 2.34-172
|
||||||
- Backport: support: Add support_next_to_fault_before support function
|
- Backport: support: Add support_next_to_fault_before support function
|
||||||
(RHEL-61569)
|
(RHEL-61569)
|
||||||
|
Loading…
Reference in New Issue
Block a user