Module Name: src Committed By: maxv Date: Tue Jul 23 17:21:33 UTC 2019
Modified Files: src/sys/dev/usb: usb_subr.c Log Message: 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@ To generate a diff of this commit: cvs rdiff -u -r1.234 -r1.235 src/sys/dev/usb/usb_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/usb_subr.c diff -u src/sys/dev/usb/usb_subr.c:1.234 src/sys/dev/usb/usb_subr.c:1.235 --- src/sys/dev/usb/usb_subr.c:1.234 Fri Jul 19 04:18:49 2019 +++ src/sys/dev/usb/usb_subr.c Tue Jul 23 17:21:33 2019 @@ -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 @@ usbd_get_string_desc(struct usbd_device 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 @@ usbd_set_config_index(struct usbd_device 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 @@ usbd_set_config_index(struct usbd_device 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 @@ usbd_set_config_index(struct usbd_device 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;