lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Fri, 22 Mar 2019 05:20:18 +0000 From: Ben Hutchings <ben@...adent.org.uk> To: linux-kernel@...r.kernel.org, stable@...r.kernel.org CC: akpm@...ux-foundation.org, Denis Kirjanov <kda@...ux-powerpc.org>, "Paolo Bonzini" <pbonzini@...hat.com>, "Jann Horn" <jannh@...gle.com> Subject: [PATCH 3.16 14/16] kvm: fix kvm_ioctl_create_device() reference counting (CVE-2019-6974) 3.16.64-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Jann Horn <jannh@...gle.com> 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@...gle.com> Signed-off-by: Paolo Bonzini <pbonzini@...hat.com> Signed-off-by: Ben Hutchings <ben@...adent.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; }
Powered by blists - more mailing lists