| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
- From: Jann Horn <[email protected]>
- 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: [email protected]
- Signed-off-by: Jann Horn <[email protected]>
- Signed-off-by: Paolo Bonzini <[email protected]>
- CVE-2019-6974
- (cherry picked from commit cfa39381173d5f969daf43582c95ad679189cbc9)
- Signed-off-by: Tyler Hicks <[email protected]>
- Signed-off-by: Thomas Lamprecht <[email protected]>
- ---
- 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;
- }
|