This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit b1a1ee593b0c924fb8ec9b7371843f815315f018 Author: chao an <[email protected]> AuthorDate: Thu Oct 29 14:27:46 2026 +0800 drivers/usbhost: Bound composite member writes Composite member allocation is based on the number of interfaces minus the interfaces merged by IAD descriptors. Malformed interface or IAD records could make the second descriptor pass write more entries than were allocated. Validate interface and IAD descriptor sizes and ranges in both passes, and check the member index before writing to the members array. Signed-off-by: chao an <[email protected]> --- drivers/usbhost/usbhost_composite.c | 50 ++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/drivers/usbhost/usbhost_composite.c b/drivers/usbhost/usbhost_composite.c index e8199e04caf..bfbc96518f8 100644 --- a/drivers/usbhost/usbhost_composite.c +++ b/drivers/usbhost/usbhost_composite.c @@ -611,6 +611,11 @@ int usbhost_composite(FAR struct usbhost_hubport_s *hport, desc = (FAR struct usb_desc_s *)&configdesc[offset]; int len = desc->len; + if (len < sizeof(struct usb_desc_s) || len > desclen - offset) + { + return -EINVAL; + } + if (offset + len <= desclen) { /* Is this an interface descriptor? */ @@ -620,7 +625,10 @@ int usbhost_composite(FAR struct usbhost_hubport_s *hport, FAR struct usb_ifdesc_s *ifdesc = (FAR struct usb_ifdesc_s *)desc; - DEBUGASSERT(ifdesc->ifno < 32); + if (len < USB_SIZEOF_IFDESC || ifdesc->ifno >= 32) + { + return -EINVAL; + } /* Increment the count of interfaces */ @@ -641,13 +649,18 @@ int usbhost_composite(FAR struct usbhost_hubport_s *hport, (FAR struct usb_iaddesc_s *)desc; uint32_t mask; + if (len < USB_SIZEOF_IADDESC || iad->nifs == 0 || + iad->firstif >= 32 || iad->nifs > 32 - iad->firstif) + { + return -EINVAL; + } + /* Keep count of the number of interfaces that will be merged */ nmerged += (iad->nifs - 1); /* Keep track of which interfaces will be merged */ - DEBUGASSERT(iad->firstif + iad->nifs < 32); mask = (1 << iad->nifs) - 1; mergeset |= mask << iad->firstif; } @@ -727,6 +740,12 @@ int usbhost_composite(FAR struct usbhost_hubport_s *hport, desc = (FAR struct usb_desc_s *)&configdesc[offset]; int len = desc->len; + if (len < sizeof(struct usb_desc_s) || len > desclen - offset) + { + ret = -EINVAL; + goto errout_with_members; + } + if (offset + len <= desclen) { /* Is this an interface descriptor? */ @@ -738,9 +757,20 @@ int usbhost_composite(FAR struct usbhost_hubport_s *hport, /* Was the interface merged via an IAD descriptor? */ - DEBUGASSERT(ifdesc->ifno < 32); + if (len < USB_SIZEOF_IFDESC || ifdesc->ifno >= 32) + { + ret = -EINVAL; + goto errout_with_members; + } + if ((mergeset & (1 << ifdesc->ifno)) == 0) { + if (i >= nclasses) + { + ret = -EINVAL; + goto errout_with_members; + } + /* No, this interface was not merged. Save the registry * lookup information from the interface descriptor. */ @@ -772,6 +802,14 @@ int usbhost_composite(FAR struct usbhost_hubport_s *hport, FAR struct usb_iaddesc_s *iad = (FAR struct usb_iaddesc_s *)desc; + if (len < USB_SIZEOF_IADDESC || iad->nifs == 0 || + iad->firstif >= 32 || iad->nifs > 32 - iad->firstif || + i >= nclasses) + { + ret = -EINVAL; + goto errout_with_members; + } + /* Yes.. Save the registry lookup information from the IAD. */ member = (FAR struct usbhost_member_s *) @@ -800,6 +838,12 @@ int usbhost_composite(FAR struct usbhost_hubport_s *hport, DEBUGASSERT(i == nclasses); + if (i != nclasses) + { + ret = -EINVAL; + goto errout_with_members; + } + /* Allocate a temporary buffer in which we can construct a custom * configuration descriptor for each member class. */
