Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > aadbe78a25743146bb784eee19f007c5 > files > 411

kvm-83-164.el5_5.9.src.rpm

From 9dad622260620bdda042282c785ecf1c1e67cfc0 Mon Sep 17 00:00:00 2001
From: Avi Kivity <avi@redhat.com>
Date: Mon, 30 Nov 2009 10:21:25 -0200
Subject: [PATCH 3/3] KVM: x86 emulator: limit instructions to 15 bytes

RH-Author: Avi Kivity <avi@redhat.com>
Message-id: <1259576485-1188-1-git-send-email-avi@redhat.com>
Patchwork-id: 3813
O-Subject: [PATCH SECURITY KVM 5.5,
	5.4.z] KVM: x86 emulator: limit instructions to 15 bytes
Bugzilla: 541165
RH-Acked-by: Eugene Teo <eugene@redhat.com>
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Gleb Natapov <gleb@redhat.com>

While we are never normally passed an instruction that exceeds 15 bytes,
smp games can cause us to attempt to interpret one, which will cause
large latencies in non-preempt hosts.

Signed-off-by: Avi Kivity <avi@redhat.com>

 Bugzilla: #541164 (5.4.z)
 Bugzilla: #541165 (5.5)

Upstream: queued for 2.6.33 and -stable; kvm.git e42d9b8141d1.

---
 arch/x86/include/asm/kvm_x86_emulate.h |    2 +-
 arch/x86/kvm/x86_emulate.c             |    5 ++++-
 2 files changed, 5 insertions(+), 2 deletions(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 arch/x86/include/asm/kvm_x86_emulate.h |    2 +-
 arch/x86/kvm/x86_emulate.c             |    5 ++++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/kvm_x86_emulate.h b/arch/x86/include/asm/kvm_x86_emulate.h
index b7ed2c4..7c18e12 100644
--- a/arch/x86/include/asm/kvm_x86_emulate.h
+++ b/arch/x86/include/asm/kvm_x86_emulate.h
@@ -129,7 +129,7 @@ struct decode_cache {
 	u8 seg_override;
 	unsigned int d;
 	unsigned long regs[NR_VCPU_REGS];
-	unsigned long eip;
+	unsigned long eip, eip_orig;
 	/* modrm */
 	u8 modrm;
 	u8 modrm_mod;
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
index 20f6062..cbc4e60 100644
--- a/arch/x86/kvm/x86_emulate.c
+++ b/arch/x86/kvm/x86_emulate.c
@@ -603,6 +603,9 @@ static int do_insn_fetch(struct x86_emulate_ctxt *ctxt,
 {
 	int rc = 0;
 
+	/* x86 instructions are limited to 15 bytes. */
+	if (eip + size - ctxt->decode.eip_orig > 15)
+		return X86EMUL_UNHANDLEABLE;
 	eip += ctxt->cs_base;
 	while (size--) {
 		rc = do_fetch_insn_byte(ctxt, ops, eip++, dest++);
@@ -861,7 +864,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 	/* Shadow copy of register state. Committed on successful emulation. */
 
 	memset(c, 0, sizeof(struct decode_cache));
-	c->eip = kvm_rip_read(ctxt->vcpu);
+	c->eip = c->eip_orig = kvm_rip_read(ctxt->vcpu);
 	ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS);
 	memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
 
-- 
1.6.3.rc4.29.g8146