Re: [PATCH 3/3] media: uvcvideo: Skip frame descriptors with a zero computed size

From: Ricardo Ribalda

Date: Thu Aug 20 2026 - 06:37:31 EST


Hi Natasha

On Thu, 20 Aug 2026 at 11:57, Natasha Klaus
<natalie.klaus@xxxxxxxxxxxxxxxxxxxxxxx> wrote:
>
> For uncompressed formats uvc_parse_frame() recomputes
> dwMaxVideoFrameBufferSize from the frame dimensions and the bits per
> pixel. All three operands are read straight from the descriptor bytes
> with no range check, so the computed size is zero whenever any of them
> is zero.
>
> A zero size is not harmless. It is copied into
> ctrl->dwMaxVideoFrameSize by uvc_fixup_video_ctrl() and reaches
> uvc_queue_setup() as the vb2 plane size, where it trips
> WARN_ON(!plane_sizes[i]) in vb2_core_reqbufs() at
> drivers/media/common/videobuf2/videobuf2-core.c:951 and fails
> VIDIOC_REQBUFS with -EINVAL. On a kernel built with panic_on_warn that
> WARN is fatal.
>
> Such a frame can also become the active one without any application
> asking for it: when no frame matches the device's default bFrameIndex,
> uvc_video_init() falls back to frames[0], so a device that also has
> usable frames can come up unusable.
>
> Skip the frame rather than rejecting the descriptor, which would discard
> the whole streaming interface and every valid format on it. This follows
> commit 81f3affa19d6 ("media: uvcvideo: Don't expose unsupported formats
> to userspace"), which drops a format descriptor the driver cannot use
> for the same reason: to keep it from reaching userspace and triggering a
> WARN_ON.
>
Reviewed-by: Ricardo Ribalda <ribalda@xxxxxxxxxxxx>
> Signed-off-by: Natasha Klaus <natalie.klaus@xxxxxxxxxxxxxxxxxxxxxxx>
> ---
> Depends on 1/3 for -EINVAL to mean "skip this frame", and on 2/3 for the
> bufsize local.
>
> After 2/3 rounds up instead of truncating, the computed size is zero only
> when one of bpp, wWidth or wHeight is zero; the "product below 8 truncates
> to zero" case no longer exists.
>
> drivers/media/usb/uvc/uvc_driver.c | 14 ++++++++++++++
> 1 file changed, 14 insertions(+)
>
> diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
> index eb7177ea291d..3bd8d31e1378 100644
> --- a/drivers/media/usb/uvc/uvc_driver.c
> +++ b/drivers/media/usb/uvc/uvc_driver.c
> @@ -308,6 +308,20 @@ static int uvc_parse_frame(struct uvc_device *dev,
> return -EINVAL;
> }
>
> + /*
> + * A zero-sized frame is unusable: it reaches vb2 as a zero
> + * plane size, and it is reported to userspace as a 0x0 frame
> + * with a zero sizeimage. Skip the frame descriptor, the
> + * caller moves on to the next one.
> + */
> + if (!bufsize) {
> + dev_warn(&streaming->intf->dev,
> + "UVC non compliance: FRAME %u has zero size (%ux%u, %u bpp), skipping it.\n",
> + frame->bFrameIndex, frame->wWidth,
> + frame->wHeight, format->bpp);
> + return -EINVAL;
> + }
> +
> frame->dwMaxVideoFrameBufferSize = bufsize;
> }
>
> --
> 2.34.1
>


--
Ricardo Ribalda