diff options
author | CoprDistGit <infra@openeuler.org> | 2024-10-09 03:36:26 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2024-10-09 03:36:26 +0000 |
commit | db43dfdfa8bc2b938582aef3d87e43594c13ee50 (patch) | |
tree | 47b95b2f6ac8d8b7e6fa373a5bd7d661bf7234df /0004-Linux-Make-__rseq_size-useful-for-feature-detection-.patch | |
parent | b933872de72b006230559f77acc3ccfb38a1f343 (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-.patch | 171 |
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 + |