* [PATCH v2 1/4] pkeys: add API to switch to permissive pkey register
[not found] <cover.1739864467.git.dvyukov@google.com>
@ 2025-02-18 7:43 ` Dmitry Vyukov
2025-02-21 14:10 ` Ingo Molnar
2025-02-18 7:43 ` [PATCH v2 2/4] x86/signal: Use switch_to_permissive_pkey_reg() helper Dmitry Vyukov
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Dmitry Vyukov @ 2025-02-18 7:43 UTC (permalink / raw)
To: mathieu.desnoyers, peterz, boqun.feng, tglx, mingo, bp,
dave.hansen, hpa, aruna.ramakrishna, elver
Cc: Dmitry Vyukov, Paul E. McKenney, x86, linux-kernel
The API allows to switch to permissive pkey register that allows accesses
to all PKEYs. This functionality is already used in x86 signal delivery,
and will be needed for rseq.
Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Aruna Ramakrishna <aruna.ramakrishna@oracle.com>
Cc: x86@kernel.org
Cc: linux-kernel@vger.kernel.org
---
Changes in v2:
- Fixed typo in commit description
---
arch/x86/Kconfig | 1 +
arch/x86/include/asm/pkeys.h | 14 ++++++++++++++
arch/x86/include/asm/pkru.h | 10 +++++++---
include/linux/pkeys.h | 22 ++++++++++++++++++++++
mm/Kconfig | 2 ++
5 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index be2c311f5118d..43af2840d098f 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1881,6 +1881,7 @@ config X86_INTEL_MEMORY_PROTECTION_KEYS
depends on X86_64 && (CPU_SUP_INTEL || CPU_SUP_AMD)
select ARCH_USES_HIGH_VMA_FLAGS
select ARCH_HAS_PKEYS
+ select ARCH_HAS_PERMISSIVE_PKEY
help
Memory Protection Keys provides a mechanism for enforcing
page-based protections, but without requiring modification of the
diff --git a/arch/x86/include/asm/pkeys.h b/arch/x86/include/asm/pkeys.h
index 2e6c04d8a45b4..1cacfe184b9d4 100644
--- a/arch/x86/include/asm/pkeys.h
+++ b/arch/x86/include/asm/pkeys.h
@@ -2,6 +2,8 @@
#ifndef _ASM_X86_PKEYS_H
#define _ASM_X86_PKEYS_H
+#include "pkru.h"
+
/*
* If more than 16 keys are ever supported, a thorough audit
* will be necessary to ensure that the types that store key
@@ -123,4 +125,16 @@ static inline int vma_pkey(struct vm_area_struct *vma)
return (vma->vm_flags & vma_pkey_mask) >> VM_PKEY_SHIFT;
}
+typedef u32 pkey_reg_t;
+
+static inline pkey_reg_t switch_to_permissive_pkey_reg(void)
+{
+ return write_pkru(0);
+}
+
+static inline void write_pkey_reg(pkey_reg_t val)
+{
+ write_pkru(val);
+}
+
#endif /*_ASM_X86_PKEYS_H */
diff --git a/arch/x86/include/asm/pkru.h b/arch/x86/include/asm/pkru.h
index 74f0a2d34ffdd..b9bf9b7f2753b 100644
--- a/arch/x86/include/asm/pkru.h
+++ b/arch/x86/include/asm/pkru.h
@@ -39,16 +39,20 @@ static inline u32 read_pkru(void)
return 0;
}
-static inline void write_pkru(u32 pkru)
+static inline u32 write_pkru(u32 pkru)
{
+ u32 old_pkru;
+
if (!cpu_feature_enabled(X86_FEATURE_OSPKE))
- return;
+ return 0;
/*
* WRPKRU is relatively expensive compared to RDPKRU.
* Avoid WRPKRU when it would not change the value.
*/
- if (pkru != rdpkru())
+ old_pkru = rdpkru();
+ if (pkru != old_pkru)
wrpkru(pkru);
+ return old_pkru;
}
static inline void pkru_write_default(void)
diff --git a/include/linux/pkeys.h b/include/linux/pkeys.h
index 86be8bf27b41b..d94a0ae7a784b 100644
--- a/include/linux/pkeys.h
+++ b/include/linux/pkeys.h
@@ -48,4 +48,26 @@ static inline bool arch_pkeys_enabled(void)
#endif /* ! CONFIG_ARCH_HAS_PKEYS */
+#ifndef CONFIG_ARCH_HAS_PERMISSIVE_PKEY
+
+/*
+ * Common name for value of the register that controls access to PKEYs
+ * (called differently on different arches: PKRU, POR, AMR).
+ */
+typedef int pkey_reg_t;
+
+/*
+ * Sets PKEY access register to the most permissive value that allows
+ * accesses to all PKEYs. Returns the current value of PKEY register.
+ * Code should generally arrange switching back to the old value
+ * using write_pkey_reg(old_value).
+ */
+static inline pkey_reg_t switch_to_permissive_pkey_reg(void)
+{
+ return 0;
+}
+
+static inline void write_pkey_reg(pkey_reg_t val) {}
+#endif /* ! CONFIG_ARCH_HAS_PERMISSIVE_PKEY */
+
#endif /* _LINUX_PKEYS_H */
diff --git a/mm/Kconfig b/mm/Kconfig
index 1b501db064172..9e874f7713a2b 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -1147,6 +1147,8 @@ config ARCH_USES_HIGH_VMA_FLAGS
bool
config ARCH_HAS_PKEYS
bool
+config ARCH_HAS_PERMISSIVE_PKEY
+ bool
config ARCH_USES_PG_ARCH_2
bool
--
2.48.1.601.g30ceb7b040-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH v2 1/4] pkeys: add API to switch to permissive pkey register
2025-02-18 7:43 ` [PATCH v2 1/4] pkeys: add API to switch to permissive pkey register Dmitry Vyukov
@ 2025-02-21 14:10 ` Ingo Molnar
2025-02-24 13:13 ` Dmitry Vyukov
0 siblings, 1 reply; 6+ messages in thread
From: Ingo Molnar @ 2025-02-21 14:10 UTC (permalink / raw)
To: Dmitry Vyukov
Cc: mathieu.desnoyers, peterz, boqun.feng, tglx, mingo, bp,
dave.hansen, hpa, aruna.ramakrishna, elver, Paul E. McKenney, x86,
linux-kernel
* Dmitry Vyukov <dvyukov@google.com> wrote:
> The API allows to switch to permissive pkey register that allows accesses
> to all PKEYs. This functionality is already used in x86 signal delivery,
> and will be needed for rseq.
>
> Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: "Paul E. McKenney" <paulmck@kernel.org>
> Cc: Boqun Feng <boqun.feng@gmail.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: Aruna Ramakrishna <aruna.ramakrishna@oracle.com>
> Cc: x86@kernel.org
> Cc: linux-kernel@vger.kernel.org
So why did not add the Reviewed-by tag by Mathieu, while you
incorporated his review feedback:
> Changes in v2:
> - Fixed typo in commit description
?
Thanks,
Ingo
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/4] pkeys: add API to switch to permissive pkey register
2025-02-21 14:10 ` Ingo Molnar
@ 2025-02-24 13:13 ` Dmitry Vyukov
0 siblings, 0 replies; 6+ messages in thread
From: Dmitry Vyukov @ 2025-02-24 13:13 UTC (permalink / raw)
To: Ingo Molnar
Cc: mathieu.desnoyers, peterz, boqun.feng, tglx, mingo, bp,
dave.hansen, hpa, aruna.ramakrishna, elver, Paul E. McKenney, x86,
linux-kernel
On Fri, 21 Feb 2025 at 15:10, Ingo Molnar <mingo@kernel.org> wrote:
>
>
> * Dmitry Vyukov <dvyukov@google.com> wrote:
>
> > The API allows to switch to permissive pkey register that allows accesses
> > to all PKEYs. This functionality is already used in x86 signal delivery,
> > and will be needed for rseq.
> >
> > Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
> > Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> > Cc: Peter Zijlstra <peterz@infradead.org>
> > Cc: "Paul E. McKenney" <paulmck@kernel.org>
> > Cc: Boqun Feng <boqun.feng@gmail.com>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: Ingo Molnar <mingo@redhat.com>
> > Cc: Borislav Petkov <bp@alien8.de>
> > Cc: Dave Hansen <dave.hansen@linux.intel.com>
> > Cc: "H. Peter Anvin" <hpa@zytor.com>
> > Cc: Aruna Ramakrishna <aruna.ramakrishna@oracle.com>
> > Cc: x86@kernel.org
> > Cc: linux-kernel@vger.kernel.org
>
> So why did not add the Reviewed-by tag by Mathieu, while you
> incorporated his review feedback:
>
> > Changes in v2:
> > - Fixed typo in commit description
>
> ?
Done in v3.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 2/4] x86/signal: Use switch_to_permissive_pkey_reg() helper
[not found] <cover.1739864467.git.dvyukov@google.com>
2025-02-18 7:43 ` [PATCH v2 1/4] pkeys: add API to switch to permissive pkey register Dmitry Vyukov
@ 2025-02-18 7:43 ` Dmitry Vyukov
2025-02-18 7:43 ` [PATCH v2 3/4] rseq: Make rseq work with protection keys Dmitry Vyukov
2025-02-18 7:43 ` [PATCH v2 4/4] selftests/rseq: Add test for rseq+pkeys Dmitry Vyukov
3 siblings, 0 replies; 6+ messages in thread
From: Dmitry Vyukov @ 2025-02-18 7:43 UTC (permalink / raw)
To: mathieu.desnoyers, peterz, boqun.feng, tglx, mingo, bp,
dave.hansen, hpa, aruna.ramakrishna, elver
Cc: Dmitry Vyukov, Paul E. McKenney, x86, linux-kernel
Use the new switch_to_permissive_pkey_reg() helper instead of the
custom code. No functional changes intended.
Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Aruna Ramakrishna <aruna.ramakrishna@oracle.com>
Cc: x86@kernel.org
Cc: linux-kernel@vger.kernel.org
---
arch/x86/kernel/signal.c | 33 +++++++++++++--------------------
1 file changed, 13 insertions(+), 20 deletions(-)
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 5f441039b5725..b753de278257a 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -28,6 +28,7 @@
#include <linux/entry-common.h>
#include <linux/syscalls.h>
#include <linux/rseq.h>
+#include <linux/pkeys.h>
#include <asm/processor.h>
#include <asm/ucontext.h>
@@ -60,24 +61,6 @@ static inline int is_x32_frame(struct ksignal *ksig)
ksig->ka.sa.sa_flags & SA_X32_ABI;
}
-/*
- * Enable all pkeys temporarily, so as to ensure that both the current
- * execution stack as well as the alternate signal stack are writeable.
- * The application can use any of the available pkeys to protect the
- * alternate signal stack, and we don't know which one it is, so enable
- * all. The PKRU register will be reset to init_pkru later in the flow,
- * in fpu__clear_user_states(), and it is the application's responsibility
- * to enable the appropriate pkey as the first step in the signal handler
- * so that the handler does not segfault.
- */
-static inline u32 sig_prepare_pkru(void)
-{
- u32 orig_pkru = read_pkru();
-
- write_pkru(0);
- return orig_pkru;
-}
-
/*
* Set up a signal frame.
*/
@@ -157,8 +140,18 @@ get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size,
return (void __user *)-1L;
}
- /* Update PKRU to enable access to the alternate signal stack. */
- pkru = sig_prepare_pkru();
+ /*
+ * Enable all pkeys temporarily, so as to ensure that both the current
+ * execution stack as well as the alternate signal stack are
+ * writeable. The application can use any of the available pkeys to
+ * protect the alternate signal stack, and we don't know which one it
+ * is, so enable all. The PKRU register will be reset to init_pkru
+ * later in the flow, in fpu__clear_user_states(), and it is the
+ * application's responsibility to enable the appropriate pkey as the
+ * first step in the signal handler so that the handler does not
+ * segfault.
+ */
+ pkru = switch_to_permissive_pkey_reg();
/* save i387 and extended state */
if (!copy_fpstate_to_sigframe(*fpstate, (void __user *)buf_fx, math_size, pkru)) {
/*
--
2.48.1.601.g30ceb7b040-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v2 3/4] rseq: Make rseq work with protection keys
[not found] <cover.1739864467.git.dvyukov@google.com>
2025-02-18 7:43 ` [PATCH v2 1/4] pkeys: add API to switch to permissive pkey register Dmitry Vyukov
2025-02-18 7:43 ` [PATCH v2 2/4] x86/signal: Use switch_to_permissive_pkey_reg() helper Dmitry Vyukov
@ 2025-02-18 7:43 ` Dmitry Vyukov
2025-02-18 7:43 ` [PATCH v2 4/4] selftests/rseq: Add test for rseq+pkeys Dmitry Vyukov
3 siblings, 0 replies; 6+ messages in thread
From: Dmitry Vyukov @ 2025-02-18 7:43 UTC (permalink / raw)
To: mathieu.desnoyers, peterz, boqun.feng, tglx, mingo, bp,
dave.hansen, hpa, aruna.ramakrishna, elver
Cc: Dmitry Vyukov, Paul E. McKenney, x86, linux-kernel
If an application registers rseq, and ever switches to another pkey
protection (such that the rseq becomes inaccessible), then any
context switch will cause failure in __rseq_handle_notify_resume()
attempting to read/write struct rseq and/or rseq_cs. Since context
switches are asynchronous and are outside of the application control
(not part of the restricted code scope), temporarily switch to
permissive pkey register to read/write rseq/rseq_cs, similarly
to signal delivery accesses to altstack.
Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Aruna Ramakrishna <aruna.ramakrishna@oracle.com>
Cc: x86@kernel.org
Cc: linux-kernel@vger.kernel.org
---
Changes in v2:
- fixed typos and reworded the comment
---
kernel/rseq.c | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/kernel/rseq.c b/kernel/rseq.c
index 442aba29bc4cf..6fc9f799720cd 100644
--- a/kernel/rseq.c
+++ b/kernel/rseq.c
@@ -10,6 +10,7 @@
#include <linux/sched.h>
#include <linux/uaccess.h>
+#include <linux/pkeys.h>
#include <linux/syscalls.h>
#include <linux/rseq.h>
#include <linux/types.h>
@@ -403,10 +404,13 @@ void __rseq_handle_notify_resume(struct ksignal *ksig, struct pt_regs *regs)
{
struct task_struct *t = current;
int ret, sig;
+ pkey_reg_t saved;
+ bool switched_pkey_reg = false;
if (unlikely(t->flags & PF_EXITING))
return;
+retry:
/*
* regs is NULL if and only if the caller is in a syscall path. Skip
* fixup and leave rseq_cs as is so that rseq_sycall() will detect and
@@ -419,9 +423,43 @@ void __rseq_handle_notify_resume(struct ksignal *ksig, struct pt_regs *regs)
}
if (unlikely(rseq_update_cpu_node_id(t)))
goto error;
+ if (switched_pkey_reg)
+ write_pkey_reg(saved);
return;
error:
+ /*
+ * If the application registers rseq, and ever switches to another
+ * pkey protection (such that the rseq becomes inaccessible), then
+ * any context switch will cause failure here attempting to read/write
+ * struct rseq and/or rseq_cs. Since context switches are
+ * asynchronous and are outside of the application control
+ * (not part of the restricted code scope), temporarily switch
+ * to permissive pkey register to read/write rseq/rseq_cs,
+ * similarly to signal delivery accesses to altstack.
+ *
+ * Don't bother to check if the failure really happened due to
+ * pkeys or not, since it does not matter (performance-wise and
+ * otherwise).
+ *
+ * Note that if code has write access to struct rseq, it may install
+ * rseq_cs that is not accessible to it due to pkeys. Still let this
+ * function read such rseq_cs on behalf of the code circumventing
+ * pkeys protection. It's unclear what benefits the restricted code
+ * gets by doing this (it presumably has already hijacked control
+ * flow at this point, or has arbitrary write primitive to write
+ * arbitrary values to struct rseq). A sane sandbox should prohibit
+ * restricted code from accessing struct rseq. Disabling pkeys
+ * protection is still better than terminating the app
+ * unconditionally.
+ */
+ if (!switched_pkey_reg) {
+ switched_pkey_reg = true;
+ saved = switch_to_permissive_pkey_reg();
+ goto retry;
+ } else {
+ write_pkey_reg(saved);
+ }
sig = ksig ? ksig->sig : 0;
force_sigsegv(sig);
}
--
2.48.1.601.g30ceb7b040-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v2 4/4] selftests/rseq: Add test for rseq+pkeys
[not found] <cover.1739864467.git.dvyukov@google.com>
` (2 preceding siblings ...)
2025-02-18 7:43 ` [PATCH v2 3/4] rseq: Make rseq work with protection keys Dmitry Vyukov
@ 2025-02-18 7:43 ` Dmitry Vyukov
3 siblings, 0 replies; 6+ messages in thread
From: Dmitry Vyukov @ 2025-02-18 7:43 UTC (permalink / raw)
To: mathieu.desnoyers, peterz, boqun.feng, tglx, mingo, bp,
dave.hansen, hpa, aruna.ramakrishna, elver
Cc: Dmitry Vyukov, Paul E. McKenney, x86, linux-kernel
Add a test that ensures that PKEY-protected struct rseq_cs
works and does not lead to process kills.
Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Aruna Ramakrishna <aruna.ramakrishna@oracle.com>
Cc: x86@kernel.org
Cc: linux-kernel@vger.kernel.org
---
Changes in v2:
- change test to install protected rseq_cs instead of rseq
---
tools/testing/selftests/rseq/Makefile | 2 +-
tools/testing/selftests/rseq/pkey_test.c | 66 ++++++++++++++++++++++++
tools/testing/selftests/rseq/rseq.h | 1 +
3 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/rseq/Makefile b/tools/testing/selftests/rseq/Makefile
index 5a3432fceb586..9111d25fea3af 100644
--- a/tools/testing/selftests/rseq/Makefile
+++ b/tools/testing/selftests/rseq/Makefile
@@ -16,7 +16,7 @@ OVERRIDE_TARGETS = 1
TEST_GEN_PROGS = basic_test basic_percpu_ops_test basic_percpu_ops_mm_cid_test param_test \
param_test_benchmark param_test_compare_twice param_test_mm_cid \
- param_test_mm_cid_benchmark param_test_mm_cid_compare_twice
+ param_test_mm_cid_benchmark param_test_mm_cid_compare_twice pkey_test
TEST_GEN_PROGS_EXTENDED = librseq.so
diff --git a/tools/testing/selftests/rseq/pkey_test.c b/tools/testing/selftests/rseq/pkey_test.c
new file mode 100644
index 0000000000000..0bca8fda9aa92
--- /dev/null
+++ b/tools/testing/selftests/rseq/pkey_test.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: LGPL-2.1
+/*
+ * Ensure that rseq works when rseq data is protected with PKEYs.
+ */
+
+#define _GNU_SOURCE
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include "rseq.h"
+#include "rseq-abi.h"
+
+int main(int argc, char **argv)
+{
+ struct rseq_abi_cs *cs;
+ __u32 *sig;
+ unsigned long page_size;
+ int pkey, i;
+
+ pkey = pkey_alloc(0, 0);
+ if (pkey == -1) {
+ printf("[SKIP]\tKernel does not support PKEYs: %s\n",
+ strerror(errno));
+ return 0;
+ }
+
+ if (rseq_register_current_thread())
+ err(1, "rseq_register_current_thread failed");
+
+ page_size = getpagesize();
+ cs = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE, -1, 0);
+ if (cs == MAP_FAILED)
+ err(1, "mmap failed");
+ /* Create valid rseq_cs. */
+ sig = (__u32 *)(cs + 1);
+ *sig = RSEQ_SIG;
+ cs->abort_ip = (__u64)(sig + 1);
+ if (pkey_mprotect(cs, page_size, PROT_READ | PROT_WRITE, pkey))
+ err(1, "pkey_mprotect failed");
+ if (pkey_set(pkey, PKEY_DISABLE_ACCESS))
+ err(1, "pkey_set failed");
+
+ /* Install pkey-protected rseq_cs. */
+ rseq_get_abi()->rseq_cs.ptr64 = (__u64)cs;
+
+ /*
+ * If the kernel misbehaves, context switches in the following loop
+ * will terminate the process with SIGSEGV.
+ */
+ for (i = 0; i < 10; i++)
+ usleep(100);
+
+ /*
+ * Ensure that the kernel has restored the previous value of pkeys
+ * register after changing it.
+ */
+ if (pkey_get(pkey) != PKEY_DISABLE_ACCESS)
+ errx(1, "pkey protection has changed");
+ return 0;
+}
diff --git a/tools/testing/selftests/rseq/rseq.h b/tools/testing/selftests/rseq/rseq.h
index ba424ce80a719..65da4a727c550 100644
--- a/tools/testing/selftests/rseq/rseq.h
+++ b/tools/testing/selftests/rseq/rseq.h
@@ -8,6 +8,7 @@
#ifndef RSEQ_H
#define RSEQ_H
+#include <assert.h>
#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>
--
2.48.1.601.g30ceb7b040-goog
^ permalink raw reply related [flat|nested] 6+ messages in thread