From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Ricardo Ribalda <ribalda@chromium.org>
Cc: Louis Clinckx <clinckx.louis@gmail.com>,
Mauro Carvalho Chehab <mchehab@kernel.org>,
linux-media@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] media: uvcvideo: skip bulk output URBs smaller than the payload header
Date: Tue, 13 Oct 2026 12:21:52 +0200 [thread overview]
Message-ID: <20261013102152.GF56180@killaraus.ideasonboard.com> (raw)
In-Reply-To: <CANiDSCujghpaqP64tWnObOTMUmNTdQp3-6yb2C2MrOC9=48a4w@mail.gmail.com>
On Tue, Oct 13, 2026 at 05:53:55PM +0800, Ricardo Ribalda wrote:
> HI Louis
>
> Thanks for your patch
>
> On Tue, 13 Oct 2026 at 14:56, Louis Clinckx <clinckx.louis@gmail.com> wrote:
> >
> > For a bulk video output stream, uvc_video_encode_bulk() starts each
> > payload by writing a fixed 2-byte header with uvc_video_encode_header()
> > and subtracts it from a signed length counter initialised to the URB
> > size:
>
> Out of curiosity, do you have a UVC output device? I would really like
> to test one out, but I could not find anything on the market.
>
> >
> > int len = stream->urb_size;
> > ...
> > len -= uvc_video_encode_header(...); /* always returns 2 */
> >
> > An output device can describe a bulk endpoint with wMaxPacketSize 1 and
> > negotiate dwMaxPayloadTransferSize 1, which leaves stream->urb_size == 1.
> > len then becomes -1, and uvc_video_encode_data() casts it to unsigned:
> >
> > nbytes = min((unsigned int)len, buf->bytesused - queue->buf_used);
> >
> > so (unsigned)-1 does not clamp and the following memcpy() copies the
> > whole frame past the one-byte URB buffer.
> >
> > A URB that cannot hold the 2-byte header cannot carry a payload, so skip
> > it instead of letting the length underflow.
> >
> > Signed-off-by: Louis Clinckx <clinckx.louis@gmail.com>
> > ---
> > drivers/media/usb/uvc/uvc_video.c | 7 +++++++
> > 1 file changed, 7 insertions(+)
> >
> > diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
> > --- a/drivers/media/usb/uvc/uvc_video.c
> > +++ b/drivers/media/usb/uvc/uvc_video.c
> > @@ -1701,7 +1701,14 @@ static void uvc_video_encode_bulk(struct uvc_urb *uvc_urb,
> > if (buf == NULL) {
> > urb->transfer_buffer_length = 0;
> > return;
> > }
> >
> > + /* The 2-byte payload header must fit; a smaller URB would make len
> > + * underflow and uvc_video_encode_data() copy past the buffer. */
> > + if (len < 2) {
> > + urb->transfer_buffer_length = 0;
> > + return;
> > + }
> > +
> > /* If the URB is the first of its payload, add the header. */
> > if (stream->bulk.header_size == 0) {
>
> I'd also detect that the configuration is broken, maybe in
> uvc_init_video_bulk() ?
There's indeed no point in silently and unconditionally failing to
encode data when the issue can be detected when starting the stream (or
even better, at probe time). Thisis what the next version should do.
> and a bit nitpick. I think this is slightly more idiomatic than your check.
>
> diff --git a/drivers/media/usb/uvc/uvc_video.c
> b/drivers/media/usb/uvc/uvc_video.c
> index ec76595f3c4b..03940b62b250 100644
> --- a/drivers/media/usb/uvc/uvc_video.c
> +++ b/drivers/media/usb/uvc/uvc_video.c
> @@ -1373,6 +1373,8 @@ static void uvc_video_decode_end(struct uvc_streaming *stream,
> static int uvc_video_encode_header(struct uvc_streaming *stream,
> struct uvc_buffer *buf, u8 *data, int len)
> {
> + if (len < 2)
> + return -ENOSPC;
If we reject invalid configurations this won't be necessary any more.
> data[0] = 2; /* Header length */
> data[1] = UVC_STREAM_EOH | UVC_STREAM_EOF
> | (stream->last_fid & UVC_STREAM_FID);
> @@ -1656,6 +1658,10 @@ static void uvc_video_encode_bulk(struct uvc_urb *uvc_urb,
> /* If the URB is the first of its payload, add the header. */
> if (stream->bulk.header_size == 0) {
> ret = uvc_video_encode_header(stream, buf, mem, len);
> + if (ret < 0) {
> + urb->transfer_buffer_length = 0;
> + return;
> + }
> stream->bulk.header_size = ret;
> stream->bulk.payload_size += ret;
> mem += ret;
--
Regards,
Laurent Pinchart
prev parent reply other threads:[~2026-10-13 10:22 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-13 6:53 [PATCH] media: uvcvideo: skip bulk output URBs smaller than the payload header Louis Clinckx
2026-10-13 9:53 ` Ricardo Ribalda
2026-10-13 10:21 ` Laurent Pinchart [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261013102152.GF56180@killaraus.ideasonboard.com \
--to=laurent.pinchart@ideasonboard.com \
--cc=clinckx.louis@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@kernel.org \
--cc=ribalda@chromium.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.