Skip to content

Commit 70ab814

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 cddd213 commit 70ab814

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
@@ -689,10 +689,14 @@ static int uvc_get_vs_probe(const struct device *dev, struct net_buf *const buf,
689689
const struct usb_setup_packet *const setup)
690690
{
691691
struct uvc_data *data = dev->data;
692-
const size_t size = MIN(sizeof(struct uvc_probe), net_buf_tailroom(buf));
692+
size_t size;
693693
struct uvc_probe probe = {0};
694694
int ret;
695695

696+
size = net_buf_tailroom(buf);
697+
size = MIN(size, sizeof(struct uvc_probe));
698+
size = MIN(size, setup->wLength);
699+
696700
switch (setup->bRequest) {
697701
case UVC_GET_INFO:
698702
if (size < 1) {
@@ -889,12 +893,16 @@ static int uvc_get_vc_ctrl(const struct device *dev, struct net_buf *const buf,
889893
const struct device *video_dev = data->video_dev;
890894
struct video_ctrl_query cq = {.id = map->cid, .dev = video_dev};
891895
struct video_control ctrl = {.id = map->cid};
892-
size_t size = MIN(setup->wLength, net_buf_tailroom(buf));
896+
size_t size;
893897
int64_t val64;
894898
int ret;
895899

896900
__ASSERT_NO_MSG(video_dev != NULL);
897901

902+
size = net_buf_tailroom(buf);
903+
size = MIN(size, sizeof(struct uvc_probe));
904+
size = MIN(size, setup->wLength);
905+
898906
ret = video_query_ctrl(&cq);
899907
if (ret != 0) {
900908
LOG_ERR("Failed to query %s for control 0x%x", video_dev->name, cq.id);
@@ -1081,7 +1089,11 @@ static int uvc_get_errno(const struct device *dev, struct net_buf *const buf,
10811089
const struct usb_setup_packet *const setup)
10821090
{
10831091
struct uvc_data *data = dev->data;
1084-
size_t size = MIN(setup->wLength, net_buf_tailroom(buf));
1092+
size_t size;
1093+
1094+
size = net_buf_tailroom(buf);
1095+
size = MIN(size, sizeof(struct uvc_probe));
1096+
size = MIN(size, setup->wLength);
10851097

10861098
switch (setup->bRequest) {
10871099
case UVC_GET_INFO:

0 commit comments

Comments
 (0)