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. Signed-off-by: Jonathan Cavitt <jonathan.cav...@intel.com> Cc: Andi Shyti <andi.sh...@linux.intel.com> --- drivers/gpu/drm/i915/gvt/kvmgt.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 69830a5c49d3..d1c9d43ae12f 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -1361,21 +1361,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 (hweight32(hdr.flags & VFIO_IRQ_DATA_TYPE_MASK) != 1 || + hweight32(hdr.flags & VFIO_IRQ_ACTION_TYPE_MASK) != 1) + 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, -- 2.43.0