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

Khaled Elmously khalid.elmously at canonical.com
Fri Feb 28 04:00:56 UTC 2020


This patch doesn't apply to 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