Skip to content

Commit

Permalink
kvm: fix kvm_ioctl_create_device() reference counting (CVE-2019-6974)
Browse files Browse the repository at this point in the history
commit cfa3938 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: 852b6d5 ("kvm: add device control API")
Cc: [email protected]
Signed-off-by: Jann Horn <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
thejh authored and gregkh committed Feb 23, 2019
1 parent f5aebe7 commit bc4db52
Showing 1 changed file with 2 additions and 1 deletion.
3 changes: 2 additions & 1 deletion virt/kvm/kvm_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2711,14 +2711,15 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
return ret;
}

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);
ops->destroy(dev);
return ret;
}

list_add(&dev->vm_node, &kvm->devices);
kvm_get_kvm(kvm);
cd->fd = ret;
return 0;
}
Expand Down

0 comments on commit bc4db52

Please sign in to comment.