From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
To: Ricardo Ribalda <ribalda@chromium.org>
Cc: Hans de Goede <hansg@kernel.org>,
Mauro Carvalho Chehab <mchehab@kernel.org>,
Guennadi Liakhovetski <guennadi.liakhovetski@intel.com>,
Mauro Carvalho Chehab <mchehab+samsung@kernel.org>,
linux-media@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org
Subject: Re: [PATCH] media: uvcvideo: Do not read beyond the uvc_status_control memory
Date: Fri, 2 Oct 2026 03:08:01 +0300 [thread overview]
Message-ID: <20261002000801.GC9061@killaraus.ideasonboard.com> (raw)
In-Reply-To: <20260813-uvc-status-11-v1-1-2cf43e9590b0@chromium.org>
Hi Ricardo,
Thank you for the patch.
On Thu, Aug 13, 2026 at 08:43:24PM +0000, Ricardo Ribalda wrote:
> When we receive an event from the camera we only receive 11 bytes. If a
> v4l2 control is mapped into a UVC control beyond those 11 bytes, right
> now the code is blindly reading those.
>
> Add a check in the event handler to ignore controls that are not
> available in those 11 bytes.
I tried to see where the 11 bytes size came from, and couldn't find any
mention of it (direct or indirect) in the UVC spec.
Checking my UVC descriptors collection, here are the wMaxPacketSize I
see for the control interrupt endpoint (the first column is the number
of devices):
11 wMaxPacketSize 0x0004 1x 4 bytes
89 wMaxPacketSize 0x0008 1x 8 bytes
37 wMaxPacketSize 0x000a 1x 10 bytes
2 wMaxPacketSize 0x000c 1x 12 bytes
238 wMaxPacketSize 0x0010 1x 16 bytes
3 wMaxPacketSize 0x0017 1x 23 bytes
12 wMaxPacketSize 0x0020 1x 32 bytes
41 wMaxPacketSize 0x0040 1x 64 bytes
1 wMaxPacketSize 0x4000 1x 0 bytes
16 bytes is by far the most common value, but smaller and larger sizes
are not uncommon. It seems we shouldn't harcode the size to 11, but
instead dynamically size the buffer based on the endpoint max packet
size, and, more importantly, validate the mapping offset and size
against the actual transfer length. The length is passed to
uvc_event_control() and is then lost when calling
uvc_ctrl_status_event_async(). It should be passed to the function
(subtracting the header size), stored in uvc_ctrl_work, and used in
uvc_ctrl_status_event_work() to pass it to uvc_ctrl_status_event().
One additional upside of that change is that we will be able to pass the
correct length to uvc_ctrl_status_event() in uvc_gpio_event().
What do you think ?
> Cc: stable@vger.kernel.org
> Closes: https://sashiko.dev/#/patchset/F0F008459FFA835D%2B20260813074632.2021311-1-raoxu%40uniontech.com
> Fixes: e5225c820c05 ("media: uvcvideo: Send a control event when a Control Change interrupt arrives")
> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
> ---
> drivers/media/usb/uvc/uvc_ctrl.c | 4 +++-
> drivers/media/usb/uvc/uvcvideo.h | 3 ++-
> 2 files changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
> index 3ca108b83f1d..3061f388f57b 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -2158,7 +2158,9 @@ void uvc_ctrl_status_event(struct uvc_video_chain *chain,
> list_for_each_entry(mapping, &ctrl->info.mappings, list) {
> s32 value;
>
> - if (uvc_ctrl_mapping_is_compound(mapping))
> + if (uvc_ctrl_mapping_is_compound(mapping) ||
> + DIV_ROUND_UP(mapping->offset + mapping->size, 8) >
> + UVC_STATUS_CONTROL_LEN)
> value = 0;
> else
> value = uvc_mapping_get_s32(mapping, UVC_GET_CUR, data);
> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> index b6bcee4a222f..ae5e6b6fdd98 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -559,10 +559,11 @@ struct uvc_status_streaming {
> u8 button;
> } __packed;
>
> +#define UVC_STATUS_CONTROL_LEN 11
> struct uvc_status_control {
> u8 bSelector;
> u8 bAttribute;
> - u8 bValue[11];
> + u8 bValue[UVC_STATUS_CONTROL_LEN];
> } __packed;
>
> struct uvc_status {
>
> ---
> base-commit: 7b1734e1761258d78651263706182f1d772c0d3b
> change-id: 20260813-uvc-status-11-99b9e27a8ea9
--
Regards,
Laurent Pinchart
prev parent reply other threads:[~2026-10-02 0:08 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-13 20:43 Ricardo Ribalda
2026-10-02 0:08 ` 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=20261002000801.GC9061@killaraus.ideasonboard.com \
--to=laurent.pinchart@ideasonboard.com \
--cc=guennadi.liakhovetski@intel.com \
--cc=hansg@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=mchehab+samsung@kernel.org \
--cc=mchehab@kernel.org \
--cc=ribalda@chromium.org \
--cc=stable@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®