[Bionic 4/4] KVM: nVMX: Check IO instruction VM-exit conditions

Thadeu Lima de Souza Cascardo cascardo at canonical.com
Fri Feb 28 10:37:47 UTC 2020


On Thu, Feb 27, 2020 at 11:00:56PM -0500, Khaled Elmously wrote:
> This patch doesn't apply to Bionic
> 

~/bionic$ git reset --hard 22000e3c4bde
HEAD is now at 22000e3c4bde UBUNTU: Ubuntu-4.15.0-90.91
~/bionic$ git am ~/tmp/2732.mbox
Applying: KVM: x86: emulate RDPID
Applying: KVM: nVMX: Don't emulate instructions in guest mode
Applying: KVM: nVMX: Refactor IO bitmap checks into helper function
Applying: KVM: nVMX: Check IO instruction VM-exit conditions
~/bionic$

> On 2020-02-27 15:51:22 , Thadeu Lima de Souza Cascardo wrote:
> > From: Oliver Upton <oupton at google.com>
> > 
> > CVE-2020-2732
> > 
> > commit 35a571346a94fb93b5b3b6a599675ef3384bc75c upstream.
> > 
> > Consult the 'unconditional IO exiting' and 'use IO bitmaps' VM-execution
> > controls when checking instruction interception. If the 'use IO bitmaps'
> > VM-execution control is 1, check the instruction access against the IO
> > bitmaps to determine if the instruction causes a VM-exit.
> > 
> > Signed-off-by: Oliver Upton <oupton at google.com>
> > Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
> > Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> > Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo at canonical.com>
> > ---
> >  arch/x86/kvm/vmx.c | 59 ++++++++++++++++++++++++++++++++++++++++------
> >  1 file changed, 52 insertions(+), 7 deletions(-)
> > 
> > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
> > index 6a2da0068ae2..3728ecea95e4 100644
> > --- a/arch/x86/kvm/vmx.c
> > +++ b/arch/x86/kvm/vmx.c
> > @@ -5004,7 +5004,7 @@ static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu,
> >  				       struct vmcs12 *vmcs12)
> >  {
> >  	unsigned long exit_qualification;
> > -	unsigned int port;
> > +	unsigned short port;
> >  	int size;
> >  
> >  	if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS))
> > @@ -12342,6 +12342,39 @@ static void nested_vmx_entry_failure(struct kvm_vcpu *vcpu,
> >  		to_vmx(vcpu)->nested.sync_shadow_vmcs = true;
> >  }
> >  
> > +static int vmx_check_intercept_io(struct kvm_vcpu *vcpu,
> > +				  struct x86_instruction_info *info)
> > +{
> > +	struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
> > +	unsigned short port;
> > +	bool intercept;
> > +	int size;
> > +
> > +	if (info->intercept == x86_intercept_in ||
> > +	    info->intercept == x86_intercept_ins) {
> > +		port = info->src_val;
> > +		size = info->dst_bytes;
> > +	} else {
> > +		port = info->dst_val;
> > +		size = info->src_bytes;
> > +	}
> > +
> > +	/*
> > +	 * If the 'use IO bitmaps' VM-execution control is 0, IO instruction
> > +	 * VM-exits depend on the 'unconditional IO exiting' VM-execution
> > +	 * control.
> > +	 *
> > +	 * Otherwise, IO instruction VM-exits are controlled by the IO bitmaps.
> > +	 */
> > +	if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS))
> > +		intercept = nested_cpu_has(vmcs12,
> > +					   CPU_BASED_UNCOND_IO_EXITING);
> > +	else
> > +		intercept = nested_vmx_check_io_bitmaps(vcpu, port, size);
> > +
> > +	return intercept ? X86EMUL_UNHANDLEABLE : X86EMUL_CONTINUE;
> > +}
> > +
> >  static int vmx_check_intercept(struct kvm_vcpu *vcpu,
> >  			       struct x86_instruction_info *info,
> >  			       enum x86_intercept_stage stage)
> > @@ -12349,18 +12382,30 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu,
> >  	struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
> >  	struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt;
> >  
> > +	switch (info->intercept) {
> >  	/*
> >  	 * RDPID causes #UD if disabled through secondary execution controls.
> >  	 * Because it is marked as EmulateOnUD, we need to intercept it here.
> >  	 */
> > -	if (info->intercept == x86_intercept_rdtscp &&
> > -	    !nested_cpu_has2(vmcs12, SECONDARY_EXEC_RDTSCP)) {
> > -		ctxt->exception.vector = UD_VECTOR;
> > -		ctxt->exception.error_code_valid = false;
> > -		return X86EMUL_PROPAGATE_FAULT;
> > -	}
> > +	case x86_intercept_rdtscp:
> > +		if (!nested_cpu_has2(vmcs12, SECONDARY_EXEC_RDTSCP)) {
> > +			ctxt->exception.vector = UD_VECTOR;
> > +			ctxt->exception.error_code_valid = false;
> > +			return X86EMUL_PROPAGATE_FAULT;
> > +		}
> > +		break;
> > +
> > +	case x86_intercept_in:
> > +	case x86_intercept_ins:
> > +	case x86_intercept_out:
> > +	case x86_intercept_outs:
> > +		return vmx_check_intercept_io(vcpu, info);
> >  
> >  	/* TODO: check more intercepts... */
> > +	default:
> > +		break;
> > +	}
> > +
> >  	return X86EMUL_UNHANDLEABLE;
> >  }
> >  
> > -- 
> > 2.25.1
> > 
> > 
> > -- 
> > kernel-team mailing list
> > kernel-team at lists.ubuntu.com
> > https://lists.ubuntu.com/mailman/listinfo/kernel-team



More information about the kernel-team mailing list