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);

Reply via email to