Skip to content

Commit 5bfaf7e

Browse files
authored
fix(usbh): bounds-check cur_ep before writing ep[] in parse_config_descriptor (#426)
* fix(usbh): check cur_ep against CONFIG_USBHOST_MAX_ENDPOINTS before writing ep[] parse_config_descriptor() checks cur_ep_num (the interface descriptor's self-declared bNumEndpoints) against CONFIG_USBHOST_MAX_ENDPOINTS when the INTERFACE descriptor is parsed, but cur_ep (the actual write index, incremented once per ENDPOINT sub-descriptor encountered in the byte stream) is never bounds-checked in the USB_DESCRIPTOR_TYPE_ENDPOINT case before the memcpy. A non-conformant or malicious device can declare a small bNumEndpoints while still emitting more ENDPOINT descriptors than declared in the raw config descriptor byte stream, causing cur_ep to exceed CONFIG_USBHOST_MAX_ENDPOINTS and the memcpy to write past the ep[] array, past altsetting[], and potentially past the whole usbh_configuration struct. Add the same bounds check pattern already used for cur_iface and cur_alt_setting two cases above, applied to cur_ep before the memcpy. * Allow interfaces to use configured capacity Endpoint counts are quantities, so a declaration equal to the endpoint array capacity is valid. The per-index guard still rejects descriptors that contain more endpoint records than the storage can hold. Constraint: Preserve the new cur_ep index guard Confidence: high Scope-risk: narrow Tested: Real parser matrix for declared/actual 3/3, 4/4, 5/5, and 3/5; MinGW and WSL GCC13 ASan+UBSan Not-tested: Physical USB device enumeration
1 parent bcf74e9 commit 5bfaf7e

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

core/usbh_core.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config
242242
return -USB_ERR_NOMEM;
243243
}
244244

245-
if (cur_ep_num >= CONFIG_USBHOST_MAX_ENDPOINTS) {
245+
if (cur_ep_num > CONFIG_USBHOST_MAX_ENDPOINTS) {
246246
USB_LOG_ERR("Endpoint num %d overflow\r\n", cur_ep_num);
247247
return -USB_ERR_NOMEM;
248248
}
@@ -272,6 +272,12 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config
272272
return -USB_ERR_INVAL;
273273
}
274274
ep_desc = (struct usb_endpoint_descriptor *)p;
275+
276+
if (cur_ep >= CONFIG_USBHOST_MAX_ENDPOINTS) {
277+
USB_LOG_ERR("Endpoint num %d overflow\r\n", cur_ep);
278+
return -USB_ERR_NOMEM;
279+
}
280+
275281
memcpy(&hport->config.intf[cur_iface].altsetting[cur_alt_setting].ep[cur_ep].ep_desc, ep_desc, 7);
276282
cur_ep++;
277283
break;

0 commit comments

Comments
 (0)