Re: [PATCH 3/3] media: uvcvideo: Skip frame descriptors with a zero computed size
Ricardo Ribalda <[email protected]>
| Newsgroups | org.kernel.vger.linux-media,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CANiDSCtBqiShkaCyrDhwiFZSJTwZSLng=sphMf4MmfGEvyziLQ@mail.gmail.com> |
Hi Natasha On Thu, 20 Aug 2026 at 11:57, Natasha Klaus <[email protected]> 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 <[email protected]> > Signed-off-by: Natasha Klaus <[email protected]> > --- > 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