If a frame has size of less or equal than one packet size
uvc_alloc_urb_buffers() is unable to allocate memory for it due to a
off-by-one error.
Fix the off-by-one-error and now that we are at it, make sure that
stream->urb_size has always a valid value when we return from the
function, even when an error happens.
Fixes: efdc8a9585ce ("V4L/DVB (10295): uvcvideo: Retry URB buffers allocation when the system is low on memory.")
Reported-by: Itay Chamiel <itay.chamiel@q.ai>
Closes: https://lore.kernel.org/linux-media/CANiDSCsSoZf2LsCCoWAUbCg6tJT-ypXR1B85aa6rAdMVYr2iBQ@mail.gmail.com/T/#t
Co-developed-by: Itay Chamiel <itay.chamiel@q.ai>
Signed-off-by: Itay Chamiel <itay.chamiel@q.ai>
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
---
drivers/media/usb/uvc/uvc_video.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index 2094e059d7d39ac5a196cbbd58f9bc997f1c1557..ec76595f3c4be0f49b798ec663d6855d78ab21c4 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -1812,7 +1812,7 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream,
npackets = UVC_MAX_PACKETS;
/* Retry allocations until one succeed. */
- for (; npackets > 1; npackets /= 2) {
+ for (; npackets > 0; npackets /= 2) {
stream->urb_size = psize * npackets;
for (i = 0; i < UVC_URBS; ++i) {
@@ -1837,6 +1837,7 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream,
uvc_dbg(stream->dev, VIDEO,
"Failed to allocate URB buffers (%u bytes per packet)\n",
psize);
+ stream->urb_size = 0;
return 0;
}
--
2.52.0.457.g6b5491de43-goog
Hi Ricardo,
Thank you for the patch.
On Wed, Jan 14, 2026 at 10:32:13AM +0000, Ricardo Ribalda wrote:
> If a frame has size of less or equal than one packet size
> uvc_alloc_urb_buffers() is unable to allocate memory for it due to a
> off-by-one error.
>
> Fix the off-by-one-error and now that we are at it, make sure that
> stream->urb_size has always a valid value when we return from the
> function, even when an error happens.
>
> Fixes: efdc8a9585ce ("V4L/DVB (10295): uvcvideo: Retry URB buffers allocation when the system is low on memory.")
> Reported-by: Itay Chamiel <itay.chamiel@q.ai>
> Closes: https://lore.kernel.org/linux-media/CANiDSCsSoZf2LsCCoWAUbCg6tJT-ypXR1B85aa6rAdMVYr2iBQ@mail.gmail.com/T/#t
> Co-developed-by: Itay Chamiel <itay.chamiel@q.ai>
> Signed-off-by: Itay Chamiel <itay.chamiel@q.ai>
> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> drivers/media/usb/uvc/uvc_video.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
> index 2094e059d7d39ac5a196cbbd58f9bc997f1c1557..ec76595f3c4be0f49b798ec663d6855d78ab21c4 100644
> --- a/drivers/media/usb/uvc/uvc_video.c
> +++ b/drivers/media/usb/uvc/uvc_video.c
> @@ -1812,7 +1812,7 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream,
> npackets = UVC_MAX_PACKETS;
>
> /* Retry allocations until one succeed. */
> - for (; npackets > 1; npackets /= 2) {
> + for (; npackets > 0; npackets /= 2) {
> stream->urb_size = psize * npackets;
>
> for (i = 0; i < UVC_URBS; ++i) {
> @@ -1837,6 +1837,7 @@ static int uvc_alloc_urb_buffers(struct uvc_streaming *stream,
> uvc_dbg(stream->dev, VIDEO,
> "Failed to allocate URB buffers (%u bytes per packet)\n",
> psize);
> + stream->urb_size = 0;
> return 0;
> }
>
--
Regards,
Laurent Pinchart
© 2016 - 2026 Red Hat, Inc.