diff options
| author | maxv <maxv@NetBSD.org> | 2019-07-31 19:40:59 +0000 |
|---|---|---|
| committer | maxv <maxv@NetBSD.org> | 2019-07-31 19:40:59 +0000 |
| commit | b2bdfa6169625f471836f7c89851fe8ab3621d4f (patch) | |
| tree | 5a2b848e566c69fdfc52972632b36c91dcb2443d /sys/dev | |
| parent | 65423c12546025d0f57e87576062dbf8feb39197 (diff) | |
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@
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/usb/usb_subr.c | 10 | ||||
| -rw-r--r-- | sys/dev/usb/usbdi_util.c | 10 |
2 files changed, 13 insertions, 7 deletions
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c index 0291e45e8af..4948f33abaf 100644 --- a/sys/dev/usb/usb_subr.c +++ b/sys/dev/usb/usb_subr.c @@ -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 *dev, int ifaceidx, int altidx) 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 *dev, int index, int msg) 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); diff --git a/sys/dev/usb/usbdi_util.c b/sys/dev/usb/usbdi_util.c index 374ab9d8158..78203f0dbc7 100644 --- a/sys/dev/usb/usbdi_util.c +++ b/sys/dev/usb/usbdi_util.c @@ -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_interface *ifc) 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_interface *ifc, void **descp, int *sizep) 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); |
