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) If the descriptor length is bigger than the U...



details:   https://anonhg.NetBSD.org/src/rev/849527ff190f
branches:  trunk
changeset: 457874:849527ff190f
user:      maxv <maxv%NetBSD.org@localhost>
date:      Tue Jul 23 17:21:33 2019 +0000

description:
1) If the descriptor length is bigger than the USB string descriptor
    itself, error out. Otherwise there is a small overflow (seen on KASAN,
    with bLength=255).
 2) Make sure we have a config descriptor header, otherwise there are small
    overflows (seen on KASAN, with wTotalLength=1).
 3) Once we have the complete config descriptor, make sure its size didn't
    change in the meantime. Otherwise there could be severe overflows.
 4) Make sure we have a bos descriptor header, otherwise overflow, same
    as 2).

ok mrg@ skrll@

diffstat:

 sys/dev/usb/usb_subr.c |  15 +++++++++++----
 1 files changed, 11 insertions(+), 4 deletions(-)

diffs (57 lines):

diff -r 67f3a9420bd2 -r 849527ff190f sys/dev/usb/usb_subr.c
--- a/sys/dev/usb/usb_subr.c    Tue Jul 23 16:02:32 2019 +0000
+++ b/sys/dev/usb/usb_subr.c    Tue Jul 23 17:21:33 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: usb_subr.c,v 1.234 2019/07/19 04:18:49 mrg Exp $       */
+/*     $NetBSD: usb_subr.c,v 1.235 2019/07/23 17:21:33 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.234 2019/07/19 04:18:49 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.235 2019/07/23 17:21:33 maxv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_compat_netbsd.h"
@@ -135,6 +135,8 @@
        if (actlen < 2)
                return USBD_SHORT_XFER;
 
+       if (sdesc->bLength > sizeof(*sdesc))
+               return USBD_INVAL;
        USETW(req.wLength, sdesc->bLength);     /* the whole string */
        err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK,
                &actlen, USBD_DEFAULT_TIMEOUT);
@@ -607,7 +609,7 @@
                return err;
        }
        len = UGETW(cd.wTotalLength);
-       if (len == 0) {
+       if (len < USB_CONFIG_DESCRIPTOR_SIZE) {
                DPRINTF("empty short descriptor", 0, 0, 0, 0);
                return USBD_INVAL;
        }
@@ -629,6 +631,11 @@
                err = USBD_INVAL;
                goto bad;
        }
+       if (UGETW(cdp->wTotalLength) != UGETW(cd.wTotalLength)) {
+               DPRINTF("bad len %jd", UGETW(cdp->wTotalLength), 0, 0, 0);
+               err = USBD_INVAL;
+               goto bad;
+       }
 
        if (USB_IS_SS(dev->ud_speed)) {
                usb_bos_descriptor_t bd;
@@ -637,7 +644,7 @@
                err = usbd_get_bos_desc(dev, index, &bd);
                if (!err) {
                        int blen = UGETW(bd.wTotalLength);
-                       if (blen == 0) {
+                       if (blen < USB_BOS_DESCRIPTOR_SIZE) {
                                DPRINTF("empty bos descriptor", 0, 0, 0, 0);
                                err = USBD_INVAL;
                                goto bad;



Home | Main Index | Thread Index | Old Index