• Thomas Gleixner's avatar
    x86/fpu: Prevent FPU state corruption · 59f5ede3
    Thomas Gleixner authored
    The FPU usage related to task FPU management is either protected by
    disabling interrupts (switch_to, return to user) or via fpregs_lock() which
    is a wrapper around local_bh_disable(). When kernel code wants to use the
    FPU then it has to check whether it is possible by calling irq_fpu_usable().
    
    But the condition in irq_fpu_usable() is wrong. It allows FPU to be used
    when:
    
       !in_interrupt() || interrupted_user_mode() || interrupted_kernel_fpu_idle()
    
    The latter is checking whether some other context already uses FPU in the
    kernel, but if that's not the case then it allows FPU to be used
    unconditionally even if the calling context interrupted a fpregs_lock()
    critical region. If that happens then the FPU state of the interrupted
    context becomes corrupted.
    
    Allow in kernel FPU usage only when no other context has in kernel FPU
    usage and either the calling context is not hard interrupt context or the
    hard interrupt did not interrupt a local bottomhalf disabled region.
    
    It's hard to find a proper Fixes tag as the condition was broken in one way
    or the other for a very long time and the eager/lazy FPU changes caused a
    lot of churn. Picked something remotely connected from the history.
    
    This survived undetected for quite some time as FPU usage in interrupt
    context is rare, but the recent changes to the random code unearthed it at
    least on a kernel which had FPU debugging enabled. There is probably a
    higher rate of silent corruption as not all issues can be detected by the
    FPU debugging code. This will be addressed in a subsequent change.
    
    Fixes: 5d2bd700 ("x86, fpu: decouple non-lazy/eager fpu restore from xsave")
    Reported-by: default avatarFilipe Manana <fdmanana@suse.com>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Tested-by: default avatarFilipe Manana <fdmanana@suse.com>
    Reviewed-by: default avatarBorislav Petkov <bp@suse.de>
    Cc: stable@vger.kernel.org
    Link: https://lore.kernel.org/r/20220501193102.588689270@linutronix.de
    59f5ede3
core.c 22.4 KB