mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 14:14:24 +08:00
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 commit70375c2d8f
, and fixes several other file types that have been buggy since their introduction. Fixes:70375c2d8f
("Revert "KVM: set owner of cpu and vm file operations"") Fixes:3bcd0662d6
("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>
This commit is contained in:
parent
547c91929f
commit
087e15206d
@ -182,6 +182,7 @@ static int kvm_mmu_rmaps_stat_release(struct inode *inode, struct file *file)
|
||||
}
|
||||
|
||||
static const struct file_operations mmu_rmaps_stat_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = kvm_mmu_rmaps_stat_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
|
@ -3887,7 +3887,7 @@ static int kvm_vcpu_release(struct inode *inode, struct file *filp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations kvm_vcpu_fops = {
|
||||
static struct file_operations kvm_vcpu_fops = {
|
||||
.release = kvm_vcpu_release,
|
||||
.unlocked_ioctl = kvm_vcpu_ioctl,
|
||||
.mmap = kvm_vcpu_mmap,
|
||||
@ -4081,6 +4081,7 @@ static int kvm_vcpu_stats_release(struct inode *inode, struct file *file)
|
||||
}
|
||||
|
||||
static const struct file_operations kvm_vcpu_stats_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = kvm_vcpu_stats_read,
|
||||
.release = kvm_vcpu_stats_release,
|
||||
.llseek = noop_llseek,
|
||||
@ -4431,7 +4432,7 @@ static int kvm_device_release(struct inode *inode, struct file *filp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations kvm_device_fops = {
|
||||
static struct file_operations kvm_device_fops = {
|
||||
.unlocked_ioctl = kvm_device_ioctl,
|
||||
.release = kvm_device_release,
|
||||
KVM_COMPAT(kvm_device_ioctl),
|
||||
@ -4759,6 +4760,7 @@ static int kvm_vm_stats_release(struct inode *inode, struct file *file)
|
||||
}
|
||||
|
||||
static const struct file_operations kvm_vm_stats_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = kvm_vm_stats_read,
|
||||
.release = kvm_vm_stats_release,
|
||||
.llseek = noop_llseek,
|
||||
@ -5060,7 +5062,7 @@ static long kvm_vm_compat_ioctl(struct file *filp,
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct file_operations kvm_vm_fops = {
|
||||
static struct file_operations kvm_vm_fops = {
|
||||
.release = kvm_vm_release,
|
||||
.unlocked_ioctl = kvm_vm_ioctl,
|
||||
.llseek = noop_llseek,
|
||||
@ -6095,6 +6097,9 @@ int kvm_init(unsigned vcpu_size, unsigned vcpu_align, struct module *module)
|
||||
goto err_async_pf;
|
||||
|
||||
kvm_chardev_ops.owner = module;
|
||||
kvm_vm_fops.owner = module;
|
||||
kvm_vcpu_fops.owner = module;
|
||||
kvm_device_fops.owner = module;
|
||||
|
||||
kvm_preempt_ops.sched_in = kvm_sched_in;
|
||||
kvm_preempt_ops.sched_out = kvm_sched_out;
|
||||
|
Loading…
Reference in New Issue
Block a user