linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@kernel.org>
To: Eric Biggers <ebiggers3@gmail.com>
Cc: linux-kernel@vger.kernel.org,
	Andrew Morton <akpm@linux-foundation.org>,
	Andy Lutomirski <luto@amacapital.net>,
	Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	Fenghua Yu <fenghua.yu@intel.com>,
	"H . Peter Anvin" <hpa@zytor.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Oleg Nesterov <oleg@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Rik van Riel <riel@redhat.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Yu-cheng Yu <yu-cheng.yu@intel.com>
Subject: Re: [PATCH 03/10] x86/fpu: Use validate_xstate_header() to validate the xstate_header in sanitize_restored_xstate()
Date: Mon, 25 Sep 2017 08:07:59 +0200	[thread overview]
Message-ID: <20170925060759.cei6lheshpeud6df@gmail.com> (raw)
In-Reply-To: <20170924200853.GB26260@zzz.localdomain>


* Eric Biggers <ebiggers3@gmail.com> wrote:

> The following diff against tip/master fixes the bug.  Note: we *could* check
> 'use_xsave()' instead of 'state_size > offsetof(struct xregs_state, header)',
> but that might be confusing in the case where we couldn't find the xstate
> information in the memory layout and only copy the fxregs_state, since then we'd
> actually be validating the xsave_header which was already there, which shouldn't
> ever fail.
> 
> diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
> index afe54247cf27..fb639e70048f 100644
> --- a/arch/x86/kernel/fpu/signal.c
> +++ b/arch/x86/kernel/fpu/signal.c
> @@ -331,7 +331,8 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size)
>  			err = copy_user_to_xstate(&fpu->state.xsave, buf_fx);
>  		} else {
>  			err = __copy_from_user(&fpu->state.xsave, buf_fx, state_size);
> -			if (!err)
> +
> +			if (!err && state_size > offsetof(struct xregs_state, header))
>  				err = validate_xstate_header(&fpu->state.xsave.header);
>  		}

Yeah, I agree that checking 'state_size' is cleaner although note that technically 
this check isn't enough, because if 'state_size' is pointing somewhere inside the 
header (i.e. does not fully include it), the code still attempts a bad memcpy().

But that cannot happen, due to how state_size is set up:

        int state_size = fpu_kernel_xstate_size;

	...

                        state_size = sizeof(struct fxregs_state);
		...
                } else {
		...
                        state_size = fx_sw_user.xstate_size;
		...

and because fx_sw_user.xstate_size has to be at least:

        int min_xstate_size = sizeof(struct fxregs_state) +
                              sizeof(struct xstate_header);

i.e. the 'state_size' variable has a discrete set of possible values, none of 
which values point inside the header. Something to keep in mind ...


Note that there's some room for improvement within both the signal and the regset 
copying of FPU state. We have this pattern:

                if (using_compacted_format()) {
                        err = copy_user_to_xstate(&fpu->state.xsave, buf_fx);
                } else {
                        err = __copy_from_user(&fpu->state.xsave, buf_fx, state_size);
                        if (!err)
                                err = validate_xstate_header(&fpu->state.xsave.header);
                }

... and copy_user_to_xstate() does:

        if (__copy_from_user(&hdr, ubuf + offset, size))
                return -EFAULT;

        if (validate_xstate_header(&hdr))
                return -EINVAL;

I.e. what we probably want is a helper function that just copies the darn thing 
and validates everything.

Note how regset.c duplicates a similar pattern:

        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_xstate_header(&xsave->header);
        }


I.e. what we should probably do is to push the using_compacted_format() check into 
copy_user_to_xstate(). That makes copy_user_to_xstate() a high level method that 
can deal with all formats and which does all verification.

But that's a separate cleanup.

