From: "tip-bot2 for Aruna Ramakrishna" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: Aruna Ramakrishna <aruna.ramakrishna@oracle.com>,
Thomas Gleixner <tglx@linutronix.de>,
x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [tip: x86/mm] x86/pkeys: Add PKRU as a parameter in signal handling functions
Date: Fri, 02 Aug 2024 13:01:12 -0000 [thread overview]
Message-ID: <172260367260.2215.4188177993426167724.tip-bot2@tip-bot2> (raw)
In-Reply-To: <20240802061318.2140081-2-aruna.ramakrishna@oracle.com>
The following commit has been merged into the x86/mm branch of tip:
Commit-ID: 24cf2bc982ffe02aeffb4a3885c71751a2c7023b
Gitweb: https://git.kernel.org/tip/24cf2bc982ffe02aeffb4a3885c71751a2c7023b
Author: Aruna Ramakrishna <aruna.ramakrishna@oracle.com>
AuthorDate: Fri, 02 Aug 2024 06:13:14
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 02 Aug 2024 14:12:20 +02:00
x86/pkeys: Add PKRU as a parameter in signal handling functions
Assume there's a multithreaded application that runs untrusted user
code. Each thread has its stack/code protected by a non-zero PKEY, and the
PKRU register is set up such that only that particular non-zero PKEY is
enabled. Each thread also sets up an alternate signal stack to handle
signals, which is protected by PKEY zero. The PKEYs man page documents that
the PKRU will be reset to init_pkru when the signal handler is invoked,
which means that PKEY zero access will be enabled. But this reset happens
after the kernel attempts to push fpu state to the alternate stack, which
is not (yet) accessible by the kernel, which leads to a new SIGSEGV being
sent to the application, terminating it.
Enabling both the non-zero PKEY (for the thread) and PKEY zero in
userspace will not work for this use case. It cannot have the alt stack
writeable by all - the rationale here is that the code running in that
thread (using a non-zero PKEY) is untrusted and should not have access
to the alternate signal stack (that uses PKEY zero), to prevent the
return address of a function from being changed. The expectation is that
kernel should be able to set up the alternate signal stack and deliver
the signal to the application even if PKEY zero is explicitly disabled
by the application. The signal handler accessibility should not be
dictated by whatever PKRU value the thread sets up.
The PKRU register is managed by XSAVE, which means the sigframe contents
must match the register contents - which is not the case here. It's
required that the signal frame contains the user-defined PKRU value (so
that it is restored correctly from sigcontext) but the actual register must
be reset to init_pkru so that the alt stack is accessible and the signal
can be delivered to the application. It seems that the proper fix here
would be to remove PKRU from the XSAVE framework and manage it separately,
which is quite complicated. As a workaround, do this:
orig_pkru = rdpkru();
wrpkru(orig_pkru & init_pkru_value);
xsave_to_user_sigframe();
put_user(pkru_sigframe_addr, orig_pkru)
In preparation for writing PKRU to sigframe, pass PKRU as an additional
parameter down the call chain from get_sigframe().
No functional change.
Signed-off-by: Aruna Ramakrishna <aruna.ramakrishna@oracle.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20240802061318.2140081-2-aruna.ramakrishna@oracle.com
---
arch/x86/include/asm/fpu/signal.h | 2 +-
arch/x86/kernel/fpu/signal.c | 6 +++---
arch/x86/kernel/signal.c | 3 ++-
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/arch/x86/include/asm/fpu/signal.h b/arch/x86/include/asm/fpu/signal.h
index 611fa41..eccc75b 100644
--- a/arch/x86/include/asm/fpu/signal.h
+++ b/arch/x86/include/asm/fpu/signal.h
@@ -29,7 +29,7 @@ fpu__alloc_mathframe(unsigned long sp, int ia32_frame,
unsigned long fpu__get_fpstate_size(void);
-extern bool copy_fpstate_to_sigframe(void __user *buf, void __user *fp, int size);
+extern bool copy_fpstate_to_sigframe(void __user *buf, void __user *fp, int size, u32 pkru);
extern void fpu__clear_user_states(struct fpu *fpu);
extern bool fpu__restore_sig(void __user *buf, int ia32_frame);
diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index 247f222..2b3b9e1 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -156,7 +156,7 @@ static inline bool save_xstate_epilog(void __user *buf, int ia32_frame,
return !err;
}
-static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf)
+static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf, u32 pkru)
{
if (use_xsave())
return xsave_to_user_sigframe(buf);
@@ -185,7 +185,7 @@ static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf)
* For [f]xsave state, update the SW reserved fields in the [f]xsave frame
* indicating the absence/presence of the extended state to the user.
*/
-bool copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
+bool copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size, u32 pkru)
{
struct task_struct *tsk = current;
struct fpstate *fpstate = tsk->thread.fpu.fpstate;
@@ -228,7 +228,7 @@ retry:
fpregs_restore_userregs();
pagefault_disable();
- ret = copy_fpregs_to_sigframe(buf_fx);
+ ret = copy_fpregs_to_sigframe(buf_fx, pkru);
pagefault_enable();
fpregs_unlock();
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 31b6f5d..1f1e8e0 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -84,6 +84,7 @@ get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size,
unsigned long math_size = 0;
unsigned long sp = regs->sp;
unsigned long buf_fx = 0;
+ u32 pkru = read_pkru();
/* redzone */
if (!ia32_frame)
@@ -139,7 +140,7 @@ get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size,
}
/* save i387 and extended state */
- if (!copy_fpstate_to_sigframe(*fpstate, (void __user *)buf_fx, math_size))
+ if (!copy_fpstate_to_sigframe(*fpstate, (void __user *)buf_fx, math_size, pkru))
return (void __user *)-1L;
return (void __user *)sp;
next prev parent reply other threads:[~2024-08-02 13:01 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-02 6:13 [PATCH v8 0/5] x86/pkeys: update PKRU to enable all pkeys before XSAVE Aruna Ramakrishna
2024-08-02 6:13 ` [PATCH v8 1/5] x86/pkeys: Add PKRU as a parameter in signal handling functions Aruna Ramakrishna
2024-08-02 13:01 ` tip-bot2 for Aruna Ramakrishna [this message]
2024-08-09 17:16 ` Jeff Xu
2024-08-02 6:13 ` [PATCH v8 2/5] x86/pkeys: Add helper functions to update PKRU on the sigframe Aruna Ramakrishna
2024-08-02 13:01 ` [tip: x86/mm] " tip-bot2 for Aruna Ramakrishna
2024-08-02 6:13 ` [PATCH v8 3/5] x86/pkeys: Update PKRU to enable all pkeys before XSAVE Aruna Ramakrishna
2024-08-02 13:01 ` [tip: x86/mm] " tip-bot2 for Aruna Ramakrishna
2024-08-09 17:30 ` [PATCH v8 3/5] " Jeff Xu
2024-08-27 0:53 ` Jeff Xu
2024-10-03 23:29 ` Aruna Ramakrishna
2024-10-04 4:20 ` Jeff Xu
2025-02-04 10:01 ` Dmitry Vyukov
2025-02-06 18:06 ` Dmitry Vyukov
2025-02-10 22:46 ` Jeff Xu
2025-02-11 6:47 ` Dmitry Vyukov
2025-02-06 18:21 ` Dave Hansen
2025-02-06 18:35 ` Dmitry Vyukov
2024-08-02 6:13 ` [PATCH v8 4/5] x86/pkeys: Restore altstack access in sigreturn() Aruna Ramakrishna
2024-08-02 13:01 ` [tip: x86/mm] " tip-bot2 for Aruna Ramakrishna
2024-08-02 6:13 ` [PATCH v8 5/5] selftests/mm: Add new testcases for pkeys Aruna Ramakrishna
2024-08-02 8:16 ` Thomas Gleixner
2024-08-02 8:22 ` Thomas Gleixner
2024-08-02 12:04 ` Thomas Gleixner
2024-08-02 13:01 ` [tip: x86/mm] " tip-bot2 for Keith Lucas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=172260367260.2215.4188177993426167724.tip-bot2@tip-bot2 \
--to=tip-bot2@linutronix.de \
--cc=aruna.ramakrishna@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®