Module Name: src Committed By: maxv Date: Wed Jul 31 19:40:59 UTC 2019
Modified Files: src/sys/dev/usb: usb_subr.c usbdi_util.c Log Message: 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@ To generate a diff of this commit: cvs rdiff -u -r1.235 -r1.236 src/sys/dev/usb/usb_subr.c cvs rdiff -u -r1.73 -r1.74 src/sys/dev/usb/usbdi_util.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.235 src/sys/dev/usb/usb_subr.c:1.236 --- src/sys/dev/usb/usb_subr.c:1.235 Tue Jul 23 17:21:33 2019 +++ src/sys/dev/usb/usb_subr.c Wed Jul 31 19:40:59 2019 @@ -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 @@ usbd_fill_iface_data(struct usbd_device 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 @@ usbd_set_config_index(struct usbd_device 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); Index: src/sys/dev/usb/usbdi_util.c diff -u src/sys/dev/usb/usbdi_util.c:1.73 src/sys/dev/usb/usbdi_util.c:1.74 --- src/sys/dev/usb/usbdi_util.c:1.73 Thu Feb 7 13:20:41 2019 +++ src/sys/dev/usb/usbdi_util.c Wed Jul 31 19:40:59 2019 @@ -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 @@ usbd_get_hid_descriptor(struct usbd_inte 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 @@ usbd_read_report_desc(struct usbd_interf 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);