Thanks,

	Ingo

  reply	other threads:[~2017-09-25  6:08 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-24 10:59 [PATCH 00/10] x86/fpu: Split up "x86/fpu: Tighten validation of user-supplied xstate_header" Ingo Molnar
2017-09-24 10:59 ` [PATCH 01/10] x86/fpu: Introduce validate_xstate_header() Ingo Molnar
2017-09-26  8:34   ` [tip:x86/fpu] " tip-bot for Eric Biggers
2017-09-24 10:59 ` [PATCH 02/10] x86/fpu: Use validate_xstate_header() to validate the xstate_header in xstateregs_set() Ingo Molnar
2017-09-26  8:34   ` [tip:x86/fpu] " tip-bot for Eric Biggers
2017-09-24 10:59 ` [PATCH 03/10] x86/fpu: Use validate_xstate_header() to validate the xstate_header in sanitize_restored_xstate() Ingo Molnar
2017-09-24 18:51   ` Eric Biggers
2017-09-24 19:02     ` Ingo Molnar
2017-09-24 20:08       ` Eric Biggers
2017-09-25  6:07         ` Ingo Molnar [this message]
2017-09-25  6:14         ` Ingo Molnar
2017-09-25  7:20           ` Eric Biggers
2017-09-25  7:30             ` Ingo Molnar
2017-09-26  8:35   ` [tip:x86/fpu] x86/fpu: Use validate_xstate_header() to validate the xstate_header in __fpu__restore_sig() tip-bot for Eric Biggers
2017-09-24 10:59 ` [PATCH 04/10] x86/fpu: Copy the full state_header in copy_kernel_to_xstate() Ingo Molnar
2017-09-26  8:35   ` [tip:x86/fpu] " tip-bot for Eric Biggers
2017-09-24 10:59 ` [PATCH 05/10] x86/fpu: Eliminate the 'xfeatures' local variable " Ingo Molnar
2017-09-26  8:35   ` [tip:x86/fpu] " tip-bot for Eric Biggers
2017-09-24 10:59 ` [PATCH 06/10] x86/fpu: Use validate_xstate_header() to validate the xstate_header " Ingo Molnar
2017-09-26  8:36   ` [tip:x86/fpu] " tip-bot for Eric Biggers
2017-09-24 10:59 ` [PATCH 07/10] x86/fpu: Copy the full header in copy_user_to_xstate() Ingo Molnar
2017-09-26  8:36   ` [tip:x86/fpu] " tip-bot for Eric Biggers
2017-09-24 10:59 ` [PATCH 08/10] x86/fpu: Eliminate the 'xfeatures' local variable " Ingo Molnar
2017-09-26  8:37   ` [tip:x86/fpu] " tip-bot for Eric Biggers
2017-09-24 10:59 ` [PATCH 09/10] x86/fpu: Use validate_xstate_header() to validate the xstate_header " Ingo Molnar
2017-09-26  8:37   ` [tip:x86/fpu] " tip-bot for Eric Biggers
2017-09-24 10:59 ` [PATCH 10/10] x86/fpu: Use using_compacted_format() instead of open coded X86_FEATURE_XSAVES Ingo Molnar
2017-09-26  8:37   ` [tip:x86/fpu] " tip-bot for Eric Biggers
2017-09-24 18:04 ` [PATCH 00/10] x86/fpu: Split up "x86/fpu: Tighten validation of user-supplied xstate_header" Linus Torvalds
2017-09-24 19:01   ` Ingo Molnar
2017-09-26 16:28     ` [RFC GIT PULL] x86 FPU fixes and cleanups Ingo Molnar
2017-09-26 18:17       ` Linus Torvalds
2017-09-27  7:40         ` [RFC GIT PULL, v2] " Ingo Molnar

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=20170925060759.cei6lheshpeud6df@gmail.com \
    --to=mingo@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=ebiggers3@gmail.com \
    --cc=fenghua.yu@intel.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=oleg@redhat.com \
    --cc=peterz@infradead.org \
    --cc=riel@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).