Message ID | 20170425175718.25904-2-apw@canonical.com |
---|---|
State | New |
Headers | show |
On 25/04/17 18:57, Andy Whitcroft wrote: > [ 1046.384746] BUG: unable to handle kernel NULL pointer dereference at 0000000000000070 > [ 1046.387386] IP: [<ffffffffa05b3ca3>] handle_invept+0x123/0x170 [kvm_intel] > [ 1046.389577] PGD 0 > [ 1046.390273] Oops: 0000 [#1] SMP > > (tested with Ubuntu 14.04 linux-image-3.13.0-113-generic) > > The host KVM touches NULL pointer (vmx->nested.current_vmcs12) when a > (crafted or buggy) guest issues a single-context INVEPT instruction > *without* VMPTRLD like this: > > kvm_cpu_vmxon(phys_addr); > ept_sync_context(0); > > (requires nested EPT; full PoC module code attached) > > This flaw was introduced in commit bfd0a56b90005f8c8a004baf407ad90045c2b11e > (nEPT: Nested INVEPT) and removed in 4b855078601fc422dbac3059f2215e776f49780f > (KVM: nVMX: Don't advertise single context invalidation for invept). > > Original-Patch-By: Minoura Makoto <minoura@valinux.co.jp> > CVE-2017-8106 > BugLink: http://bugs.launchpad.net/bugs/1678676 > Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=195167 > Reviewed-by: Tyler Hicks <tyhicks@canonical.com> > Signed-off-by: Andy Whitcroft <apw@canonical.com> > --- > arch/x86/kvm/vmx.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c > index 6658c0bf3666..57eae7732493 100644 > --- a/arch/x86/kvm/vmx.c > +++ b/arch/x86/kvm/vmx.c > @@ -6386,6 +6386,8 @@ static int handle_invept(struct kvm_vcpu *vcpu) > > switch (type) { > case VMX_EPT_EXTENT_CONTEXT: > + if (to_vmx(vcpu)->nested.current_vmptr == -1ull) > + break; > if ((operand.eptp & eptp_mask) != > (nested_ept_get_cr3(vcpu) & eptp_mask)) > break; > Has been tested, looks OK to me. Acked-by: Colin Ian King <colin.king@canonical.com>
Applied to trusty master-next branch. Thanks. Cascardo.
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 6658c0bf3666..57eae7732493 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -6386,6 +6386,8 @@ static int handle_invept(struct kvm_vcpu *vcpu) switch (type) { case VMX_EPT_EXTENT_CONTEXT: + if (to_vmx(vcpu)->nested.current_vmptr == -1ull) + break; if ((operand.eptp & eptp_mask) != (nested_ept_get_cr3(vcpu) & eptp_mask)) break;