diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2018-06-17 05:16:21 -0400 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2018-06-21 12:17:50 -0400 |
commit | 7ddfd3e0df29106c728dda2a6bd6591ee43a4e3c (patch) | |
tree | 881292b233bf620c55ae432583778e59a18f4591 /virt | |
parent | 47a91b7232fa25abc7e0b7fc1c69ae4f81061594 (diff) |
KVM: Enforce error in ioctl for compat tasks when !KVM_COMPAT
The current behaviour of the compat ioctls is a bit odd.
We provide a compat_ioctl method when KVM_COMPAT is set, and NULL
otherwise. But NULL means that the normal, non-compat ioctl should
be used directly for compat tasks, and there is no way to actually
prevent a compat task from issueing KVM ioctls.
This patch changes this behaviour, by always registering a compat_ioctl
method, even if KVM_COMPAT is not selected. In that case, the callback
will always return -EINVAL.
Fixes: de8e5d744051568c8aad ("KVM: Disable compat ioctl for s390")
Reported-by: Mark Rutland <mark.rutland@arm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Acked-by: Radim Krčmář <rkrcmar@redhat.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/kvm_main.c | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index ada21f47f22b..8b47507faab5 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -116,6 +116,11 @@ static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl, | |||
116 | #ifdef CONFIG_KVM_COMPAT | 116 | #ifdef CONFIG_KVM_COMPAT |
117 | static long kvm_vcpu_compat_ioctl(struct file *file, unsigned int ioctl, | 117 | static long kvm_vcpu_compat_ioctl(struct file *file, unsigned int ioctl, |
118 | unsigned long arg); | 118 | unsigned long arg); |
119 | #define KVM_COMPAT(c) .compat_ioctl = (c) | ||
120 | #else | ||
121 | static long kvm_no_compat_ioctl(struct file *file, unsigned int ioctl, | ||
122 | unsigned long arg) { return -EINVAL; } | ||
123 | #define KVM_COMPAT(c) .compat_ioctl = kvm_no_compat_ioctl | ||
119 | #endif | 124 | #endif |
120 | static int hardware_enable_all(void); | 125 | static int hardware_enable_all(void); |
121 | static void hardware_disable_all(void); | 126 | static void hardware_disable_all(void); |
@@ -2396,11 +2401,9 @@ static int kvm_vcpu_release(struct inode *inode, struct file *filp) | |||
2396 | static struct file_operations kvm_vcpu_fops = { | 2401 | static struct file_operations kvm_vcpu_fops = { |
2397 | .release = kvm_vcpu_release, | 2402 | .release = kvm_vcpu_release, |
2398 | .unlocked_ioctl = kvm_vcpu_ioctl, | 2403 | .unlocked_ioctl = kvm_vcpu_ioctl, |
2399 | #ifdef CONFIG_KVM_COMPAT | ||
2400 | .compat_ioctl = kvm_vcpu_compat_ioctl, | ||
2401 | #endif | ||
2402 | .mmap = kvm_vcpu_mmap, | 2404 | .mmap = kvm_vcpu_mmap, |
2403 | .llseek = noop_llseek, | 2405 | .llseek = noop_llseek, |
2406 | KVM_COMPAT(kvm_vcpu_compat_ioctl), | ||
2404 | }; | 2407 | }; |
2405 | 2408 | ||
2406 | /* | 2409 | /* |
@@ -2824,10 +2827,8 @@ static int kvm_device_release(struct inode *inode, struct file *filp) | |||
2824 | 2827 | ||
2825 | static const struct file_operations kvm_device_fops = { | 2828 | static const struct file_operations kvm_device_fops = { |
2826 | .unlocked_ioctl = kvm_device_ioctl, | 2829 | .unlocked_ioctl = kvm_device_ioctl, |
2827 | #ifdef CONFIG_KVM_COMPAT | ||
2828 | .compat_ioctl = kvm_device_ioctl, | ||
2829 | #endif | ||
2830 | .release = kvm_device_release, | 2830 | .release = kvm_device_release, |
2831 | KVM_COMPAT(kvm_device_ioctl), | ||
2831 | }; | 2832 | }; |
2832 | 2833 | ||
2833 | struct kvm_device *kvm_device_from_filp(struct file *filp) | 2834 | struct kvm_device *kvm_device_from_filp(struct file *filp) |
@@ -3165,10 +3166,8 @@ static long kvm_vm_compat_ioctl(struct file *filp, | |||
3165 | static struct file_operations kvm_vm_fops = { | 3166 | static struct file_operations kvm_vm_fops = { |
3166 | .release = kvm_vm_release, | 3167 | .release = kvm_vm_release, |
3167 | .unlocked_ioctl = kvm_vm_ioctl, | 3168 | .unlocked_ioctl = kvm_vm_ioctl, |
3168 | #ifdef CONFIG_KVM_COMPAT | ||
3169 | .compat_ioctl = kvm_vm_compat_ioctl, | ||
3170 | #endif | ||
3171 | .llseek = noop_llseek, | 3169 | .llseek = noop_llseek, |
3170 | KVM_COMPAT(kvm_vm_compat_ioctl), | ||
3172 | }; | 3171 | }; |
3173 | 3172 | ||
3174 | static int kvm_dev_ioctl_create_vm(unsigned long type) | 3173 | static int kvm_dev_ioctl_create_vm(unsigned long type) |
@@ -3259,8 +3258,8 @@ out: | |||
3259 | 3258 | ||
3260 | static struct file_operations kvm_chardev_ops = { | 3259 | static struct file_operations kvm_chardev_ops = { |
3261 | .unlocked_ioctl = kvm_dev_ioctl, | 3260 | .unlocked_ioctl = kvm_dev_ioctl, |
3262 | .compat_ioctl = kvm_dev_ioctl, | ||
3263 | .llseek = noop_llseek, | 3261 | .llseek = noop_llseek, |
3262 | KVM_COMPAT(kvm_dev_ioctl), | ||
3264 | }; | 3263 | }; |
3265 | 3264 | ||
3266 | static struct miscdevice kvm_dev = { | 3265 | static struct miscdevice kvm_dev = { |