[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