Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb Add missing length checks on descriptors, to pre...
details: https://anonhg.NetBSD.org/src/rev/e3347a6eb5e4
branches: trunk
changeset: 454367:e3347a6eb5e4
user: maxv <maxv%NetBSD.org@localhost>
date: Sun Sep 15 09:21:36 2019 +0000
description:
Add missing length checks on descriptors, to prevent buffer overflows.
Found via KASAN+vHCI. Some remain however, but it looks like the code
needs to be re-thought along the way, so it will be fixed later.
diffstat:
sys/dev/usb/uvideo.c | 25 ++++++++++++++++++++++---
1 files changed, 22 insertions(+), 3 deletions(-)
diffs (86 lines):
diff -r 1674172aac04 -r e3347a6eb5e4 sys/dev/usb/uvideo.c
--- a/sys/dev/usb/uvideo.c Sun Sep 15 09:18:17 2019 +0000
+++ b/sys/dev/usb/uvideo.c Sun Sep 15 09:21:36 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvideo.c,v 1.47 2019/05/05 03:17:54 mrg Exp $ */
+/* $NetBSD: uvideo.c,v 1.48 2019/09/15 09:21:36 maxv Exp $ */
/*
* Copyright (c) 2008 Patrick Mahoney
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvideo.c,v 1.47 2019/05/05 03:17:54 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvideo.c,v 1.48 2019/09/15 09:21:36 maxv Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -527,6 +527,12 @@
(ifdesc = usb_desc_iter_next_interface(&iter)) != NULL;
++ifaceidx)
{
+ if (ifdesc->bLength < USB_INTERFACE_DESCRIPTOR_SIZE) {
+ DPRINTFN(50, ("uvideo_attach: "
+ "ignoring incorrect descriptor len=%d\n",
+ ifdesc->bLength));
+ continue;
+ }
if (ifdesc->bInterfaceClass != UICLASS_VIDEO) {
DPRINTFN(50, ("uvideo_attach: "
"ignoring non-uvc interface: "
@@ -884,13 +890,17 @@
switch (desc->bDescriptorSubtype) {
case UDESC_INPUT_TERMINAL:
+ if (desc->bLength < sizeof(*input))
+ return USBD_INVAL;
input = (const uvideo_input_terminal_descriptor_t *)desc;
switch (UGETW(input->wTerminalType)) {
case UVIDEO_ITT_CAMERA:
+ if (desc->bLength < sizeof(*camera))
+ return USBD_INVAL;
camera =
(const uvideo_camera_terminal_descriptor_t *)desc;
+
ct = &vu->u.vu_camera;
-
ct->ct_objective_focal_min =
UGETW(camera->wObjectiveFocalLengthMin);
ct->ct_objective_focal_max =
@@ -911,12 +921,16 @@
case UDESC_OUTPUT_TERMINAL:
break;
case UDESC_SELECTOR_UNIT:
+ if (desc->bLength < sizeof(*selector))
+ return USBD_INVAL;
selector = (const uvideo_selector_unit_descriptor_t *)desc;
uvideo_unit_alloc_sources(vu, selector->bNrInPins,
selector->baSourceID);
break;
case UDESC_PROCESSING_UNIT:
+ if (desc->bLength < sizeof(*processing))
+ return USBD_INVAL;
processing = (const uvideo_processing_unit_descriptor_t *)desc;
pu = &vu->u.vu_processing;
@@ -928,6 +942,8 @@
processing->bmControls);
break;
case UDESC_EXTENSION_UNIT:
+ if (desc->bLength < sizeof(*extension))
+ return USBD_INVAL;
extension = (const uvideo_extension_unit_descriptor_t *)desc;
/* TODO: copy guid */
@@ -1081,6 +1097,9 @@
* interface descriptor, modifying the iterator. This may be called
* multiple times because there may be several alternate interfaces
* associated with the same interface number. */
+/*
+ * XXX XXX XXX: This function accesses descriptors in an unsafe manner.
+ */
static usbd_status
uvideo_stream_init_desc(struct uvideo_stream *vs,
const usb_interface_descriptor_t *ifdesc,
Home |
Main Index |
Thread Index |
Old Index