All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86/fpu: verify xstate buffer size according with requested features
@ 2024-01-17 19:31 Dave Hansen
  2024-01-17 19:34 ` Dave Hansen
  0 siblings, 1 reply; 14+ messages in thread
From: Dave Hansen @ 2024-01-17 19:31 UTC (permalink / raw)
  To: patches, Dave Hansen

From: Andrei Vagin <avagin@google.com>

Users must provide buffers that fit states of all requested features.
Otherwise, the kernel can be stuck in an endless loop:
 * xrstor faults outside of the provided buffer.
 * fault_in_readable scans the buffer and restarts the first step
   because the entire buffer is present in memory.

Fixes: fcb3635f5018 ("x86/fpu/signal: Handle #PF in the direct restore path")
Signed-off-by: Andrei Vagin <avagin@google.com>
---
 arch/x86/kernel/fpu/signal.c | 23 +++++++++++++++++------
 arch/x86/kernel/fpu/xstate.c |  2 +-
 arch/x86/kernel/fpu/xstate.h |  2 ++
 3 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index 558076dbde5b..fea02fe7f712 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -27,28 +27,39 @@
 static inline bool check_xstate_in_sigframe(struct fxregs_state __user *fxbuf,
 					    struct _fpx_sw_bytes *fx_sw)
 {
-	int min_xstate_size = sizeof(struct fxregs_state) +
-			      sizeof(struct xstate_header);
-	void __user *fpstate = fxbuf;
+	struct fpstate *fpstate = current->thread.fpu.fpstate;
+	void __user *buf = fxbuf;
 	unsigned int magic2;
 
 	if (__copy_from_user(fx_sw, &fxbuf->sw_reserved[0], sizeof(*fx_sw)))
 		return false;
 
+	/* Restore enabled features only. */
+	fx_sw->xfeatures &= fpstate->user_xfeatures;
+
 	/* Check for the first magic field and other error scenarios. */
 	if (fx_sw->magic1 != FP_XSTATE_MAGIC1 ||
-	    fx_sw->xstate_size < min_xstate_size ||
-	    fx_sw->xstate_size > current->thread.fpu.fpstate->user_size ||
 	    fx_sw->xstate_size > fx_sw->extended_size)
 		goto setfx;
 
+	/* xstate_size has to fit all requested components. */
+	if (fx_sw->xstate_size != fpstate->user_size) {
+		int min_xstate_size =
+			xstate_calculate_size(fx_sw->xfeatures, false);
+
+		if (min_xstate_size < 0 ||
+		    fx_sw->xstate_size < min_xstate_size ||
+		    fx_sw->xstate_size > fpstate->user_size)
+			goto setfx;
+	}
+
 	/*
 	 * Check for the presence of second magic word at the end of memory
 	 * layout. This detects the case where the user just copied the legacy
 	 * fpstate layout with out copying the extended state information
 	 * in the memory layout.
 	 */
-	if (__get_user(magic2, (__u32 __user *)(fpstate + fx_sw->xstate_size)))
+	if (__get_user(magic2, (__u32 __user *)(buf + fx_sw->xstate_size)))
 		return false;
 
 	if (likely(magic2 == FP_XSTATE_MAGIC2))
diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index 117e74c44e75..35a1ccbba55d 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -556,7 +556,7 @@ static bool __init check_xstate_against_struct(int nr)
 	return true;
 }
 
-static unsigned int xstate_calculate_size(u64 xfeatures, bool compacted)
+unsigned int xstate_calculate_size(u64 xfeatures, bool compacted)
 {
 	unsigned int topmost = fls64(xfeatures) -  1;
 	unsigned int offset = xstate_offsets[topmost];
diff --git a/arch/x86/kernel/fpu/xstate.h b/arch/x86/kernel/fpu/xstate.h
index 3518fb26d06b..93ed710e76ac 100644
--- a/arch/x86/kernel/fpu/xstate.h
+++ b/arch/x86/kernel/fpu/xstate.h
@@ -69,6 +69,8 @@ static inline u64 xfeatures_mask_independent(void)
 	return XFEATURE_MASK_INDEPENDENT;
 }
 
+unsigned int xstate_calculate_size(u64 xfeatures, bool compacted);
+
 /* XSAVE/XRSTOR wrapper functions */
 
 #ifdef CONFIG_X86_64
-- 
2.43.0.429.g432eaa2c6b-goog


^ permalink raw reply related	[flat|nested] 14+ messages in thread
* [PATCH] x86/fpu: verify xstate buffer size according with requested features
@ 2024-01-17 18:55 Dave Hansen
  0 siblings, 0 replies; 14+ messages in thread
From: Dave Hansen @ 2024-01-17 18:55 UTC (permalink / raw)
  To: patches



^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2024-01-22 13:26 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-01-17 19:31 [PATCH] x86/fpu: verify xstate buffer size according with requested features Dave Hansen
2024-01-17 19:34 ` Dave Hansen
2024-01-17 22:30   ` Andrei Vagin
2024-01-17 23:52     ` Dave Hansen
2024-01-18  7:59       ` Andrei Vagin
2024-01-18 18:27         ` Dave Hansen
2024-01-18 19:54           ` Thomas Gleixner
2024-01-18 22:02             ` Dave Hansen
2024-01-18 22:11               ` Thomas Gleixner
2024-01-22  3:58                 ` Andrei Vagin
2024-01-22 13:26                   ` Thomas Gleixner
2024-01-18 19:07         ` Thomas Gleixner
2024-01-22  6:43           ` Andrei Vagin
  -- strict thread matches above, loose matches on Subject: below --
2024-01-17 18:55 Dave Hansen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.