Blob Blame History Raw
Disable rseq integration until the Firefox sandbox supports rseq.

Sandbox is incompatible with rseq registration
<https://bugzilla.mozilla.org/show_bug.cgi?id=1651701>

diff --git a/elf/libc_early_init.c b/elf/libc_early_init.c
index 86da66d5e01af08f..fd779941e7180fb6 100644
--- a/elf/libc_early_init.c
+++ b/elf/libc_early_init.c
@@ -28,8 +28,9 @@ __libc_early_init (_Bool initial)
   __ctype_init ();
 
   /* Register rseq ABI to the kernel for the main program's libc.   */
+  rseq_active_init ();
   if (initial)
-    rseq_register_current_thread ();
+      rseq_register_current_thread ();
 
   /* Only the outer namespace is marked as single-threaded.  */
   __libc_single_threaded = initial;
diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions
index f72741b7e5afb22a..a730077142f0e20a 100644
--- a/sysdeps/unix/sysv/linux/Versions
+++ b/sysdeps/unix/sysv/linux/Versions
@@ -171,6 +171,8 @@ libc {
     __rseq_abi;
   }
   GLIBC_PRIVATE {
+    __rseq_active;
+
     # functions used in other libraries
     __syscall_rt_sigqueueinfo;
     __open_nocancel;
diff --git a/sysdeps/unix/sysv/linux/rseq-internal.h b/sysdeps/unix/sysv/linux/rseq-internal.h
index 8f6772ca1deada89..acaf033be465facd 100644
--- a/sysdeps/unix/sysv/linux/rseq-internal.h
+++ b/sysdeps/unix/sysv/linux/rseq-internal.h
@@ -23,13 +23,29 @@
 #include <kernel-features.h>
 #include <stdio.h>
 #include <sys/rseq.h>
+#include <unistd.h>
 
 #ifdef RSEQ_SIG
+
+extern _Bool __rseq_active;
+
+static inline void
+rseq_active_init (void)
+{
+  __rseq_active = __access ("/etc/glibc.rseq.enabled", F_OK) == 0;
+}
+
 static inline void
 rseq_register_current_thread (void)
 {
   int ret;
 
+  if (!__rseq_active)
+    {
+      __rseq_abi.cpu_id = RSEQ_CPU_ID_REGISTRATION_FAILED;
+      return;
+    }
+
   if (__rseq_abi.cpu_id != RSEQ_CPU_ID_UNINITIALIZED)
     __libc_fatal ("glibc fatal error: "
                   "rseq already initialized for this thread\n");
@@ -64,6 +80,11 @@ rseq_register_current_thread (void)
     }
 }
 #else /* RSEQ_SIG */
+static inline void
+rseq_active_init (void)
+{
+}
+
 static inline void
 rseq_register_current_thread (void)
 {
diff --git a/sysdeps/unix/sysv/linux/rseq-sym.c b/sysdeps/unix/sysv/linux/rseq-sym.c
index 090093408f1a4b3f..78d3a9dd8355436b 100644
--- a/sysdeps/unix/sysv/linux/rseq-sym.c
+++ b/sysdeps/unix/sysv/linux/rseq-sym.c
@@ -19,8 +19,11 @@
 #include <stdint.h>
 #include <kernel-features.h>
 #include <sys/rseq.h>
+#include <rseq-internal.h>
 
 __thread struct rseq __rseq_abi =
   {
     .cpu_id = RSEQ_CPU_ID_UNINITIALIZED,
   };
+
+_Bool __rseq_active __attribute__ ((nocommon));
diff --git a/sysdeps/unix/sysv/linux/tst-rseq-nptl.c b/sysdeps/unix/sysv/linux/tst-rseq-nptl.c
index 5e788dcfa9eef8ef..ed846e9f5d5a5f4e 100644
--- a/sysdeps/unix/sysv/linux/tst-rseq-nptl.c
+++ b/sysdeps/unix/sysv/linux/tst-rseq-nptl.c
@@ -250,6 +250,10 @@ do_rseq_test (void)
 static int
 do_test (void)
 {
+  extern _Bool __rseq_active;
+  if (!__rseq_active)
+    FAIL_UNSUPPORTED ("/etc/glibc.rseq.enabled missing, test disabled");
+
   return do_rseq_test ();
 }
 
diff --git a/sysdeps/unix/sysv/linux/tst-rseq.c b/sysdeps/unix/sysv/linux/tst-rseq.c
index aa902fb26a64f917..60eaab4bc13d1275 100644
--- a/sysdeps/unix/sysv/linux/tst-rseq.c
+++ b/sysdeps/unix/sysv/linux/tst-rseq.c
@@ -57,6 +57,10 @@ do_rseq_test (void)
 static int
 do_test (void)
 {
+  extern _Bool __rseq_active;
+  if (!__rseq_active)
+    FAIL_UNSUPPORTED ("/etc/glibc.rseq.enabled missing, test disabled");
+
   do_rseq_test ();
   return 0;
 }