Skip to content

Commit d298b03

Browse files
committed
x86/fpu: Restore the masking out of reserved MXCSR bits
Ser Olmy reported a boot failure: init[1] bad frame in sigreturn frame:(ptrval) ip:b7c9fbe6 sp:bf933310 orax:ffffffff \ in libc-2.33.so[b7bed000+156000] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b CPU: 0 PID: 1 Comm: init Tainted: G W 5.14.9 #1 Hardware name: Hewlett-Packard HP PC/HP Board, BIOS JD.00.06 12/06/2001 Call Trace: dump_stack_lvl dump_stack panic do_exit.cold do_group_exit get_signal arch_do_signal_or_restart ? force_sig_info_to_task ? force_sig exit_to_user_mode_prepare syscall_exit_to_user_mode do_int80_syscall_32 entry_INT80_32 on an old 32-bit Intel CPU: vendor_id : GenuineIntel cpu family : 6 model : 6 model name : Celeron (Mendocino) stepping : 5 microcode : 0x3 Ser bisected the problem to the commit in Fixes. tglx suggested reverting the rejection of invalid MXCSR values which this commit introduced and replacing it with what the old code did - simply masking them out to zero. Further debugging confirmed his suggestion: fpu->state.fxsave.mxcsr: 0xb7be13b4, mxcsr_feature_mask: 0xffbf WARNING: CPU: 0 PID: 1 at arch/x86/kernel/fpu/signal.c:384 __fpu_restore_sig+0x51f/0x540 so restore the original behavior only for 32-bit kernels where you have ancient machines with buggy hardware. For 32-bit programs on 64-bit kernels, user space which supplies wrong MXCSR values is considered malicious so fail the sigframe restoration there. Fixes: 6f9866a ("x86/fpu/signal: Let xrstor handle the features to init") Reported-by: Ser Olmy <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Tested-by: Ser Olmy <[email protected]> Cc: <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 225bac2 commit d298b03

File tree

1 file changed

+8
-3
lines changed

1 file changed

+8
-3
lines changed

arch/x86/kernel/fpu/signal.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,9 +379,14 @@ static int __fpu_restore_sig(void __user *buf, void __user *buf_fx,
379379
sizeof(fpu->state.fxsave)))
380380
return -EFAULT;
381381

382-
/* Reject invalid MXCSR values. */
383-
if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask)
384-
return -EINVAL;
382+
if (IS_ENABLED(CONFIG_X86_64)) {
383+
/* Reject invalid MXCSR values. */
384+
if (fpu->state.fxsave.mxcsr & ~mxcsr_feature_mask)
385+
return -EINVAL;
386+
} else {
387+
/* Mask invalid bits out for historical reasons (broken hardware). */
388+
fpu->state.fxsave.mxcsr &= ~mxcsr_feature_mask;
389+
}
385390

386391
/* Enforce XFEATURE_MASK_FPSSE when XSAVE is enabled */
387392
if (use_xsave())

0 commit comments

Comments
 (0)