[<prev] [next>] [day] [month] [year] [list]
Message-ID: <ac4d535eb0c14008d2e1287f4610a10a77d2dffc.1740402517.git.dvyukov@google.com>
Date: Mon, 24 Feb 2025 14:12:30 +0100
From: Dmitry Vyukov <dvyukov@...gle.com>
To: mathieu.desnoyers@...icios.com, peterz@...radead.org, boqun.feng@...il.com,
tglx@...utronix.de, mingo@...hat.com, bp@...en8.de,
dave.hansen@...ux.intel.com, hpa@...or.com, aruna.ramakrishna@...cle.com,
elver@...gle.com
Cc: Dmitry Vyukov <dvyukov@...gle.com>, "Paul E. McKenney" <paulmck@...nel.org>, x86@...nel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH v3 3/4] rseq: Make rseq work with protection keys
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
pkey value that allows access to the 0 (default) PKEY.
Signed-off-by: Dmitry Vyukov <dvyukov@...gle.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@...icios.com>
Cc: Peter Zijlstra <peterz@...radead.org>
Cc: "Paul E. McKenney" <paulmck@...nel.org>
Cc: Boqun Feng <boqun.feng@...il.com>
Cc: Thomas Gleixner <tglx@...utronix.de>
Cc: Ingo Molnar <mingo@...hat.com>
Cc: Borislav Petkov <bp@...en8.de>
Cc: Dave Hansen <dave.hansen@...ux.intel.com>
Cc: "H. Peter Anvin" <hpa@...or.com>
Cc: Aruna Ramakrishna <aruna.ramakrishna@...cle.com>
Cc: x86@...nel.org
Cc: linux-kernel@...r.kernel.org
---
Changes in v3:
- simplify control flow to always enable access to 0 pkey
Changes in v2:
- fixed typos and reworded the comment
---
kernel/rseq.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/kernel/rseq.c b/kernel/rseq.c
index 2cb16091ec0ae..9d9c976d3b78c 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>
@@ -402,11 +403,19 @@ static int rseq_ip_fixup(struct pt_regs *regs)
void __rseq_handle_notify_resume(struct ksignal *ksig, struct pt_regs *regs)
{
struct task_struct *t = current;
+ pkey_reg_t saved_pkey;
int ret, sig;
if (unlikely(t->flags & PF_EXITING))
return;
+ /*
+ * Enable access to the default (0) pkey in case the thread has
+ * currently disabled access to it and struct rseq/rseq_cs has
+ * 0 pkey assigned (the only supported value for now).
+ */
+ saved_pkey = enable_zero_pkey_val();
+
/*
* 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 +428,11 @@ void __rseq_handle_notify_resume(struct ksignal *ksig, struct pt_regs *regs)
}
if (unlikely(rseq_update_cpu_node_id(t)))
goto error;
+ write_pkey_val(saved_pkey);
return;
error:
+ write_pkey_val(saved_pkey);
sig = ksig ? ksig->sig : 0;
force_sigsegv(sig);
}
--
2.48.1.601.g30ceb7b040-goog
Powered by blists - more mailing lists