From: Ricardo Ribalda <ribalda@chromium.org> mainline inclusion from mainline-v6.17-rc7 commit 758dbc756aad429da11c569c0d067f7fd032bcf7 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID2QLY CVE: CVE-2025-40016 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Some devices, like the Grandstream GUV3100 webcam, have an invalid UVC descriptor where multiple entities share the same ID, this is invalid and makes it impossible to make a proper entity tree without heuristics. We have recently introduced a change in the way that we handle invalid entities that has caused a regression on broken devices. Implement a new heuristic to handle these devices properly. Reported-by: Angel4005 <ooara1337@gmail.com> Closes: https://lore.kernel.org/linux-media/CAOzBiVuS7ygUjjhCbyWg-KiNx+HFTYnqH5+GJhd... Fixes: 0e2ee70291e6 ("media: uvcvideo: Mark invalid entities with id UVC_INVALID_ENTITY_ID") Cc: stable@vger.kernel.org Signed-off-by: Ricardo Ribalda <ribalda@chromium.org> Reviewed-by: Hans de Goede <hansg@kernel.org> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org> Signed-off-by: Long Li <leo.lilong@huawei.com> --- drivers/media/usb/uvc/uvc_driver.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 832590a7767c..81e5c706dce0 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -165,13 +165,26 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev, static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev, int id) { - struct uvc_streaming *stream; + struct uvc_streaming *stream, *last_stream; + unsigned int count = 0; list_for_each_entry(stream, &dev->streams, list) { + count += 1; + last_stream = stream; if (stream->header.bTerminalLink == id) return stream; } + /* + * If the streaming entity is referenced by an invalid ID, notify the + * user and use heuristics to guess the correct entity. + */ + if (count == 1 && id == UVC_INVALID_ENTITY_ID) { + dev_warn(&dev->intf->dev, + "UVC non compliance: Invalid USB header. The streaming entity has an invalid ID, guessing the correct one."); + return last_stream; + } + return NULL; } -- 2.39.2