diff options
| author | yi chen <[email protected]> | 2026-07-17 09:43:01 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-07-17 09:43:01 +0800 |
| commit | 5bfaf7e3fc542db6624fc51cceccbb1d92d8706c (patch) | |
| tree | 2b065a3c5ed446f3152465d94c09fabf069c884b /core/usbh_core.c | |
| parent | bcf74e9cdef573d4026cb5987076a263d8a8fc51 (diff) | |
* 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
Diffstat (limited to 'core/usbh_core.c')
| -rw-r--r-- | core/usbh_core.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/core/usbh_core.c b/core/usbh_core.c index b7f762ea..8aa92588 100644 --- a/core/usbh_core.c +++ b/core/usbh_core.c @@ -242,7 +242,7 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config return -USB_ERR_NOMEM; } - if (cur_ep_num >= CONFIG_USBHOST_MAX_ENDPOINTS) { + if (cur_ep_num > CONFIG_USBHOST_MAX_ENDPOINTS) { USB_LOG_ERR("Endpoint num %d overflow\r\n", cur_ep_num); return -USB_ERR_NOMEM; } @@ -272,6 +272,12 @@ static int parse_config_descriptor(struct usbh_hubport *hport, struct usb_config return -USB_ERR_INVAL; } ep_desc = (struct usb_endpoint_descriptor *)p; + + if (cur_ep >= CONFIG_USBHOST_MAX_ENDPOINTS) { + USB_LOG_ERR("Endpoint num %d overflow\r\n", cur_ep); + return -USB_ERR_NOMEM; + } + memcpy(&hport->config.intf[cur_iface].altsetting[cur_alt_setting].ep[cur_ep].ep_desc, ep_desc, 7); cur_ep++; break; |
