4ac9db0e26
- CVE-2014-3611 kvm: PIT timer race condition (rhbz 1144878 1156537) - CVE-2014-3646 kvm: vmx: invvpid vm exit not handled (rhbz 1144825 1156534) - CVE-2014-8369 kvm: excessive pages un-pinning in kvm_iommu_map error path (rhbz 1156518 1156522) - CVE-2014-8480 CVE-2014-8481 kvm: NULL pointer dereference during rip relative instruction emulation (rhbz 1156615 1156616)
65 lines
1.7 KiB
Diff
65 lines
1.7 KiB
Diff
From: Nadav Amit <namit@cs.technion.ac.il>
|
|
Date: Fri, 24 Oct 2014 17:07:15 +0200
|
|
Subject: [PATCH] KVM: x86: Fix wrong masking on relative jump/call
|
|
|
|
Relative jumps and calls do the masking according to the operand size, and not
|
|
according to the address size as the KVM emulator does today.
|
|
|
|
This patch fixes KVM behavior.
|
|
|
|
Cc: stable@vger.kernel.org
|
|
Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
|
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
---
|
|
arch/x86/kvm/emulate.c | 27 ++++++++++++++++++++++-----
|
|
1 file changed, 22 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
|
|
index a46207a05835..047698974799 100644
|
|
--- a/arch/x86/kvm/emulate.c
|
|
+++ b/arch/x86/kvm/emulate.c
|
|
@@ -504,11 +504,6 @@ static void rsp_increment(struct x86_emulate_ctxt *ctxt, int inc)
|
|
masked_increment(reg_rmw(ctxt, VCPU_REGS_RSP), stack_mask(ctxt), inc);
|
|
}
|
|
|
|
-static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
|
|
-{
|
|
- register_address_increment(ctxt, &ctxt->_eip, rel);
|
|
-}
|
|
-
|
|
static u32 desc_limit_scaled(struct desc_struct *desc)
|
|
{
|
|
u32 limit = get_desc_limit(desc);
|
|
@@ -569,6 +564,28 @@ static int emulate_nm(struct x86_emulate_ctxt *ctxt)
|
|
return emulate_exception(ctxt, NM_VECTOR, 0, false);
|
|
}
|
|
|
|
+static inline void assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst)
|
|
+{
|
|
+ switch (ctxt->op_bytes) {
|
|
+ case 2:
|
|
+ ctxt->_eip = (u16)dst;
|
|
+ break;
|
|
+ case 4:
|
|
+ ctxt->_eip = (u32)dst;
|
|
+ break;
|
|
+ case 8:
|
|
+ ctxt->_eip = dst;
|
|
+ break;
|
|
+ default:
|
|
+ WARN(1, "unsupported eip assignment size\n");
|
|
+ }
|
|
+}
|
|
+
|
|
+static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel)
|
|
+{
|
|
+ assign_eip_near(ctxt, ctxt->_eip + rel);
|
|
+}
|
|
+
|
|
static u16 get_segment_selector(struct x86_emulate_ctxt *ctxt, unsigned seg)
|
|
{
|
|
u16 selector;
|
|
--
|
|
1.9.3
|
|
|