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@
This commit is contained in:
parent
2d8834ad2a
commit
1815c58abf
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user