x86: copy_fpstate_to_sigframe(): have fpregs_soft_get() use kernel buffer
authorAl Viro <viro@zeniv.linux.org.uk>
Fri, 21 Feb 2020 05:11:55 +0000 (00:11 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 26 Jun 2020 05:01:33 +0000 (01:01 -0400)
... then copy_to_user() the results

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/x86/kernel/fpu/signal.c

index 9393a44..e0b832d 100644 (file)
@@ -170,14 +170,14 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
        ia32_fxstate &= (IS_ENABLED(CONFIG_X86_32) ||
                         IS_ENABLED(CONFIG_IA32_EMULATION));
 
+       if (!static_cpu_has(X86_FEATURE_FPU)) {
+               struct user_i387_ia32_struct fp;
+               fpregs_soft_get(current, NULL, 0, sizeof(fp), &fp, NULL);
+               return copy_to_user(buf, &fp, sizeof(fp)) ? -EFAULT : 0;
+       }
+
        if (!access_ok(buf, size))
                return -EACCES;
-
-       if (!static_cpu_has(X86_FEATURE_FPU))
-               return fpregs_soft_get(current, NULL, 0,
-                       sizeof(struct user_i387_ia32_struct), NULL,
-                       (struct _fpstate_32 __user *) buf) ? -1 : 1;
-
 retry:
        /*
         * Load the FPU registers if they are not valid for the current task.