summaryrefslogtreecommitdiff
path: root/0004-Linux-Make-__rseq_size-useful-for-feature-detection-.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-10-09 03:36:26 +0000
committerCoprDistGit <infra@openeuler.org>2024-10-09 03:36:26 +0000
commitdb43dfdfa8bc2b938582aef3d87e43594c13ee50 (patch)
tree47b95b2f6ac8d8b7e6fa373a5bd7d661bf7234df /0004-Linux-Make-__rseq_size-useful-for-feature-detection-.patch
parentb933872de72b006230559f77acc3ccfb38a1f343 (diff)
automatic import of glibcopeneuler20.03
Diffstat (limited to '0004-Linux-Make-__rseq_size-useful-for-feature-detection-.patch')
-rw-r--r--0004-Linux-Make-__rseq_size-useful-for-feature-detection-.patch171
1 files changed, 171 insertions, 0 deletions
diff --git a/0004-Linux-Make-__rseq_size-useful-for-feature-detection-.patch b/0004-Linux-Make-__rseq_size-useful-for-feature-detection-.patch
new file mode 100644
index 0000000..3dd3fd1
--- /dev/null
+++ b/0004-Linux-Make-__rseq_size-useful-for-feature-detection-.patch
@@ -0,0 +1,171 @@
+From bb30bd21622910715b7b3020b17e6e97a8b4ec80 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Mon, 8 Jul 2024 21:14:00 +0200
+Subject: [PATCH 04/12] 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>
+(cherry picked from commit 2e456ccf0c34a056e3ccafac4a0c7effef14d918)
+---
+ NEWS | 6 ++++++
+ manual/threads.texi | 8 ++++++--
+ sysdeps/nptl/dl-tls_init_tp.c | 8 +-------
+ sysdeps/unix/sysv/linux/rseq-internal.h | 23 +++++++++++++++++++++--
+ sysdeps/unix/sysv/linux/tst-rseq.c | 10 +++++++++-
+ 5 files changed, 43 insertions(+), 12 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index 6768c2da6f..f0a0834496 100644
+--- a/NEWS
++++ b/NEWS
+@@ -7,6 +7,11 @@ using `glibc' in the "product" field.
+
+ Version 2.38.1
+
++Deprecated and removed features, and other changes affecting compatibility:
++
++* __rseq_size now denotes the size of the active rseq area (20 bytes
++ initially), not the size of struct rseq (32 bytes initially).
++
+ Security related changes:
+
+ CVE-2023-4527: If the system is configured in no-aaaa mode via
+@@ -46,6 +51,7 @@ The following bugs are resolved with this release:
+ [31183] Wide stream buffer size reduced MB_LEN_MAX bytes after bug 17522 fix
+ [31184] FAIL: elf/tst-tlsgap
+ [31185] Incorrect thread point access in _dl_tlsdesc_undefweak and _dl_tlsdesc_dynamic
++ [31965] rseq extension mechanism does not work as intended
+
+
+ Version 2.38
+diff --git a/manual/threads.texi b/manual/threads.texi
+index e5544ff3da..25e99c9606 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 45ae260ceb..8f731393c4 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)
+ {
+@@ -106,9 +102,7 @@ __tls_init_tp (void)
+ bool do_rseq = true;
+ do_rseq = TUNABLE_GET (rseq, int, NULL);
+ 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 294880c04e..226ba59a24 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 16983503b1..9f9aa7eb21 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 */
+--
+2.33.0
+