lkml.org 
[lkml]   [2021]   [Jun]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 124/146] x86/fpu: Reset state for all signal restore failures
    Date
    From: Thomas Gleixner <tglx@linutronix.de>

    commit efa165504943f2128d50f63de0c02faf6dcceb0d upstream.

    If access_ok() or fpregs_soft_set() fails in __fpu__restore_sig() then the
    function just returns but does not clear the FPU state as it does for all
    other fatal failures.

    Clear the FPU state for these failures as well.

    Fixes: 72a671ced66d ("x86, fpu: Unify signal handling code paths for x86 and x86_64 kernels")
    Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    Signed-off-by: Borislav Petkov <bp@suse.de>
    Cc: stable@vger.kernel.org
    Link: https://lkml.kernel.org/r/87mtryyhhz.ffs@nanos.tec.linutronix.de
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    arch/x86/kernel/fpu/signal.c | 26 +++++++++++++++-----------
    1 file changed, 15 insertions(+), 11 deletions(-)

    --- a/arch/x86/kernel/fpu/signal.c
    +++ b/arch/x86/kernel/fpu/signal.c
    @@ -307,13 +307,17 @@ static int __fpu__restore_sig(void __use
    return 0;
    }

    - if (!access_ok(buf, size))
    - return -EACCES;
    + if (!access_ok(buf, size)) {
    + ret = -EACCES;
    + goto out;
    + }

    - if (!static_cpu_has(X86_FEATURE_FPU))
    - return fpregs_soft_set(current, NULL,
    - 0, sizeof(struct user_i387_ia32_struct),
    - NULL, buf) != 0;
    + if (!static_cpu_has(X86_FEATURE_FPU)) {
    + ret = fpregs_soft_set(current, NULL, 0,
    + sizeof(struct user_i387_ia32_struct),
    + NULL, buf);
    + goto out;
    + }

    if (use_xsave()) {
    struct _fpx_sw_bytes fx_sw_user;
    @@ -396,7 +400,7 @@ static int __fpu__restore_sig(void __use
    */
    ret = __copy_from_user(&env, buf, sizeof(env));
    if (ret)
    - goto err_out;
    + goto out;
    envp = &env;
    }

    @@ -426,7 +430,7 @@ static int __fpu__restore_sig(void __use

    ret = copy_user_to_xstate(&fpu->state.xsave, buf_fx);
    if (ret)
    - goto err_out;
    + goto out;

    sanitize_restored_user_xstate(&fpu->state, envp, user_xfeatures,
    fx_only);
    @@ -446,7 +450,7 @@ static int __fpu__restore_sig(void __use
    ret = __copy_from_user(&fpu->state.fxsave, buf_fx, state_size);
    if (ret) {
    ret = -EFAULT;
    - goto err_out;
    + goto out;
    }

    sanitize_restored_user_xstate(&fpu->state, envp, user_xfeatures,
    @@ -464,7 +468,7 @@ static int __fpu__restore_sig(void __use
    } else {
    ret = __copy_from_user(&fpu->state.fsave, buf_fx, state_size);
    if (ret)
    - goto err_out;
    + goto out;

    fpregs_lock();
    ret = copy_kernel_to_fregs_err(&fpu->state.fsave);
    @@ -475,7 +479,7 @@ static int __fpu__restore_sig(void __use
    fpregs_deactivate(fpu);
    fpregs_unlock();

    -err_out:
    +out:
    if (ret)
    fpu__clear_user_states(fpu);
    return ret;

    \
     
     \ /
      Last update: 2021-06-21 18:39    [W:4.101 / U:0.104 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site