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