All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Laight <david.laight.linux@gmail.com>
To: Noam Ben Shimon <noambs2999@gmail.com>
Cc: laurent.pinchart@ideasonboard.com, hansg@kernel.org,
	mchehab@kernel.org, linux-media@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] media: uvcvideo: Fix integer overflow in frame buffer size calculation
Date: Tue, 18 Aug 2026 09:28:03 +0100	[thread overview]
Message-ID: <20260818092803.4f51e6dc@pumpkin> (raw)
In-Reply-To: <20260807101433.54886-1-noambs2999@gmail.com>

On Fri,  7 Aug 2026 13:14:33 +0300
Noam Ben Shimon <noambs2999@gmail.com> wrote:

> In the function uvc_parse_frame(), it recomputes
> dwMaxVideoFrameBufferSize for uncompressed formats. This helps working
> around devices that report it wrong:
> 
> 	frame->dwMaxVideoFrameBufferSize = format->bpp * frame->wWidth
> 					 * frame->wHeight / 8;
> 
> These three arguments originate from the device's own descriptors, and
> therefore can be decided by it. bpp is a u8 and wWidth and wHeight are
> u16. The expression is evaluated in int, and the maximum value is
> 255 * 65535 * 65535 (which is roughly 510 times INT_MAX).
> A device that declares large dimensions therefore overflows a signed
> int here.
> The kernel is built using -fno-strict-overflow, so this wraps rather
> than being miscompiled, but the wrapped value (which is often negative)
> is then divided by 8 and stored in a u32 used as a size.
> 
> Two examples for this (using legal field values):
> 
>   - 32 bpp, 16384x4096: the product is exactly 2^31 and wraps to
>     INT_MIN. After division and conversion to u32 the field has the
>     value 4026531840 rather than 268435456.
> 
>   - 16 bpp, 16384x16384: the product is exactly 2^32 and wraps to 0.
>     The field holds 0, rather than the correct 536870912.
> 
> I don't think memory corruption is a consequence of this. The value
> reaches uvc_queue_setup() as the vb2 buffer size, and every copy on the
> decode path is bounded by buf->length, which uvc_buffer_prepare() gets
> from vb2_plane_size() rather than this field. What a wrapped value does
> instead is make the driver describe the stream inconsistently.
> For an uncompressed format uvc_fixup_video_ctrl() copies it into
> ctrl->dwMaxVideoFrameSize unconditionally, and that becomes the
> sizeimage reported by VIDIOC_G_FMT. This is while width, height and
> bytesperline continue to describe the full frame.
> This also makes uvc_video_validate_buffer() mark error on all frames,
> because it is comparing bytesused against the same number.
> 
> Compute the size in 64-bit, and if the result does not fit in the u32
> field then reject the frame descriptor. An uncompressed frame this
> large is probably not a real device and rejection is consistent with
> the other checks over malformed-descriptors in this function.
> 
> Fixes: c0efd232929c ("V4L/DVB (8145a): USB Video Class driver")
> Signed-off-by: Noam Ben Shimon <noambs2999@gmail.com>
> ---
>  drivers/media/usb/uvc/uvc_driver.c | 18 +++++++++++++++---
>  1 file changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
> index e289cc71ba98..d319368f9d21 100644
> --- a/drivers/media/usb/uvc/uvc_driver.c
> +++ b/drivers/media/usb/uvc/uvc_driver.c
> @@ -296,9 +296,21 @@ static int uvc_parse_frame(struct uvc_device *dev,
>  	 * information. For uncompressed formats this can be fixed by computing
>  	 * the value from the frame size.
>  	 */
> -	if (!(format->flags & UVC_FMT_FLAG_COMPRESSED))
> -		frame->dwMaxVideoFrameBufferSize = format->bpp * frame->wWidth
> -						 * frame->wHeight / 8;
> +	if (!(format->flags & UVC_FMT_FLAG_COMPRESSED)) {
> +		u64 bufsize;
> +
> +		bufsize = (u64)format->bpp * frame->wWidth * frame->wHeight / 8;

I'd bet there is a requirement that width*bpp is a multiple of 8 (or even 32)?
You definitely don't want the divide rounding down!

> +		if (bufsize > U32_MAX) {

Should that be >= ?

> +			uvc_dbg(dev, DESCR,
> +				"device %d videostreaming interface %d FRAME %u: computed buffer size overflows\n",

s/buffer/frame buffer/ ?

> +				dev->udev->devnum,
> +				alts->desc.bInterfaceNumber,
> +				frame->bFrameIndex);

I'd include the bpp, width and height values in the trace.
If the error happens the first thing you need the the three values.

	David

> +			return -EINVAL;
> +		}
> +
> +		frame->dwMaxVideoFrameBufferSize = bufsize;
> +	}
>  
>  	/*
>  	 * Clamp the default frame interval to the boundaries. A zero
> 
> base-commit: f9a2394a23482bfd330911e9c8295b71724feacd


      parent reply	other threads:[~2026-08-18  8:28 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-07 10:14 [PATCH] media: uvcvideo: Fix integer overflow in frame buffer size calculation Noam Ben Shimon
2026-08-10 14:12 ` Ricardo Ribalda
2026-08-12 10:32 ` [PATCH v2] " Noam Ben Shimon
2026-08-18  6:45   ` Natasha Klaus
2026-08-18  6:54     ` Ricardo Ribalda
2026-08-18  6:57       ` Ricardo Ribalda
2026-08-18  7:59   ` [PATCH] media: uvcvideo: Skip frame descriptors with a zero computed size Natasha Klaus
2026-08-18  8:31     ` Ricardo Ribalda
2026-08-18  9:40       ` Natasha Klaus
2026-08-18  9:53         ` Natasha Klaus
2026-08-18 10:18         ` Ricardo Ribalda
2026-08-18 10:32       ` Natasha Klaus
2026-08-18 10:40         ` Ricardo Ribalda
2026-08-18  8:28 ` David Laight [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=20260818092803.4f51e6dc@pumpkin \
    --to=david.laight.linux@gmail.com \
    --cc=hansg@kernel.org \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@kernel.org \
    --cc=noambs2999@gmail.com \
    /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.