mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 15:41:52 +02:00
x86/fpu: Clean up fpregs_set()
fpregs_set() has unnecessary complexity to support short or nonzero-offset writes and to handle the case in which a copy from userspace overwrites some of the target buffer and then fails. Support for partial writes is useless -- just require that the write has offset 0 and the correct size, and copy into a temporary kernel buffer to avoid clobbering the state if the user access fails. Signed-off-by: Andy Lutomirski <luto@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Borislav Petkov <bp@suse.de> Reviewed-by: Borislav Petkov <bp@suse.de> Link: https://lkml.kernel.org/r/20210623121452.710467587@linutronix.de
This commit is contained in:
parent
145e9e0d8c
commit
da53f60bb8
|
|
@ -304,31 +304,32 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset,
|
|||
struct user_i387_ia32_struct env;
|
||||
int ret;
|
||||
|
||||
fpu__prepare_write(fpu);
|
||||
fpstate_sanitize_xstate(fpu);
|
||||
/* No funny business with partial or oversized writes is permitted. */
|
||||
if (pos != 0 || count != sizeof(struct user_i387_ia32_struct))
|
||||
return -EINVAL;
|
||||
|
||||
if (!boot_cpu_has(X86_FEATURE_FPU))
|
||||
if (!cpu_feature_enabled(X86_FEATURE_FPU))
|
||||
return fpregs_soft_set(target, regset, pos, count, kbuf, ubuf);
|
||||
|
||||
if (!boot_cpu_has(X86_FEATURE_FXSR))
|
||||
return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
&fpu->state.fsave, 0,
|
||||
-1);
|
||||
|
||||
if (pos > 0 || count < sizeof(env))
|
||||
convert_from_fxsr(&env, target);
|
||||
|
||||
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &env, 0, -1);
|
||||
if (!ret)
|
||||
convert_to_fxsr(&target->thread.fpu.state.fxsave, &env);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
fpu__prepare_write(fpu);
|
||||
|
||||
if (cpu_feature_enabled(X86_FEATURE_FXSR))
|
||||
convert_to_fxsr(&fpu->state.fxsave, &env);
|
||||
else
|
||||
memcpy(&fpu->state.fsave, &env, sizeof(env));
|
||||
|
||||
/*
|
||||
* update the header bit in the xsave header, indicating the
|
||||
* Update the header bit in the xsave header, indicating the
|
||||
* presence of FP.
|
||||
*/
|
||||
if (boot_cpu_has(X86_FEATURE_XSAVE))
|
||||
if (cpu_feature_enabled(X86_FEATURE_XSAVE))
|
||||
fpu->state.xsave.header.xfeatures |= XFEATURE_MASK_FP;
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_X86_32 || CONFIG_IA32_EMULATION */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user