backport fixes for multiple KVM vulnerabilities
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
parent
cf6ea5cf34
commit
4e6465dfa5
@ -0,0 +1,60 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jann Horn <jannh@google.com>
|
||||
Date: Mon, 25 Feb 2019 11:48:05 +0000
|
||||
Subject: [PATCH] kvm: fix kvm_ioctl_create_device() reference counting
|
||||
(CVE-2019-6974)
|
||||
|
||||
kvm_ioctl_create_device() does the following:
|
||||
|
||||
1. creates a device that holds a reference to the VM object (with a borrowed
|
||||
reference, the VM's refcount has not been bumped yet)
|
||||
2. initializes the device
|
||||
3. transfers the reference to the device to the caller's file descriptor table
|
||||
4. calls kvm_get_kvm() to turn the borrowed reference to the VM into a real
|
||||
reference
|
||||
|
||||
The ownership transfer in step 3 must not happen before the reference to the VM
|
||||
becomes a proper, non-borrowed reference, which only happens in step 4.
|
||||
After step 3, an attacker can close the file descriptor and drop the borrowed
|
||||
reference, which can cause the refcount of the kvm object to drop to zero.
|
||||
|
||||
This means that we need to grab a reference for the device before
|
||||
anon_inode_getfd(), otherwise the VM can disappear from under us.
|
||||
|
||||
Fixes: 852b6d57dc7f ("kvm: add device control API")
|
||||
Cc: stable@kernel.org
|
||||
Signed-off-by: Jann Horn <jannh@google.com>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
|
||||
CVE-2019-6974
|
||||
|
||||
(cherry picked from commit cfa39381173d5f969daf43582c95ad679189cbc9)
|
||||
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
---
|
||||
virt/kvm/kvm_main.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
|
||||
index 234d03abcb75..238ddbc127e1 100644
|
||||
--- a/virt/kvm/kvm_main.c
|
||||
+++ b/virt/kvm/kvm_main.c
|
||||
@@ -2908,8 +2908,10 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
|
||||
if (ops->init)
|
||||
ops->init(dev);
|
||||
|
||||
+ kvm_get_kvm(kvm);
|
||||
ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC);
|
||||
if (ret < 0) {
|
||||
+ kvm_put_kvm(kvm);
|
||||
mutex_lock(&kvm->lock);
|
||||
list_del(&dev->vm_node);
|
||||
mutex_unlock(&kvm->lock);
|
||||
@@ -2917,7 +2919,6 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
|
||||
return ret;
|
||||
}
|
||||
|
||||
- kvm_get_kvm(kvm);
|
||||
cd->fd = ret;
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Shier <pshier@google.com>
|
||||
Date: Mon, 25 Feb 2019 11:48:06 +0000
|
||||
Subject: [PATCH] KVM: nVMX: unconditionally cancel preemption timer in
|
||||
free_nested (CVE-2019-7221)
|
||||
|
||||
Bugzilla: 1671904
|
||||
|
||||
There are multiple code paths where an hrtimer may have been started to
|
||||
emulate an L1 VMX preemption timer that can result in a call to free_nested
|
||||
without an intervening L2 exit where the hrtimer is normally
|
||||
cancelled. Unconditionally cancel in free_nested to cover all cases.
|
||||
|
||||
Embargoed until Feb 7th 2019.
|
||||
|
||||
Signed-off-by: Peter Shier <pshier@google.com>
|
||||
Reported-by: Jim Mattson <jmattson@google.com>
|
||||
Reviewed-by: Jim Mattson <jmattson@google.com>
|
||||
Reported-by: Felix Wilhelm <fwilhelm@google.com>
|
||||
Cc: stable@kernel.org
|
||||
Message-Id: <20181011184646.154065-1-pshier@google.com>
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
|
||||
CVE-2019-7221
|
||||
|
||||
(backported from commit ecec76885bcfe3294685dc363fd1273df0d5d65f)
|
||||
[tyhicks: Backport to 4.18:
|
||||
- free_nested() is in arch/x86/kvm/vmx.c]
|
||||
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
---
|
||||
arch/x86/kvm/vmx.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
|
||||
index 7ade6cb125d3..37b095e7f00a 100644
|
||||
--- a/arch/x86/kvm/vmx.c
|
||||
+++ b/arch/x86/kvm/vmx.c
|
||||
@@ -7681,6 +7681,7 @@ static void free_nested(struct vcpu_vmx *vmx)
|
||||
if (!vmx->nested.vmxon && !vmx->nested.smm.vmxon)
|
||||
return;
|
||||
|
||||
+ hrtimer_cancel(&vmx->nested.preemption_timer);
|
||||
vmx->nested.vmxon = false;
|
||||
vmx->nested.smm.vmxon = false;
|
||||
free_vpid(vmx->nested.vpid02);
|
@ -0,0 +1,50 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Date: Mon, 25 Feb 2019 11:48:07 +0000
|
||||
Subject: [PATCH] KVM: x86: work around leak of uninitialized stack contents
|
||||
(CVE-2019-7222)
|
||||
|
||||
Bugzilla: 1671930
|
||||
|
||||
Emulation of certain instructions (VMXON, VMCLEAR, VMPTRLD, VMWRITE with
|
||||
memory operand, INVEPT, INVVPID) can incorrectly inject a page fault
|
||||
when passed an operand that points to an MMIO address. The page fault
|
||||
will use uninitialized kernel stack memory as the CR2 and error code.
|
||||
|
||||
The right behavior would be to abort the VM with a KVM_EXIT_INTERNAL_ERROR
|
||||
exit to userspace; however, it is not an easy fix, so for now just
|
||||
ensure that the error code and CR2 are zero.
|
||||
|
||||
Embargoed until Feb 7th 2019.
|
||||
|
||||
Reported-by: Felix Wilhelm <fwilhelm@google.com>
|
||||
Cc: stable@kernel.org
|
||||
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
|
||||
CVE-2019-7222
|
||||
|
||||
(cherry picked from commit 353c0956a618a07ba4bbe7ad00ff29fe70e8412a)
|
||||
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
---
|
||||
arch/x86/kvm/x86.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
|
||||
index b3df576413cd..13804929adce 100644
|
||||
--- a/arch/x86/kvm/x86.c
|
||||
+++ b/arch/x86/kvm/x86.c
|
||||
@@ -4632,6 +4632,13 @@ int kvm_read_guest_virt(struct kvm_vcpu *vcpu,
|
||||
{
|
||||
u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
|
||||
|
||||
+ /*
|
||||
+ * FIXME: this should call handle_emulation_failure if X86EMUL_IO_NEEDED
|
||||
+ * is returned, but our callers are not ready for that and they blindly
|
||||
+ * call kvm_inject_page_fault. Ensure that they at least do not leak
|
||||
+ * uninitialized kernel stack memory into cr2 and error code.
|
||||
+ */
|
||||
+ memset(exception, 0, sizeof(*exception));
|
||||
return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access,
|
||||
exception);
|
||||
}
|
Loading…
Reference in New Issue
Block a user