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:   Fri, 23 Aug 2019 09:59:33 +0200
From:   Peter Zijlstra <peterz@...radead.org>
To:     Sean Christopherson <sean.j.christopherson@...el.com>
Cc:     Thomas Gleixner <tglx@...utronix.de>,
        Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>,
        x86@...nel.org, "H. Peter Anvin" <hpa@...or.com>,
        linux-kernel@...r.kernel.org, Paolo Bonzini <pbonzini@...hat.com>,
        kvm@...r.kernel.org
Subject: Re: [PATCH] x86/retpoline: Don't clobber RFLAGS during CALL_NOSPEC
 on i386

On Thu, Aug 22, 2019 at 02:11:22PM -0700, Sean Christopherson wrote:
> Use 'lea' instead of 'add' when adjusting %rsp in CALL_NOSPEC so as to
> avoid clobbering flags.
> 
> KVM's emulator makes indirect calls into a jump table of sorts, where
> the destination of the CALL_NOSPEC is a small blob of code that performs
> fast emulation by executing the target instruction with fixed operands.
> 
>   adcb_al_dl:
>      0x000339f8 <+0>:   adc    %dl,%al
>      0x000339fa <+2>:   ret
> 
> A major motiviation for doing fast emulation is to leverage the CPU to
> handle consumption and manipulation of arithmetic flags, i.e. RFLAGS is
> both an input and output to the target of CALL_NOSPEC.  Clobbering flags
> results in all sorts of incorrect emulation, e.g. Jcc instructions often
> take the wrong path.  Sans the nops...
> 
>   asm("push %[flags]; popf; " CALL_NOSPEC " ; pushf; pop %[flags]\n"
>      0x0003595a <+58>:  mov    0xc0(%ebx),%eax
>      0x00035960 <+64>:  mov    0x60(%ebx),%edx
>      0x00035963 <+67>:  mov    0x90(%ebx),%ecx
>      0x00035969 <+73>:  push   %edi
>      0x0003596a <+74>:  popf
>      0x0003596b <+75>:  call   *%esi
>      0x000359a0 <+128>: pushf
>      0x000359a1 <+129>: pop    %edi
>      0x000359a2 <+130>: mov    %eax,0xc0(%ebx)
>      0x000359b1 <+145>: mov    %edx,0x60(%ebx)
> 
>   ctxt->eflags = (ctxt->eflags & ~EFLAGS_MASK) | (flags & EFLAGS_MASK);
>      0x000359a8 <+136>: mov    -0x10(%ebp),%eax
>      0x000359ab <+139>: and    $0x8d5,%edi
>      0x000359b4 <+148>: and    $0xfffff72a,%eax
>      0x000359b9 <+153>: or     %eax,%edi
>      0x000359bd <+157>: mov    %edi,0x4(%ebx)
> 
> For the most part this has gone unnoticed as emulation of guest code
> that can trigger fast emulation is effectively limited to MMIO when
> running on modern hardware, and MMIO is rarely, if ever, accessed by
> instructions that affect or consume flags.

Also, because nobody every uses 32bit anymore, I suspect ;-)

> Breakage is almost instantaneous when running with unrestricted guest
> disabled, in which case KVM must emulate all instructions when the guest
> has invalid state, e.g. when the guest is in Big Real Mode during early
> BIOS.
> 
> Cc: Peter Zijlstra <peterz@...radead.org>
> Cc: Paolo Bonzini <pbonzini@...hat.com>
> Cc: <kvm@...r.kernel.org>
> Cc: <stable@...r.kernel.org>
> Fixes: 1a29b5b7f347a ("KVM: x86: Make indirect calls in emulator speculation safe")

Cute; arguably this is a fix for:

776b043848fd2 ("x86/retpoline: Add initial retpoline support")

The patch you quote just happens to trigger it in KVM, but you're right
to note that CALL shouldn't frob EFLAGS, and who knows what possible
other sites care.

Anyway,

Acked-by: Peter Zijlstra (Intel) <peterz@...radead.org>

> Signed-off-by: Sean Christopherson <sean.j.christopherson@...el.com>
> ---
>  arch/x86/include/asm/nospec-branch.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
> index 109f974f9835..80bc209c0708 100644
> --- a/arch/x86/include/asm/nospec-branch.h
> +++ b/arch/x86/include/asm/nospec-branch.h
> @@ -192,7 +192,7 @@
>  	"    	lfence;\n"					\
>  	"       jmp    902b;\n"					\
>  	"       .align 16\n"					\
> -	"903:	addl   $4, %%esp;\n"				\
> +	"903:	lea    4(%%esp), %%esp;\n"			\
>  	"       pushl  %[thunk_target];\n"			\
>  	"       ret;\n"						\
>  	"       .align 16\n"					\
> -- 
> 2.22.0
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