[PATCH 09/10] x86/fpu: Allow restoring signal frames with larger xstate_size
From: Andrei Vagin
Date: Mon Jun 15 2026 - 15:41:44 EST
The kernel previously enforced that the xstate_size in the signal frame
must not exceed the current task's fpstate->user_size. This prevents
restoring signal frames that were saved on another CPU (in case of
container/process migration) with a different (larger) set of enabled
xstate features, even if the features to be restored are compatible.
Relax this restriction by removing the strict check against user_size.
The previous commit introduced infrastructure to calculate the actual
required size based on the intersection of requested and supported
features. We now rely on that validation and only require that the
provided xstate_size is sufficient for the active features.
Signed-off-by: Andrei Vagin <avagin@xxxxxxxxxx>
---
arch/x86/kernel/fpu/signal.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index 1e7cc114c186..083f03d2d002 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -36,14 +36,23 @@ static inline bool check_xstate_in_sigframe(struct fxregs_state __user *buf_fx,
if (__copy_from_user(fx_sw, &buf_fx->sw_reserved[0], sizeof(*fx_sw)))
return false;
- /* Check for the first magic field and other error scenarios. */
+ /* Check for the first magic field and other error scenarios.
+ *
+ * Do not enforce that fx_sw->xstate_size matches the task's
+ * fpstate->user_size. The frame could be saved on another CPU with a
+ * different set of xtate features. The actual set of used features is
+ * defined in the xsave header. If the buffer contains any unsupported
+ * feature states, it will be rejected.
+ */
if (fx_sw->magic1 != FP_XSTATE_MAGIC1 ||
fx_sw->xstate_size < min_xstate_size ||
- fx_sw->xstate_size > fpstate->user_size ||
fx_sw->xstate_size > fx_sw->extended_size ||
fx_sw->extended_size - fx_sw->xstate_size < FP_XSTATE_MAGIC2_SIZE)
goto err_setfx;
+ if (!access_ok(buf_fx, fx_sw->extended_size))
+ goto err_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
--
2.54.0.1189.g8c84645362-goog