Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/usb 1) Make sure we have a complete endpoint descrip...



details:   https://anonhg.NetBSD.org/src/rev/5da289f2047f
branches:  trunk
changeset: 458553:5da289f2047f
user:      maxv <maxv%NetBSD.org@localhost>
date:      Wed Jul 31 19:40:59 2019 +0000

description:
1) Make sure we have a complete endpoint descriptor header, otherwise
    small overflow.
 2) Make sure the total length of the bos descriptor did not change in
    the meantime, otherwise severe memory corruption.
 3) Make sure we have a complete hid descriptor header, otherwise
    small overflow.
 4) Error out if the report descriptor is zero-sized, otherwise panic.

ok skrll@ mrg@

diffstat:

 sys/dev/usb/usb_subr.c   |  10 ++++++----
 sys/dev/usb/usbdi_util.c |  10 +++++++---
 2 files changed, 13 insertions(+), 7 deletions(-)

diffs (76 lines):

diff -r f4dfb4ed5684 -r 5da289f2047f sys/dev/usb/usb_subr.c
--- a/sys/dev/usb/usb_subr.c    Wed Jul 31 18:35:58 2019 +0000
+++ b/sys/dev/usb/usb_subr.c    Wed Jul 31 19:40:59 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: usb_subr.c,v 1.235 2019/07/23 17:21:33 maxv Exp $      */
+/*     $NetBSD: usb_subr.c,v 1.236 2019/07/31 19:40:59 maxv Exp $      */
 /*     $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $   */
 
 /*
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.235 2019/07/23 17:21:33 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.236 2019/07/31 19:40:59 maxv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -452,7 +452,8 @@
                        DPRINTFN(10, "p=%#jx end=%#jx len=%jd type=%jd",
                            (uintptr_t)p, (uintptr_t)end, ed->bLength,
                            ed->bDescriptorType);
-                       if (p + ed->bLength <= end && ed->bLength != 0 &&
+                       if (p + ed->bLength <= end &&
+                           ed->bLength >= USB_ENDPOINT_DESCRIPTOR_SIZE &&
                            ed->bDescriptorType == UDESC_ENDPOINT)
                                goto found;
                        if (ed->bLength == 0 ||
@@ -659,7 +660,8 @@
                                        break;
                                usbd_delay_ms(dev, 200);
                        }
-                       if (err || bdp->bDescriptorType != UDESC_BOS) {
+                       if (err || bdp->bDescriptorType != UDESC_BOS ||
+                           UGETW(bdp->wTotalLength) != UGETW(bd.wTotalLength)) {
                                DPRINTF("error %jd or bad desc %jd", err,
                                    bdp->bDescriptorType, 0, 0);
                                kmem_free(bdp, blen);
diff -r f4dfb4ed5684 -r 5da289f2047f sys/dev/usb/usbdi_util.c
--- a/sys/dev/usb/usbdi_util.c  Wed Jul 31 18:35:58 2019 +0000
+++ b/sys/dev/usb/usbdi_util.c  Wed Jul 31 19:40:59 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: usbdi_util.c,v 1.73 2019/02/07 13:20:41 skrll Exp $    */
+/*     $NetBSD: usbdi_util.c,v 1.74 2019/07/31 19:40:59 maxv Exp $     */
 
 /*
  * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usbdi_util.c,v 1.73 2019/02/07 13:20:41 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usbdi_util.c,v 1.74 2019/07/31 19:40:59 maxv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -470,7 +470,9 @@
 
        for (; p < end; p += hd->bLength) {
                hd = (usb_hid_descriptor_t *)p;
-               if (p + hd->bLength <= end && hd->bDescriptorType == UDESC_HID)
+               if (p + hd->bLength <= end &&
+                   hd->bLength >= USB_HID_DESCRIPTOR_SIZE(0) &&
+                   hd->bDescriptorType == UDESC_HID)
                        return hd;
                if (hd->bDescriptorType == UDESC_INTERFACE)
                        break;
@@ -494,6 +496,8 @@
        if (hid == NULL)
                return USBD_IOERROR;
        *sizep = UGETW(hid->descrs[0].wDescriptorLength);
+       if (*sizep == 0)
+               return USBD_INVAL;
        *descp = kmem_alloc(*sizep, KM_SLEEP);
        err = usbd_get_report_descriptor(dev, id->bInterfaceNumber,
                                         *sizep, *descp);



Home | Main Index | Thread Index | Old Index