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 5cd22c7da34c7c3eae3d291da2e9b855d16d00fc Author: chao an <[email protected]> AuthorDate: Thu Oct 29 14:27:46 2026 +0800 drivers/usbhost: Validate composite interface copies usbhost_copyinterface() copied the selected interface descriptor before checking that the descriptor length fit in the destination buffer. It also advanced through the source configuration buffer without validating that each descriptor length stayed within the source data. Validate source descriptor lengths and destination space before copying interface, class-specific, and endpoint descriptors into the generated composite configuration. Signed-off-by: chao an <[email protected]> --- drivers/usbhost/usbhost_composite.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/usbhost/usbhost_composite.c b/drivers/usbhost/usbhost_composite.c index 0c154efef2b..e8199e04caf 100644 --- a/drivers/usbhost/usbhost_composite.c +++ b/drivers/usbhost/usbhost_composite.c @@ -285,6 +285,12 @@ static int usbhost_copyinterface(uint8_t ifno, FAR const uint8_t *configdesc, int neps; int len; + if (configdesc == NULL || buffer == NULL || + desclen < sizeof(struct usb_desc_s)) + { + return -EINVAL; + } + /* Make sure that the buffer will hold at least the interface descriptor */ if (buflen < USB_SIZEOF_IFDESC) @@ -301,10 +307,20 @@ static int usbhost_copyinterface(uint8_t ifno, FAR const uint8_t *configdesc, desc = (FAR struct usb_desc_s *)&configdesc[offset]; len = desc->len; + if (len < sizeof(struct usb_desc_s) || len > desclen - offset) + { + return -EINVAL; + } + /* Is this an interface descriptor? */ if (desc->type == USB_DESC_TYPE_INTERFACE) { + if (len < USB_SIZEOF_IFDESC) + { + return -EINVAL; + } + ifdesc = (FAR struct usb_ifdesc_s *)&configdesc[offset]; /* Is it the one we are looking for? */ @@ -313,6 +329,11 @@ static int usbhost_copyinterface(uint8_t ifno, FAR const uint8_t *configdesc, { /* Yes.. return the interface descriptor */ + if (buflen < len) + { + return -ENOSPC; + } + memcpy(buffer, desc, len); buffer += len; buflen -= len; @@ -339,6 +360,12 @@ static int usbhost_copyinterface(uint8_t ifno, FAR const uint8_t *configdesc, desc = (FAR struct usb_desc_s *)&configdesc[offset]; len = desc->len; + if (len < sizeof(struct usb_desc_s) || + len > desclen - offset) + { + return -EINVAL; + } + /* Is this a class-specific interface descriptor? */ if (desc->type == USB_DESC_TYPE_CSINTERFACE)
