Skip to content

Commit ff18028

Browse files
committed
usb: uvc: respect setup->wLength in responses
In some cases, 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 <me@josuah.net>
1 parent 26cb178 commit ff18028

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

subsys/usb/device_next/class/usbd_uvc.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -694,10 +694,14 @@ static int uvc_get_vs_probe(const struct device *dev, struct net_buf *const buf,
694694
const struct usb_setup_packet *const setup)
695695
{
696696
struct uvc_data *data = dev->data;
697-
const size_t size = MIN(sizeof(struct uvc_probe), net_buf_tailroom(buf));
697+
size_t size;
698698
struct uvc_probe probe = {0};
699699
int ret;
700700

701+
size = net_buf_tailroom(buf);
702+
size = MIN(size, sizeof(struct uvc_probe));
703+
size = MIN(size, setup->wLength);
704+
701705
switch (setup->bRequest) {
702706
case UVC_GET_INFO:
703707
if (size < 1) {
@@ -912,12 +916,16 @@ static int uvc_get_vc_ctrl(const struct device *dev, struct net_buf *const buf,
912916
const struct device *video_dev = data->video_dev;
913917
struct video_ctrl_query cq = {.id = map->cid, .dev = video_dev};
914918
struct video_control ctrl = {.id = map->cid};
915-
size_t size = MIN(setup->wLength, net_buf_tailroom(buf));
919+
size_t size;
916920
int64_t val64;
917921
int ret;
918922

919923
__ASSERT_NO_MSG(video_dev != NULL);
920924

925+
size = net_buf_tailroom(buf);
926+
size = MIN(size, sizeof(struct uvc_probe));
927+
size = MIN(size, setup->wLength);
928+
921929
ret = video_query_ctrl(&cq);
922930
if (ret != 0) {
923931
LOG_ERR("Failed to query %s for control 0x%x", video_dev->name, cq.id);
@@ -1104,7 +1112,11 @@ static int uvc_get_errno(const struct device *dev, struct net_buf *const buf,
11041112
const struct usb_setup_packet *const setup)
11051113
{
11061114
struct uvc_data *data = dev->data;
1107-
size_t size = MIN(setup->wLength, net_buf_tailroom(buf));
1115+
size_t size;
1116+
1117+
size = net_buf_tailroom(buf);
1118+
size = MIN(size, sizeof(struct uvc_probe));
1119+
size = MIN(size, setup->wLength);
11081120

11091121
switch (setup->bRequest) {
11101122
case UVC_GET_INFO:

0 commit comments

Comments
 (0)