All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marcelo Tosatti <mtosatti@redhat.com>
To: Stefan Bader <stefan.bader@canonical.com>
Cc: stable@vger.kernel.org, kvm@vger.kernel.org,
	Stephan Baerwolf <stephan.baerwolf@tu-ilmenau.de>,
	Avi Kivity <avi@redhat.com>
Subject: Re: [v3.0.y 2/2] KVM: x86: fix missing checks in syscall emulation
Date: Fri, 23 Mar 2012 11:01:04 -0300	[thread overview]
Message-ID: <20120323140104.GB8174@amt.cnet> (raw)
In-Reply-To: <1332406246-3978-5-git-send-email-stefan.bader@canonical.com>

On Thu, Mar 22, 2012 at 09:50:44AM +0100, Stefan Bader wrote:
> >From 30870b1a5d29c07b75843c0b667fa29a63d818a4 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Stephan=20B=C3=A4rwolf?= <stephan.baerwolf@tu-ilmenau.de>
> Date: Thu, 12 Jan 2012 16:43:04 +0100
> Subject: [PATCH 8/8] KVM: x86: fix missing checks in syscall emulation
> 
> On hosts without this patch, 32bit guests will crash (and 64bit guests
> may behave in a wrong way) for example by simply executing following
> nasm-demo-application:
> 
>     [bits 32]
>     global _start
>     SECTION .text
>     _start: syscall
> 
> (I tested it with winxp and linux - both always crashed)
> 
>     Disassembly of section .text:
> 
>     00000000 <_start>:
>        0:   0f 05                   syscall
> 
> The reason seems a missing "invalid opcode"-trap (int6) for the
> syscall opcode "0f05", which is not available on Intel CPUs
> within non-longmodes, as also on some AMD CPUs within legacy-mode.
> (depending on CPU vendor, MSR_EFER and cpuid)
> 
> Because previous mentioned OSs may not engage corresponding
> syscall target-registers (STAR, LSTAR, CSTAR), they remain
> NULL and (non trapping) syscalls are leading to multiple
> faults and finally crashs.
> 
> Depending on the architecture (AMD or Intel) pretended by
> guests, various checks according to vendor's documentation
> are implemented to overcome the current issue and behave
> like the CPUs physical counterparts.
> 
> [mtosatti: cleanup/beautify code]
> 
> Signed-off-by: Stephan Baerwolf <stephan.baerwolf@tu-ilmenau.de>
> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
> 
> (backported from commit c2226fc9e87ba3da060e47333657cd6616652b84 upstream)
> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
> ---
>  arch/x86/include/asm/kvm_emulate.h |   13 +++++++++
>  arch/x86/kvm/emulate.c             |   51 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 64 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
> index 18e54f1..0ab6a4d 100644
> --- a/arch/x86/include/asm/kvm_emulate.h
> +++ b/arch/x86/include/asm/kvm_emulate.h
> @@ -301,6 +301,19 @@ struct x86_emulate_ctxt {
>  #define X86EMUL_MODE_PROT     (X86EMUL_MODE_PROT16|X86EMUL_MODE_PROT32| \
>  			       X86EMUL_MODE_PROT64)
>  
> +/* CPUID vendors */
> +#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx 0x68747541
> +#define X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx 0x444d4163
> +#define X86EMUL_CPUID_VENDOR_AuthenticAMD_edx 0x69746e65
> +
> +#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx 0x69444d41
> +#define X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx 0x21726574
> +#define X86EMUL_CPUID_VENDOR_AMDisbetterI_edx 0x74656273
> +
> +#define X86EMUL_CPUID_VENDOR_GenuineIntel_ebx 0x756e6547
> +#define X86EMUL_CPUID_VENDOR_GenuineIntel_ecx 0x6c65746e
> +#define X86EMUL_CPUID_VENDOR_GenuineIntel_edx 0x49656e69
> +
>  enum x86_intercept_stage {
>  	X86_ICTP_NONE = 0,   /* Allow zero-init to not match anything */
>  	X86_ICPT_PRE_EXCEPT,
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index adc9867..3e7d913 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -1901,6 +1901,51 @@ setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
>  	ss->p = 1;
>  }
>  
> +static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
> +{
> +	struct x86_emulate_ops *ops = ctxt->ops;
> +	u32 eax, ebx, ecx, edx;
> +
> +	/*
> +	 * syscall should always be enabled in longmode - so only become
> +	 * vendor specific (cpuid) if other modes are active...
> +	 */
> +	if (ctxt->mode == X86EMUL_MODE_PROT64)
> +		return true;
> +
> +	eax = 0x00000000;
> +	ecx = 0x00000000;
> +	if (ops->get_cpuid(ctxt, &eax, &ebx, &ecx, &edx)) {
> +		/*
> +		 * Intel ("GenuineIntel")
> +		 * remark: Intel CPUs only support "syscall" in 64bit
> +		 * longmode. Also an 64bit guest with a
> +		 * 32bit compat-app running will #UD !! While this
> +		 * behaviour can be fixed (by emulating) into AMD
> +		 * response - CPUs of AMD can't behave like Intel.
> +		 */
> +		if (ebx == X86EMUL_CPUID_VENDOR_GenuineIntel_ebx &&
> +		    ecx == X86EMUL_CPUID_VENDOR_GenuineIntel_ecx &&
> +		    edx == X86EMUL_CPUID_VENDOR_GenuineIntel_edx)
> +			return false;
> +
> +		/* AMD ("AuthenticAMD") */
> +		if (ebx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ebx &&
> +		    ecx == X86EMUL_CPUID_VENDOR_AuthenticAMD_ecx &&
> +		    edx == X86EMUL_CPUID_VENDOR_AuthenticAMD_edx)
> +			return true;
> +
> +		/* AMD ("AMDisbetter!") */
> +		if (ebx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ebx &&
> +		    ecx == X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx &&
> +		    edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx)
> +			return true;
> +	}
> +
> +	/* default: (not Intel, not AMD), apply Intel's stricter rules... */
> +	return false;
> +}
> +
>  static int
>  emulate_syscall(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
>  {
> @@ -1915,9 +1960,15 @@ emulate_syscall(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
>  	    ctxt->mode == X86EMUL_MODE_VM86)
>  		return emulate_ud(ctxt);
>  
> +	if (!(em_syscall_is_enabled(ctxt)))
> +		return emulate_ud(ctxt);
> +
>  	ops->get_msr(ctxt, MSR_EFER, &efer);
>  	setup_syscalls_segments(ctxt, ops, &cs, &ss);
>  
> +	if (!(efer & EFER_SCE))
> +		return emulate_ud(ctxt);
> +
>  	ops->get_msr(ctxt, MSR_STAR, &msr_data);
>  	msr_data >>= 32;
>  	cs_sel = (u16)(msr_data & 0xfffc);

ACK


  reply	other threads:[~2012-03-23 14:01 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-22  8:50 CVE-2012-0045 for 3.2.y, 3.0.y and 2.6.32.y (again) Stefan Bader
2012-03-22  8:50 ` [v2.6.32.y 1/2] KVM: x86: extend "struct x86_emulate_ops" with "get_cpuid" Stefan Bader
2012-03-22  8:50 ` [v2.6.32.y 2/2] KVM: x86: fix missing checks in syscall emulation Stefan Bader
2012-03-23  0:07   ` Marcelo Tosatti
2012-03-23  7:01     ` Stefan Bader
2012-03-22  8:50 ` [v3.0.y 1/2] KVM: x86: extend "struct x86_emulate_ops" with "get_cpuid" Stefan Bader
2012-03-23 14:00   ` Marcelo Tosatti
2012-03-23 17:22   ` Greg KH
2012-03-23 17:47     ` Stefan Bader
2012-03-23 17:57       ` Greg KH
2012-03-22  8:50 ` [v3.0.y 2/2] KVM: x86: fix missing checks in syscall emulation Stefan Bader
2012-03-23 14:01   ` Marcelo Tosatti [this message]
2012-03-22  8:50 ` [v3.2.y 1/2] KVM: x86: extend "struct x86_emulate_ops" with "get_cpuid" Stefan Bader
2012-03-22  8:50 ` [v3.2.y 2/2] KVM: x86: fix missing checks in syscall emulation Stefan Bader
2012-03-22 14:37 ` CVE-2012-0045 for 3.2.y, 3.0.y and 2.6.32.y (again) Greg KH
2012-03-23  1:47 ` Marcelo Tosatti

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=20120323140104.GB8174@amt.cnet \
    --to=mtosatti@redhat.com \
    --cc=avi@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=stefan.bader@canonical.com \
    --cc=stephan.baerwolf@tu-ilmenau.de \
    /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.