This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch releases/13.1
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 069384817bb8df58c7bd0acac045528a67eab1c2
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)

Reply via email to