All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: Dave Hansen <dave.hansen@intel.com>, LKML <linux-kernel@vger.kernel.org>
Cc: x86@kernel.org, Andy Lutomirski <luto@kernel.org>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	Fenghua Yu <fenghua.yu@intel.com>,
	Tony Luck <tony.luck@intel.com>,
	Yu-cheng Yu <yu-cheng.yu@intel.com>
Subject: Re: [patch 0/8] x86/fpu: Mop up XSAVES and related damage
Date: Sat, 05 Jun 2021 13:56:19 +0200	[thread overview]
Message-ID: <87k0n8zfrw.ffs@nanos.tec.linutronix.de> (raw)
In-Reply-To: <87mts4zkac.ffs@nanos.tec.linutronix.de>

On Sat, Jun 05 2021 at 12:18, Thomas Gleixner wrote:
> On Fri, Jun 04 2021 at 15:04, Dave Hansen wrote:
>> No bug is jumping out of the code as I took a brief look at it.  The
>> xbuf versus kbuf code looks a bit wonky, but I can't find a hole in it.
>
> I can....
>
> --- a/arch/x86/kernel/fpu/regset.c
> +++ b/arch/x86/kernel/fpu/regset.c
> @@ -128,7 +128,7 @@ int xstateregs_set(struct task_struct *t
>  		xbuf = vmalloc(count);
>  		if (!xbuf)
>  			return -ENOMEM;
> -		ret = user_regset_copyin(&pos, &count, NULL, &ubuf, xbuf, 0, -1);
> +		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, xbuf, 0, -1);
>  		if (ret)
>  			goto out;
>  	}

But this whole user_regset_copyin() is pointless here. See below.

Thanks,

        tglx
---
 include/asm/fpu/xstate.h |    4 ----
 kernel/fpu/regset.c      |   40 ++++++++++++++++------------------------
 kernel/fpu/xstate.c      |   12 +++++++-----
 3 files changed, 23 insertions(+), 33 deletions(-)

--- a/arch/x86/include/asm/fpu/xstate.h
+++ b/arch/x86/include/asm/fpu/xstate.h
@@ -112,8 +112,4 @@ void copy_supervisor_to_kernel(struct xr
 void copy_dynamic_supervisor_to_kernel(struct xregs_state *xstate, u64 mask);
 void copy_kernel_to_dynamic_supervisor(struct xregs_state *xstate, u64 mask);
 
-
-/* Validate an xstate header supplied by userspace (ptrace or sigreturn) */
-int validate_user_xstate_header(const struct xstate_header *hdr);
-
 #endif
--- a/arch/x86/kernel/fpu/regset.c
+++ b/arch/x86/kernel/fpu/regset.c
@@ -6,6 +6,9 @@
 #include <asm/fpu/signal.h>
 #include <asm/fpu/regset.h>
 #include <asm/fpu/xstate.h>
+
+#include <linux/vmalloc.h>
+
 #include <linux/sched/task_stack.h>
 
 /*
@@ -108,7 +111,7 @@ int xstateregs_set(struct task_struct *t
 		  const void *kbuf, const void __user *ubuf)
 {
 	struct fpu *fpu = &target->thread.fpu;
-	struct xregs_state *xsave;
+	struct xregs_state *xbuf = NULL;
 	int ret;
 
 	if (!boot_cpu_has(X86_FEATURE_XSAVE))
@@ -120,32 +123,21 @@ int xstateregs_set(struct task_struct *t
 	if (pos != 0 || count != fpu_user_xstate_size)
 		return -EFAULT;
 
-	xsave = &fpu->state.xsave;
-
-	fpu__prepare_write(fpu);
-
-	if (using_compacted_format()) {
-		if (kbuf)
-			ret = copy_kernel_to_xstate(xsave, kbuf);
-		else
-			ret = copy_user_to_xstate(xsave, ubuf);
-	} else {
-		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, xsave, 0, -1);
-		if (!ret)
-			ret = validate_user_xstate_header(&xsave->header);
+	if (!kbuf) {
+		xbuf = vmalloc(count);
+		if (!xbuf)
+			return -ENOMEM;
+		if (copy_from_user(xbuf, ubuf, count)) {
+			ret = -EFAULT;
+			goto out;
+		}
 	}
 
-	/*
-	 * mxcsr reserved bits must be masked to zero for security reasons.
-	 */
-	xsave->i387.mxcsr &= mxcsr_feature_mask;
-
-	/*
-	 * In case of failure, mark all states as init:
-	 */
-	if (ret)
-		fpstate_init(&fpu->state);
+	fpu__prepare_write(fpu);
+	ret = copy_kernel_to_xstate(&fpu->state.xsave, kbuf ? kbuf : xbuf);
 
+out:
+	vfree(xbuf);
 	return ret;
 }
 
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -515,7 +515,7 @@ int using_compacted_format(void)
 }
 
 /* Validate an xstate header supplied by userspace (ptrace or sigreturn) */
