]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/gvt: Improve intel_vgpu_ioctl hdr error handling
authorJonathan Cavitt <jonathan.cavitt@intel.com>
Tue, 23 Sep 2025 21:23:33 +0000 (21:23 +0000)
committerAndi Shyti <andi.shyti@linux.intel.com>
Thu, 25 Sep 2025 22:27:54 +0000 (00:27 +0200)
Add error handling for the following VFIO_DEVICE_SET_IRQS cases with
respect to the hdr struct:

- More than one VFIO_IRQ_DATA_TYPE_MASK flag is set in hdr.flags
- More than one VFIO_IRQ_ACTION_TYPE_MASK flag is set in hdr.flags
- hdr.count is not specified

Note that since hdr.count != 0, data_size != 0 is guaranteed unless
vfio_set_irqs_validate_and_prepare fails and returns an error.  So, we
no longer need to check data_size before running memdup_user because
checking the return value of the function is sufficient.

v2: Use correct name for mask

v3: Use is_power_of_2 over hweight32 as it's more efficient (Andi)

Signed-off-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
Cc: Andi Shyti <andi.shyti@linux.intel.com>
Reviewed-by: Zhenyu Wang <zhenyuw.linux@gmail.com>
Reviewed-by: Krzysztof Karas <krzysztof.karas@intel.com>
Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
Link: https://lore.kernel.org/r/20250923212332.112137-2-jonathan.cavitt@intel.com
drivers/gpu/drm/i915/gvt/kvmgt.c

index 70af86d46fe8ea83e05539db178ba731e8159440..183128b846305807f7e9ef1cb792213c895e41e2 100644 (file)
@@ -1356,21 +1356,27 @@ static long intel_vgpu_ioctl(struct vfio_device *vfio_dev, unsigned int cmd,
                if (copy_from_user(&hdr, (void __user *)arg, minsz))
                        return -EFAULT;
 
+               if (!is_power_of_2(hdr.flags & VFIO_IRQ_SET_DATA_TYPE_MASK) ||
+                   !is_power_of_2(hdr.flags & VFIO_IRQ_SET_ACTION_TYPE_MASK))
+                       return -EINVAL;
+
                if (!(hdr.flags & VFIO_IRQ_SET_DATA_NONE)) {
                        int max = intel_vgpu_get_irq_count(vgpu, hdr.index);
 
+                       if (!hdr.count)
+                               return -EINVAL;
+
                        ret = vfio_set_irqs_validate_and_prepare(&hdr, max,
                                                VFIO_PCI_NUM_IRQS, &data_size);
                        if (ret) {
                                gvt_vgpu_err("intel:vfio_set_irqs_validate_and_prepare failed\n");
                                return -EINVAL;
                        }
-                       if (data_size) {
-                               data = memdup_user((void __user *)(arg + minsz),
-                                                  data_size);
-                               if (IS_ERR(data))
-                                       return PTR_ERR(data);
-                       }
+
+                       data = memdup_user((void __user *)(arg + minsz),
+                                          data_size);
+                       if (IS_ERR(data))
+                               return PTR_ERR(data);
                }
 
                ret = intel_vgpu_set_irqs(vgpu, hdr.flags, hdr.index,