[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