Skip to content

Commit 087e152

Browse files
committed
KVM: Set file_operations.owner appropriately for all such structures
Set .owner for all KVM-owned filed types so that the KVM module is pinned until any files with callbacks back into KVM are completely freed. Using "struct kvm" as a proxy for the module, i.e. keeping KVM-the-module alive while there are active VMs, doesn't provide full protection. Userspace can invoke delete_module() the instant the last reference to KVM is put. If KVM itself puts the last reference, e.g. via kvm_destroy_vm(), then it's possible for KVM to be preempted and deleted/unloaded before KVM fully exits, e.g. when the task running kvm_destroy_vm() is scheduled back in, it will jump to a code page that is no longer mapped. Note, file types that can call into sub-module code, e.g. kvm-intel.ko or kvm-amd.ko on x86, must use the module pointer passed to kvm_init(), not THIS_MODULE (which points at kvm.ko). KVM assumes that if /dev/kvm is reachable, e.g. VMs are active, then the vendor module is loaded. To reduce the probability of forgetting to set .owner entirely, use THIS_MODULE for stats files where KVM does not call back into vendor code. This reverts commit 70375c2, and fixes several other file types that have been buggy since their introduction. Fixes: 70375c2 ("Revert "KVM: set owner of cpu and vm file operations"") Fixes: 3bcd066 ("KVM: X86: Introduce mmu_rmaps_stat per-vm debugfs file") Reported-by: Al Viro <viro@zeniv.linux.org.uk> Link: https://lore.kernel.org/all/20231010003746.GN800259@ZenIV Link: https://lore.kernel.org/r/20231018204624.1905300-2-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 547c919 commit 087e152

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

arch/x86/kvm/debugfs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ static int kvm_mmu_rmaps_stat_release(struct inode *inode, struct file *file)
182182
}
183183

184184
static const struct file_operations mmu_rmaps_stat_fops = {
185+
.owner = THIS_MODULE,
185186
.open = kvm_mmu_rmaps_stat_open,
186187
.read = seq_read,
187188
.llseek = seq_lseek,

virt/kvm/kvm_main.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3887,7 +3887,7 @@ static int kvm_vcpu_release(struct inode *inode, struct file *filp)
38873887
return 0;
38883888
}
38893889

3890-
static const struct file_operations kvm_vcpu_fops = {
3890+
static struct file_operations kvm_vcpu_fops = {
38913891
.release = kvm_vcpu_release,
38923892
.unlocked_ioctl = kvm_vcpu_ioctl,
38933893
.mmap = kvm_vcpu_mmap,
@@ -4081,6 +4081,7 @@ static int kvm_vcpu_stats_release(struct inode *inode, struct file *file)
40814081
}
40824082

40834083
static const struct file_operations kvm_vcpu_stats_fops = {
4084+
.owner = THIS_MODULE,
40844085
.read = kvm_vcpu_stats_read,
40854086
.release = kvm_vcpu_stats_release,
40864087
.llseek = noop_llseek,
@@ -4431,7 +4432,7 @@ static int kvm_device_release(struct inode *inode, struct file *filp)
44314432
return 0;
44324433
}
44334434

4434-
static const struct file_operations kvm_device_fops = {
4435+
static struct file_operations kvm_device_fops = {
44354436
.unlocked_ioctl = kvm_device_ioctl,
44364437
.release = kvm_device_release,
44374438
KVM_COMPAT(kvm_device_ioctl),
@@ -4759,6 +4760,7 @@ static int kvm_vm_stats_release(struct inode *inode, struct file *file)
47594760
}
47604761

47614762
static const struct file_operations kvm_vm_stats_fops = {
4763+
.owner = THIS_MODULE,
47624764
.read = kvm_vm_stats_read,
47634765
.release = kvm_vm_stats_release,
47644766
.llseek = noop_llseek,
@@ -5060,7 +5062,7 @@ static long kvm_vm_compat_ioctl(struct file *filp,
50605062
}
50615063
#endif
50625064

5063-
static const struct file_operations kvm_vm_fops = {
5065+
static struct file_operations kvm_vm_fops = {
50645066
.release = kvm_vm_release,
50655067
.unlocked_ioctl = kvm_vm_ioctl,
50665068
.llseek = noop_llseek,
@@ -6095,6 +6097,9 @@ int kvm_init(unsigned vcpu_size, unsigned vcpu_align, struct module *module)
60956097
goto err_async_pf;
60966098

60976099
kvm_chardev_ops.owner = module;
6100+
kvm_vm_fops.owner = module;
6101+
kvm_vcpu_fops.owner = module;
6102+
kvm_device_fops.owner = module;
60986103

60996104
kvm_preempt_ops.sched_in = kvm_sched_in;
61006105
kvm_preempt_ops.sched_out = kvm_sched_out;

0 commit comments

Comments
 (0)