lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 11 Jan 2018 08:20:39 -0600
From:   Josh Poimboeuf <jpoimboe@...hat.com>
To:     David Woodhouse <dwmw@...zon.co.uk>
Cc:     Andi Kleen <ak@...ux.intel.com>, Paul Turner <pjt@...gle.com>,
        LKML <linux-kernel@...r.kernel.org>,
        Linus Torvalds <torvalds@...ux-foundation.org>,
        Greg Kroah-Hartman <gregkh@...ux-foundation.org>,
        Tim Chen <tim.c.chen@...ux.intel.com>,
        Dave Hansen <dave.hansen@...el.com>, tglx@...utronix.de,
        Kees Cook <keescook@...gle.com>,
        Rik van Riel <riel@...hat.com>,
        Peter Zijlstra <peterz@...radead.org>,
        Andy Lutomirski <luto@...capital.net>,
        Jiri Kosina <jikos@...nel.org>, gnomes@...rguk.ukuu.org.uk,
        x86@...nel.org, bp@...en8.de, rga@...zon.de,
        thomas.lendacky@....com
Subject: Re: [PATCH v2.1] x86/retpoline: Fill return stack buffer on vmexit

On Thu, Jan 11, 2018 at 11:37:18AM +0000, David Woodhouse wrote:
> In accordance with the Intel and AMD documentation, we need to overwrite
> all entries in the RSB on exiting a guest, to prevent malicious branch
> target predictions from affecting the host kernel. This is needed both
> for retpoline and for IBRS.
> 
> Signed-off-by: David Woodhouse <dwmw@...zon.co.uk>
> ---
> v2: Reduce the size of the ALTERNATIVE insns, fix .align (again)!
>     Sent in private email for testing, hence this second public post is
> v2.1: Add CONFIG_RETPOLINE around RSB stuffing
> 
> Sorry, Josh, objtool broke again! :)
> 
>  arch/x86/include/asm/nospec-branch.h | 76 ++++++++++++++++++++++++++++++++++++
>  arch/x86/kvm/svm.c                   |  4 ++
>  arch/x86/kvm/vmx.c                   |  4 ++
>  3 files changed, 84 insertions(+)
> 
> diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
> index 7d70ea9..b55ff79 100644
> --- a/arch/x86/include/asm/nospec-branch.h
> +++ b/arch/x86/include/asm/nospec-branch.h
> @@ -7,6 +7,50 @@
>  #include <asm/alternative-asm.h>
>  #include <asm/cpufeatures.h>
>  
> +/*
> + * Fill the CPU return stack buffer.
> + *
> + * Each entry in the RSB, if used for a speculative 'ret', contains an
> + * infinite 'pause; jmp' loop to capture speculative execution.
> + *
> + * This is required in various cases for retpoline and IBRS-based
> + * mitigations for the Spectre variant 2 vulnerability. Sometimes to
> + * eliminate potentially bogus entries from the RSB, and sometimes
> + * purely to ensure that it doesn't get empty, which on some CPUs would
> + * allow predictions from other (unwanted!) sources to be used.
> + *
> + * We define a CPP macro such that it can be used from both .S files and
> + * inline assembly. It's possible to do a .macro and then include that
> + * from C via asm(".include <asm/nospec-branch.h>") but let's not go there.
> + */
> +
> +#define RSB_CLEAR_LOOPS		32	/* To forcibly overwrite all entries */
> +#define RSB_FILL_LOOPS		16	/* To avoid underflow */
> +
> +#define __FILL_RETURN_BUFFER_PREP(reg, nr)	\
> +	mov	$(nr/2), reg
> +
> +#define __FILL_RETURN_BUFFER(reg, nr, sp, uniq)	\
> +	.align	16;				\
> +.Ldo_call1_ ## uniq:				\
> +	call	.Ldo_call2_ ## uniq;		\
> +.Ltrap1_ ## uniq:				\
> +	pause;					\
> +	jmp	.Ltrap1_ ## uniq;		\
> +	.align	16;				\
> +.Ldo_call2_ ## uniq:				\
> +	call	.Ldo_loop_ ## uniq;		\
> +.Ltrap2_ ## uniq:				\
> +	pause;					\
> +	jmp	.Ltrap2_ ## uniq;		\
> +	.align	16;				\
> +.Ldo_loop_ ## uniq:				\
> +	dec	reg;				\
> +	jnz	.Ldo_call1_ ## uniq;		\
> +	add	$(BITS_PER_LONG/8) * nr, sp; \
> +.Lskip_rsb_ ## uniq:;
> +
> +
>  #ifdef __ASSEMBLY__
>  
>  /*
> @@ -61,6 +105,19 @@
>  #endif
>  .endm
>  
> + /*
> +  * A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP
> +  * monstrosity above, manually.
> +  */
> +.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req
> +#ifdef CONFIG_RETPOLINE
> +	 ALTERNATIVE "jmp .Lskip_rsb_\@",				\
> +		     __stringify(__FILL_RETURN_BUFFER_PREP(\reg,\nr)),	\
> +		     \ftr
> +	__FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP,\@)
> +#endif
> +.endm

This seems weird.  I liked v1 a lot better.  What's the problem with
patching in the whole thing?

Also, if you go back to v1, it should be an easy objtool fix, just add
ANNOTATE_NOSPEC_ALTERNATIVE in front of it.

-- 
Josh

Powered by blists - more mailing lists