-int validate_user_xstate_header(const struct xstate_header *hdr)
+static int validate_user_xstate_header(const struct xstate_header *hdr)
 {
 	/* No unknown or supervisor features may be set */
 	if (hdr->xfeatures & ~xfeatures_mask_user())
@@ -1172,14 +1172,16 @@ int copy_kernel_to_xstate(struct xregs_s
 	 */
 	xsave->header.xfeatures |= hdr.xfeatures;
 
+	/* mxcsr reserved bits must be masked to zero for security reasons. */
+	xsave->i387.mxcsr &= mxcsr_feature_mask;
+
 	return 0;
 }
 
 /*
- * Convert from a ptrace or sigreturn standard-format user-space buffer to
- * kernel XSAVES format and copy to the target thread. This is called from
- * xstateregs_set(), as well as potentially from the sigreturn() and
- * rt_sigreturn() system calls.
+ * Convert from a sigreturn standard-format user-space buffer to kernel
+ * XSAVES format and copy to the target thread. This is called from the
+ * sigreturn() and rt_sigreturn() system calls.
  */
 int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf)
 {

      reply	other threads:[~2021-06-05 11:56 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-02  9:55 [patch 0/8] x86/fpu: Mop up XSAVES and related damage Thomas Gleixner
2021-06-02  9:55 ` [patch 1/8] selftests/x86: Test signal frame XSTATE header corruption handling Thomas Gleixner
2021-06-02 12:38   ` Borislav Petkov
2021-06-02 14:15     ` Thomas Gleixner
2021-06-03 13:16       ` Shuah Khan
2021-06-02 15:59   ` [patch V2 " Thomas Gleixner
2021-06-02 16:02     ` [patch V2a " Thomas Gleixner
2021-06-02  9:55 ` [patch 2/8] x86/fpu: Prevent state corruption in __fpu__restore_sig() Thomas Gleixner
2021-06-02 13:12   ` Borislav Petkov
2021-06-02 14:46     ` Thomas Gleixner
2021-06-02 15:58   ` [patch V2 " Thomas Gleixner
2021-06-02  9:55 ` [patch 3/8] x86/fpu: Invalidate FPU state after a failed XRSTOR from a user buffer Thomas Gleixner
2021-06-02 15:06   ` Borislav Petkov
2021-06-03 17:30     ` Andy Lutomirski
2021-06-03 19:28       ` Borislav Petkov
2021-06-02  9:55 ` [patch 4/8] x86/fpu: Limit xstate copy size in xstateregs_set() Thomas Gleixner
2021-06-02 17:44   ` Borislav Petkov
2021-06-02  9:55 ` [patch 5/8] x86/fpu: Sanitize xstateregs_set() Thomas Gleixner
2021-06-02 16:01   ` [patch V2 " Thomas Gleixner
2021-06-03 11:32     ` Borislav Petkov
2021-06-03 17:24   ` [patch " Andy Lutomirski
2021-06-02  9:55 ` [patch 6/8] x86/fpu: Add address range checks to copy_user_to_xstate() Thomas Gleixner
2021-06-02  9:55 ` [patch 7/8] x86/fpu: Clean up the fpu__clear() variants Thomas Gleixner
2021-06-02  9:55 ` [patch 8/8] x86/fpu: Deduplicate copy_xxx_to_xstate() Thomas Gleixner
2021-06-03 16:56   ` Andy Lutomirski
2021-06-02 21:28 ` [patch 0/8] x86/fpu: Mop up XSAVES and related damage Yu, Yu-cheng
2021-06-04 14:05   ` Thomas Gleixner
2021-06-04 16:27     ` Yu, Yu-cheng
2021-06-04 17:46     ` Dave Hansen
2021-06-04 18:14       ` Thomas Gleixner
2021-06-04 22:04 ` Dave Hansen
2021-06-05 10:18   ` Thomas Gleixner
2021-06-05 11:56     ` Thomas Gleixner [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87k0n8zfrw.ffs@nanos.tec.linutronix.de \
    --to=tglx@linutronix.de \
    --cc=dave.hansen@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=fenghua.yu@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=tony.luck@intel.com \
    --cc=x86@kernel.org \
    --cc=yu-cheng.yu@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.