Ack: [CVE-2015-0239][Utopic][Trusty] KVM: x86: SYSENTER emulation is broken

Brad Figg brad.figg at canonical.com
Wed Jan 28 15:10:44 UTC 2015


On Mon, Jan 26, 2015 at 03:09:20PM +0000, Luis Henriques wrote:
> From: Nadav Amit <namit at cs.technion.ac.il>
> 
> 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.
> 
> Cc: stable at vger.linux.org
> Signed-off-by: Nadav Amit <namit at cs.technion.ac.il>
> Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
> (backported from commit f3747379accba8e95d70cec0eae0582c8c182050)
> CVE-2015-0239
> BugLink: http://bugs.launchpad.net/bugs/1414651
> Signed-off-by: Luis Henriques <luis.henriques at canonical.com>
> ---
>  arch/x86/kvm/emulate.c | 27 ++++++++-------------------
>  1 file changed, 8 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index 4426db1a0548..26ce877cdac7 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -2311,7 +2311,7 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt)
>  	 * 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);
>  
> @@ -2324,25 +2324,13 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt)
>  	setup_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;
>  	}
> @@ -2351,10 +2339,11 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt)
>  	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;
>  }
> 
> -- 
> kernel-team mailing list
> kernel-team at lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team

Looks like a good backport.

-- 
Brad Figg brad.figg at canonical.com http://www.canonical.com




More information about the kernel-team mailing list