]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
nptl: clear the whole rseq area before registration
authorMichael Jeanson <mjeanson@efficios.com>
Fri, 14 Feb 2025 18:54:22 +0000 (13:54 -0500)
committerMichael Jeanson <mjeanson@efficios.com>
Wed, 12 Mar 2025 19:24:43 +0000 (19:24 +0000)
Due to the extensible nature of the rseq area we can't explictly
initialize fields that are not part of the ABI yet. It was agreed with
upstream that all new fields will be documented as zero initialized by
userspace. Future kernels configured with CONFIG_DEBUG_RSEQ will
validate the content of all fields during registration.

Replace the explicit field initialization with a memset of the whole
rseq area which will cover fields as they are added to future kernels.

Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
(cherry picked from commit 689a62a4217fae78b9ce0db781dc2a421f2b1ab4)

sysdeps/nptl/dl-tls_init_tp.c
sysdeps/unix/sysv/linux/rseq-internal.h

index f487bfb66e78759525680814bae31b63f0405aa7..8629b5d41b09f001b10c78d09b06fcfe794ad79d 100644 (file)
@@ -23,6 +23,7 @@
 #include <tls.h>
 #include <rseq-internal.h>
 #include <thread_pointer.h>
+#include <dl-symbol-redir-ifunc.h>
 
 #define TUNABLE_NAMESPACE pthread
 #include <dl-tunables.h>
index f89e78424317dcd903f6b8c4c17ca241060dedd5..d2ab4cb829bb42490e137f5a0a9ec6baf38e48f6 100644 (file)
@@ -108,13 +108,12 @@ rseq_register_current_thread (struct pthread *self, bool do_rseq)
       if (size < RSEQ_AREA_SIZE_INITIAL)
         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.  */
+      /* Initialize the whole rseq area to zero prior to registration.  */
+      memset (RSEQ_SELF (), 0, size);
+
+      /* Set the cpu_id field to RSEQ_CPU_ID_UNINITIALIZED, this is checked by
+         the kernel at registration when CONFIG_DEBUG_RSEQ is enabled.  */
       RSEQ_SETMEM (cpu_id, RSEQ_CPU_ID_UNINITIALIZED);
-      RSEQ_SETMEM (cpu_id_start, 0);
-      RSEQ_SETMEM (rseq_cs, 0);
-      RSEQ_SETMEM (flags, 0);
 
       int ret = INTERNAL_SYSCALL_CALL (rseq, RSEQ_SELF (), size, 0, RSEQ_SIG);
       if (!INTERNAL_SYSCALL_ERROR_P (ret))