Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/usb usbdi(9): Fix usbd_get_no_alts.



details:   https://anonhg.NetBSD.org/src/rev/2ce17eb32344
branches:  trunk
changeset: 364358:2ce17eb32344
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sat Mar 19 10:05:52 2022 +0000

description:
usbdi(9): Fix usbd_get_no_alts.

This incorrectly rejected the configuration as invalid if any
descriptor is not large enough to be interface descriptors.

Instead, it should reject the configuration only if any descriptor is
not large enough to be a _descriptor_, or if any interface-type
descriptor is not large enough to be an interface descriptor, but
skip over descriptors of other types even if they're smaller than
interface descriptors.

Candidate fix for PR kern/56762.

diffstat:

 sys/dev/usb/usbdi.c |  24 ++++++++++++++++--------
 1 files changed, 16 insertions(+), 8 deletions(-)

diffs (49 lines):

diff -r e6f765cd67fa -r 2ce17eb32344 sys/dev/usb/usbdi.c
--- a/sys/dev/usb/usbdi.c       Sat Mar 19 09:55:30 2022 +0000
+++ b/sys/dev/usb/usbdi.c       Sat Mar 19 10:05:52 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: usbdi.c,v 1.238 2022/03/13 13:07:39 riastradh Exp $    */
+/*     $NetBSD: usbdi.c,v 1.239 2022/03/19 10:05:52 riastradh Exp $    */
 
 /*
  * Copyright (c) 1998, 2012, 2015 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.238 2022/03/13 13:07:39 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.239 2022/03/19 10:05:52 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -973,16 +973,24 @@
 {
        char *p = (char *)cdesc;
        char *end = p + UGETW(cdesc->wTotalLength);
-       usb_interface_descriptor_t *d;
+       usb_descriptor_t *desc;
+       usb_interface_descriptor_t *idesc;
        int n;
 
-       for (n = 0; end - p >= sizeof(*d); p += d->bLength) {
-               d = (usb_interface_descriptor_t *)p;
-               if (d->bLength < sizeof(*d) || d->bLength > end - p)
+       for (n = 0; end - p >= sizeof(*desc); p += desc->bLength) {
+               desc = (usb_descriptor_t *)p;
+               if (desc->bLength < sizeof(*desc) || desc->bLength > end - p)
                        break;
-               if (d->bDescriptorType == UDESC_INTERFACE &&
-                   d->bInterfaceNumber == ifaceno)
+               if (desc->bDescriptorType != UDESC_INTERFACE)
+                       continue;
+               if (desc->bLength < sizeof(*idesc))
+                       break;
+               idesc = (usb_interface_descriptor_t *)desc;
+               if (idesc->bInterfaceNumber == ifaceno) {
                        n++;
+                       if (n == INT_MAX)
+                               break;
+               }
        }
        return n;
 }



Home | Main Index | Thread Index | Old Index