Patch "KVM: x86: SYSENTER emulation is broken" has been added to the 3.10-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
KVM: x86: SYSENTER emulation is broken
to the 3.10-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
kvm-x86-sysenter-emulation-is-broken.patch
and it can be found in the queue-3.10 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
f3747379accba8e95d70cec0eae0582c8c182050Mon Sep 17 00:00:00 2001
From: Nadav Amit <[email protected]>
Date: Thu, 1 Jan 2015 23:11:11 +0200
Subject: KVM: x86: SYSENTER emulation is broken
From: Nadav Amit <[email protected]>
commit f3747379accba8e95d70cec0eae0582c8c182050 upstream.
SYSENTER emulation is broken in several ways:
1. It misses the case of 16-bit code segments completely (CVE-2015-0239).
2. MSR_IA32_SYSENTER_CS is checked in 64-bit mode incorrectly (bits 0 and 1 can still be set without causing #GP).
3. MSR_IA32_SYSENTER_EIP and MSR_IA32_SYSENTER_ESP are not masked in legacy-mode.
4. There is some unneeded code.
Fix it.
[zhangzhiqiang: backport to 3.10:
- adjust context
- in 3.10 context "ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF)" is replaced by "ctxt->eflags &= ~(EFLG_VM | EFLG_IF)" in upstream, which was changed by another commit.
- After the above adjustments, becomes same to the original patch:
https://github.com/torvalds/linux/commit/f3747379accba8e95d70cec0eae0582c8c182050
]
--- arch/x86/kvm/emulate.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-)
arch/x86/kvm/emulate.c +8 -19
@@ -2450,7 +2450,7 @@ static int em_sysenter(struct x86_emulat* Not recognized on AMD in compat mode (but is recognized in legacy * mode). */ -if ((ctxt->mode ==X86EMUL_MODE_PROT32 ) && (efer &EFER_LMA ) +if ((ctxt->mode !=X86EMUL_MODE_PROT64 ) && (efer &EFER_LMA ) && !vendor_intel (ctxt))return emulate_ud (ctxt);
@@ -2463,25 +2463,13 @@ static int em_sysenter(struct x86_emulatsetup_syscalls_segments (ctxt, &cs, &ss); ops->get_msr (ctxt,MSR_IA32_SYSENTER_CS , &msr_data); -switch (ctxt->mode) { -case X86EMUL_MODE_PROT32 : -if ((msr_data &0xfffc ) ==0x0 ) -return emulate_gp (ctxt,0 ); -break ; -case X86EMUL_MODE_PROT64 : -if (msr_data ==0x0 ) -return emulate_gp (ctxt,0 ); -break ; -default : -break ; - } +if ((msr_data &0xfffc ) ==0x0 ) +return emulate_gp (ctxt,0 ); ctxt->eflags &= ~(EFLG_VM |EFLG_IF |EFLG_RF ); - cs_sel = (u16 )msr_data; - cs_sel &= ~SELECTOR_RPL_MASK ; + cs_sel = (u16 )msr_data & ~SELECTOR_RPL_MASK ; ss_sel = cs_sel +8 ; - ss_sel &= ~SELECTOR_RPL_MASK ; -if (ctxt->mode ==X86EMUL_MODE_PROT64 || (efer &EFER_LMA )) { +if (efer &EFER_LMA ) { cs.d =0 ; cs.l =1 ; }
@@ -2490,10 +2478,11 @@ static int em_sysenter(struct x86_emulat ops->set_segment (ctxt, ss_sel, &ss,0 ,VCPU_SREG_SS ); ops->get_msr (ctxt,MSR_IA32_SYSENTER_EIP , &msr_data); - ctxt->_eip = msr_data; + ctxt->_eip = (efer &EFER_LMA ) ? msr_data : (u32 )msr_data; ops->get_msr (ctxt,MSR_IA32_SYSENTER_ESP , &msr_data); - *reg_write (ctxt,VCPU_REGS_RSP ) = msr_data; + *reg_write (ctxt,VCPU_REGS_RSP ) = (efer &EFER_LMA ) ? msr_data : + (u32 )msr_data;return X86EMUL_CONTINUE ; }
Patches currently in stable-queue which might be from [email protected] are
queue-3.10/kvm-x86-sysenter-emulation-is-broken.patch