Skip to content

Commit 44eeff9

Browse files
avaginbp3tk0v
authored andcommitted
Revert "x86/fpu: Refine and simplify the magic number check during signal return"
This reverts dc8aa31 ("x86/fpu: Refine and simplify the magic number check during signal return"). The aforementioned commit broke applications that construct signal frames in userspace (such as CRIU and gVisor) if the frame's xstate size is smaller than the kernel's fpstate->user_size. Furthermore, this introduces a critical issue for checkpoint/restore tools like CRIU. If a process is checkpointed while inside a signal handler, its stack contains a signal frame formatted according to the source host's xstate capabilities. If that process is later restored on a destination host with larger xstate capabilities (e.g., a newer CPU with more features enabled, resulting in a larger fpstate->user_size), the kernel will look for FP_XSTATE_MAGIC2 at the destination host's larger user_size offset instead of the offset encoded in the frame's fx_sw->xstate_size. This causes the magic2 check to fail, forcing sigreturn to silently fall back to "FX-only" mode. Upon return from the signal handler, the process's extended state is reset to initial values instead of being restored, leading to silent data corruption. The aforementioned commit cited d877550 ("x86/fpu: Stop relying on userspace for info to fault in xsave buffer") as justification to stop relying on userspace for the magic number check. However, these two changes are fundamentally different. The last one only changed how much memory the kernel ensures is paged-in before running XRSTOR to prevent an infinite loop. It did not change the signal frame format or how the layout is validated. Reverting this change restores the use of fx_sw->xstate_size for locating magic2 and restores the necessary sanity checks, ensuring that the signal frame remains self-describing and portable. [ bp: Massage commit message. ] Fixes: dc8aa31 ("x86/fpu: Refine and simplify the magic number check during signal return") Signed-off-by: Andrei Vagin <avagin@google.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Acked-by: Chang S. Bae <chang.seok.bae@intel.com> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20260429000623.3356606-1-avagin@google.com
1 parent 8aeb879 commit 44eeff9

1 file changed

Lines changed: 8 additions & 3 deletions

File tree

arch/x86/kernel/fpu/signal.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,19 @@
2727
static inline bool check_xstate_in_sigframe(struct fxregs_state __user *fxbuf,
2828
struct _fpx_sw_bytes *fx_sw)
2929
{
30+
int min_xstate_size = sizeof(struct fxregs_state) +
31+
sizeof(struct xstate_header);
3032
void __user *fpstate = fxbuf;
3133
unsigned int magic2;
3234

3335
if (__copy_from_user(fx_sw, &fxbuf->sw_reserved[0], sizeof(*fx_sw)))
3436
return false;
3537

36-
/* Check for the first magic field */
37-
if (fx_sw->magic1 != FP_XSTATE_MAGIC1)
38+
/* Check for the first magic field and other error scenarios. */
39+
if (fx_sw->magic1 != FP_XSTATE_MAGIC1 ||
40+
fx_sw->xstate_size < min_xstate_size ||
41+
fx_sw->xstate_size > x86_task_fpu(current)->fpstate->user_size ||
42+
fx_sw->xstate_size > fx_sw->extended_size)
3843
goto setfx;
3944

4045
/*
@@ -43,7 +48,7 @@ static inline bool check_xstate_in_sigframe(struct fxregs_state __user *fxbuf,
4348
* fpstate layout with out copying the extended state information
4449
* in the memory layout.
4550
*/
46-
if (__get_user(magic2, (__u32 __user *)(fpstate + x86_task_fpu(current)->fpstate->user_size)))
51+
if (__get_user(magic2, (__u32 __user *)(fpstate + fx_sw->xstate_size)))
4752
return false;
4853

4954
if (likely(magic2 == FP_XSTATE_MAGIC2))

0 commit comments

Comments
 (0)