Message ID | 20200227185125.650784-9-cascardo@canonical.com |
---|---|
State | New |
Headers | show |
Series | None | expand |
This patch doesn't apply to Bionic On 2020-02-27 15:51:22 , Thadeu Lima de Souza Cascardo wrote: > From: Oliver Upton <oupton@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@google.com> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@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@lists.ubuntu.com > https://lists.ubuntu.com/mailman/listinfo/kernel-team
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@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@google.com> > > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> > > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > > Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@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@lists.ubuntu.com > > https://lists.ubuntu.com/mailman/listinfo/kernel-team
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; }