On Mon, Nov 03, 2025 at 10:16:56AM +0000, Pranjal Shrivastava wrote:
> On Thu, Oct 23, 2025 at 08:09:29PM -0300, Jason Gunthorpe wrote:
> > This op does the copy to/from user for the info and can return back
> > a cap chain through a vfio_info_cap * result.
> > 
> > Signed-off-by: Jason Gunthorpe <[email protected]>
> > ---
> >  drivers/vfio/vfio_main.c | 54 +++++++++++++++++++++++++++++++++++++---
> >  include/linux/vfio.h     |  4 +++
> >  2 files changed, 54 insertions(+), 4 deletions(-)
> 
> The newly added vfio_get_region_info seems to pull-in common boilerplate
> code (like copy_from_user, arg size validation) into the core code,
> removing redundancy across all other vfio drivers. LGTM.

I missed one thing in this patch (luckily caught it in patch 22):

> diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c
> index f056e82ba35075..82e7d79b1f9fe2 100644
> --- a/drivers/vfio/vfio_main.c
> +++ b/drivers/vfio/vfio_main.c
> @@ -1259,6 +1259,55 @@ static int vfio_ioctl_device_feature(struct 
> vfio_device *device,
>       }
>  }
>  
> +static long vfio_get_region_info(struct vfio_device *device,
> +                              struct vfio_region_info __user *arg)
> +{
> +     unsigned long minsz = offsetofend(struct vfio_region_info, offset);
> +     struct vfio_region_info info = {};
> +     int ret;
> +
> +     if (copy_from_user(&info, arg, minsz))
> +             return -EFAULT;
> +     if (info.argsz < minsz)
> +             return -EINVAL;
> +
> +     if (device->ops->get_region_info_caps) {
> +             struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
> +
> +             ret = device->ops->get_region_info_caps(device, &info, &caps);
> +             if (ret)
> +                     return ret;

device->ops->get_region_info_caps (via vfio_info_add_capability) can
allocate caps.buf and then return an error for a different reason. The
if (ret) check returns early and the kfree(caps.buf) on the success path
is never reached.

Should we add kfree(caps.buf) to the error path here?
This keeps the allocation and cleanup logic centralized in the core code

Let's either write comment saying that the get_region_info_caps op is required
to free caps.buf before returning error OR add a kfree(caps.buf) here.

> +
> +             if (caps.size) {
> +                     info.flags |= VFIO_REGION_INFO_FLAG_CAPS;
> +                     if (info.argsz < sizeof(info) + caps.size) {
> +                             info.argsz = sizeof(info) + caps.size;
> +                             info.cap_offset = 0;
> +                     } else {
> +                             vfio_info_cap_shift(&caps, sizeof(info));
> +                             if (copy_to_user(arg + 1, caps.buf,
> +                                              caps.size)) {
> +                                     kfree(caps.buf);
> +                                     return -EFAULT;
> +                             }
> +                             info.cap_offset = sizeof(info);
> +                     }
> +                     kfree(caps.buf);
> +             }
> +
> +             if (copy_to_user(arg, &info, minsz))
> +                     return -EFAULT;
> +     } else if (device->ops->get_region_info) {
> +             ret = device->ops->get_region_info(device, arg);
> +             if (ret)
> +                     return ret;

With the above comment addressed,

Reviewed-by: Pranjal Shrivastava <[email protected]>

Thanks,
Praan

Reply via email to