[PATCH] media: uvcvideo: Do not read beyond the uvc_status_control memory

Ricardo Ribalda posted 1 patch 1 month, 2 weeks ago
drivers/media/usb/uvc/uvc_ctrl.c | 4 +++-
drivers/media/usb/uvc/uvcvideo.h | 3 ++-
2 files changed, 5 insertions(+), 2 deletions(-)
[PATCH] media: uvcvideo: Do not read beyond the uvc_status_control memory
Posted by Ricardo Ribalda 1 month, 2 weeks ago
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.

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

Best regards,
-- 
Ricardo Ribalda <ribalda@chromium.org>