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: [v2.6.32.y 2/2] KVM: x86: fix missing checks in syscall emulation
Date: Thu, 22 Mar 2012 21:07:22 -0300 [thread overview]
Message-ID: <20120323000722.GA28274@amt.cnet> (raw)
In-Reply-To: <1332406246-3978-3-git-send-email-stefan.bader@canonical.com>
On Thu, Mar 22, 2012 at 09:50:42AM +0100, Stefan Bader wrote:
> >From 69712f0c7cbb6363f7b2170fba93945a72d77712 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 2/2] 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 | 57 ++++++++++++++++++++++++++++++++++-
> 2 files changed, 68 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
> index 5d938f9..1f137af 100644
> --- a/arch/x86/include/asm/kvm_emulate.h
> +++ b/arch/x86/include/asm/kvm_emulate.h
> @@ -185,6 +185,19 @@ struct x86_emulate_ctxt {
> #define X86EMUL_MODE_PROT32 4 /* 32-bit protected mode. */
> #define X86EMUL_MODE_PROT64 8 /* 64-bit (long) mode. */
>
> +/* 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
> +
> /* Host execution mode. */
> #if defined(CONFIG_X86_32)
> #define X86EMUL_MODE_HOST X86EMUL_MODE_PROT32
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index 1350e43..10134d2 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -1495,20 +1495,73 @@ setup_syscalls_segments(struct x86_emulate_ctxt *ctxt,
> ss->present = 1;
> }
>
> +static bool syscall_is_enabled(struct x86_emulate_ctxt *ctxt,
> + struct x86_emulate_ops *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->vcpu, &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)
> +emulate_syscall(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
> {
> struct decode_cache *c = &ctxt->decode;
> struct kvm_segment cs, ss;
> u64 msr_data;
> + u64 efer = 0;
>
> /* syscall is not available in real mode */
> if (c->lock_prefix || ctxt->mode == X86EMUL_MODE_REAL
> || ctxt->mode == X86EMUL_MODE_VM86)
> return -1;
>
> + if (!(syscall_is_enabled(ctxt, ops)))
> + return -1;
> +
> + kvm_x86_ops->get_msr(ctxt->vcpu, MSR_EFER, &efer);
> setup_syscalls_segments(ctxt, &cs, &ss);
>
> + if (!(efer & EFER_SCE))
> + return -1;
> +
It should inject an exception (kvm_queue_exception(UD_VECTOR)) instead
of simply looping on the same instruction.
next prev parent reply other threads:[~2012-03-23 0:12 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 [this message]
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
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=20120323000722.GA28274@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox