From 366c64eca02d38db47e443aee34c4f93f010d5fa Mon Sep 17 00:00:00 2001 From: Josuah Demangeon Date: Fri, 18 Jul 2025 19:11:55 +0000 Subject: [PATCH] usb: uvc: respect setup->wLength in responses Due to the alignment and granularity requirements of memory allocation, setup->wLength is shorter than the allocated buffer size. This lead to responses larger than what the host requested, which it rejected. Fix it by using the minimum between the allocated size, the struct size, and the wLength requested. Signed-off-by: Josuah Demangeon --- subsys/usb/device_next/class/usbd_uvc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/subsys/usb/device_next/class/usbd_uvc.c b/subsys/usb/device_next/class/usbd_uvc.c index 629b5df73b4..9038a8e0d3f 100644 --- a/subsys/usb/device_next/class/usbd_uvc.c +++ b/subsys/usb/device_next/class/usbd_uvc.c @@ -694,7 +694,8 @@ static int uvc_get_vs_probe(const struct device *dev, struct net_buf *const buf, const struct usb_setup_packet *const setup) { struct uvc_data *data = dev->data; - const size_t size = MIN(sizeof(struct uvc_probe), net_buf_tailroom(buf)); + const size_t size = MIN(net_buf_tailroom(buf), + MIN(sizeof(struct uvc_probe), setup->wLength)); struct uvc_probe probe = {0}; int ret; @@ -912,7 +913,8 @@ static int uvc_get_vc_ctrl(const struct device *dev, struct net_buf *const buf, const struct device *video_dev = data->video_dev; struct video_ctrl_query cq = {.id = map->cid, .dev = video_dev}; struct video_control ctrl = {.id = map->cid}; - size_t size = MIN(setup->wLength, net_buf_tailroom(buf)); + const size_t size = MIN(net_buf_tailroom(buf), + MIN(sizeof(struct uvc_probe), setup->wLength)); int64_t val64; int ret; @@ -1104,7 +1106,8 @@ static int uvc_get_errno(const struct device *dev, struct net_buf *const buf, const struct usb_setup_packet *const setup) { struct uvc_data *data = dev->data; - size_t size = MIN(setup->wLength, net_buf_tailroom(buf)); + const size_t size = MIN(net_buf_tailroom(buf), + MIN(sizeof(struct uvc_probe), setup->wLength)); switch (setup->bRequest) { case UVC_GET_INFO: