Skip to content

Commit f3cdfec

Browse files
committed
components: cherryusb: Fix USB host bounds checks
Validate descriptor headers and per-type lengths before reading the current USB host config descriptor entry. Reject truncated descriptor lists instead of silently accepting a partial parse. Keep recursive hubport lookup results separate from the current loop port so a recursive miss does not replace the loop state with NULL. Generated-by: OpenAI Codex Signed-off-by: Old-Ding <35417409+Old-Ding@users.noreply.github.com>
1 parent 5882e6a commit f3cdfec

1 file changed

Lines changed: 22 additions & 4 deletions

File tree

components/drivers/usb/cherryusb/core/usbh_core.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,16 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config
225225

226226
memset(hport->config.intf, 0, sizeof(struct usbh_interface) * CONFIG_USBHOST_MAX_INTERFACES);
227227

228-
while (p[DESC_bLength] && (desc_len <= length)) {
228+
while ((desc_len + DESC_bDescriptorType < length) &&
229+
(p[DESC_bLength] > DESC_bDescriptorType) &&
230+
(desc_len + p[DESC_bLength] <= length)) {
229231
switch (p[DESC_bDescriptorType]) {
230232
case USB_DESCRIPTOR_TYPE_INTERFACE:
233+
if (p[DESC_bLength] < USB_SIZEOF_INTERFACE_DESC) {
234+
USB_LOG_ERR("invalid interface bLength 0x%02x\r\n", p[DESC_bLength]);
235+
return -USB_ERR_INVAL;
236+
}
237+
231238
intf_desc = (struct usb_interface_descriptor *)p;
232239
cur_iface = intf_desc->bInterfaceNumber;
233240
cur_alt_setting = intf_desc->bAlternateSetting;
@@ -265,6 +272,11 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config
265272
hport->config.intf[cur_iface].altsetting_num = cur_alt_setting + 1;
266273
break;
267274
case USB_DESCRIPTOR_TYPE_ENDPOINT:
275+
if (p[DESC_bLength] < USB_SIZEOF_ENDPOINT_DESC) {
276+
USB_LOG_ERR("invalid endpoint bLength 0x%02x\r\n", p[DESC_bLength]);
277+
return -USB_ERR_INVAL;
278+
}
279+
268280
ep_desc = (struct usb_endpoint_descriptor *)p;
269281
memcpy(&hport->config.intf[cur_iface].altsetting[cur_alt_setting].ep[cur_ep].ep_desc, ep_desc, 7);
270282
cur_ep++;
@@ -277,6 +289,11 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config
277289
desc_len += p[DESC_bLength];
278290
p += p[DESC_bLength];
279291
}
292+
if (desc_len != length) {
293+
USB_LOG_ERR("invalid config descriptor length %lu/%u\r\n",
294+
(unsigned long)desc_len, (unsigned int)length);
295+
return -USB_ERR_INVAL;
296+
}
280297
}
281298
return 0;
282299
}
@@ -797,6 +814,7 @@ static void *usbh_list_all_interface_name(struct usbh_hub *hub, const char *devn
797814
static struct usbh_hubport *usbh_list_all_hubport(struct usbh_hub *hub, uint8_t hub_index, uint8_t hub_port)
798815
{
799816
struct usbh_hubport *hport;
817+
struct usbh_hubport *found_hport;
800818
struct usbh_hub *hub_next;
801819

802820
if (hub->index == hub_index) {
@@ -816,9 +834,9 @@ static struct usbh_hubport *usbh_list_all_hubport(struct usbh_hub *hub, uint8_t
816834
hub_next = hport->config.intf[itf].priv;
817835

818836
if (hub_next && hub_next->connected) {
819-
hport = usbh_list_all_hubport(hub_next, hub_index, hub_port);
820-
if (hport) {
821-
return hport;
837+
found_hport = usbh_list_all_hubport(hub_next, hub_index, hub_port);
838+
if (found_hport) {
839+
return found_hport;
822840
}
823841
}
824842
}

0 commit comments

Comments
 (0)