Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 66c0b394 authored by Al Viro's avatar Al Viro Committed by Avi Kivity
Browse files

KVM: kill file->f_count abuse in kvm



Use kvm own refcounting instead of playing with ->filp->f_count.
That will allow to get rid of a lot of crap in anon_inode_getfd() and
kill a race in kvm_dev_ioctl_create_vm() (file might have been closed
immediately by another thread, so ->filp might point to already freed
struct file when we get around to setting it).

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent 960b3991
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -110,7 +110,6 @@ struct kvm {
					KVM_PRIVATE_MEM_SLOTS];
					KVM_PRIVATE_MEM_SLOTS];
	struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
	struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
	struct list_head vm_list;
	struct list_head vm_list;
	struct file *filp;
	struct kvm_io_bus mmio_bus;
	struct kvm_io_bus mmio_bus;
	struct kvm_io_bus pio_bus;
	struct kvm_io_bus pio_bus;
	struct kvm_vm_stat stat;
	struct kvm_vm_stat stat;
+6 −6
Original line number Original line Diff line number Diff line
@@ -818,7 +818,7 @@ static int kvm_vcpu_release(struct inode *inode, struct file *filp)
{
{
	struct kvm_vcpu *vcpu = filp->private_data;
	struct kvm_vcpu *vcpu = filp->private_data;


	fput(vcpu->kvm->filp);
	kvm_put_kvm(vcpu->kvm);
	return 0;
	return 0;
}
}


@@ -840,9 +840,10 @@ static int create_vcpu_fd(struct kvm_vcpu *vcpu)


	r = anon_inode_getfd(&fd, &inode, &file,
	r = anon_inode_getfd(&fd, &inode, &file,
			     "kvm-vcpu", &kvm_vcpu_fops, vcpu);
			     "kvm-vcpu", &kvm_vcpu_fops, vcpu);
	if (r)
	if (r) {
		kvm_put_kvm(vcpu->kvm);
		return r;
		return r;
	atomic_inc(&vcpu->kvm->filp->f_count);
	}
	return fd;
	return fd;
}
}


@@ -877,6 +878,7 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n)
	mutex_unlock(&kvm->lock);
	mutex_unlock(&kvm->lock);


	/* Now it's all set up, let userspace reach it */
	/* Now it's all set up, let userspace reach it */
	kvm_get_kvm(kvm);
	r = create_vcpu_fd(vcpu);
	r = create_vcpu_fd(vcpu);
	if (r < 0)
	if (r < 0)
		goto unlink;
		goto unlink;
@@ -1176,12 +1178,10 @@ static int kvm_dev_ioctl_create_vm(void)
		return PTR_ERR(kvm);
		return PTR_ERR(kvm);
	r = anon_inode_getfd(&fd, &inode, &file, "kvm-vm", &kvm_vm_fops, kvm);
	r = anon_inode_getfd(&fd, &inode, &file, "kvm-vm", &kvm_vm_fops, kvm);
	if (r) {
	if (r) {
		kvm_destroy_vm(kvm);
		kvm_put_kvm(kvm);
		return r;
		return r;
	}
	}


	kvm->filp = file;

	return fd;
	return fd;
}
}