[PATCH 09/10] x86/fpu: Allow restoring signal frames with larger xstate_size
Andrei Vagin <[email protected]> Mon, 15 Jun 2026 19:37:15 +0000
| Newsgroups | dev.linux.lists.criu,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> --- 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