Hi!
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.
That's quite a confusing calling convention, right?
+++ b/arch/x86/kernel/fpu/signal.c @@ -262,15 +262,23 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) return 0; }
- if (!access_ok(VERIFY_READ, buf, size))
- if (!access_ok(VERIFY_READ, buf, size)) {
return -EACCES;fpu__clear(fpu);
- }
This returns -errno on failure.
fpu__activate_curr(fpu);
- 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)) {
int ret = fpregs_soft_set(current, NULL, 0,
sizeof(struct user_i387_ia32_struct),
NULL, buf);
if (ret)
fpu__clear(fpu);
return ret != 0;
- }
And this explicitely turns negative error into 1 for maximum confusion.
I don't see the same confusion in mainline.
Best regards, Pavel