| From: Jann Horn <jannh@google.com> |
| Date: Sat, 26 Jan 2019 01:54:33 +0100 |
| Subject: kvm: fix kvm_ioctl_create_device() reference counting (CVE-2019-6974) |
| |
| commit cfa39381173d5f969daf43582c95ad679189cbc9 upstream. |
| |
| 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") |
| Signed-off-by: Jann Horn <jannh@google.com> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| virt/kvm/kvm_main.c | 3 ++- |
| 1 file changed, 2 insertions(+), 1 deletion(-) |
| |
| --- a/virt/kvm/kvm_main.c |
| +++ b/virt/kvm/kvm_main.c |
| @@ -2340,8 +2340,10 @@ static int kvm_ioctl_create_device(struc |
| 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); |
| @@ -2349,7 +2351,6 @@ static int kvm_ioctl_create_device(struc |
| return ret; |
| } |
| |
| - kvm_get_kvm(kvm); |
| cd->fd = ret; |
| return 0; |
| } |