DragonFlyBSD Kernel Audit
DF-1012 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/bus/u4b/uvc/uvc_drv.c b/sys/bus/u4b/uvc/uvc_drv.c
--- a/sys/bus/u4b/uvc/uvc_drv.c
+++ b/sys/bus/u4b/uvc/uvc_drv.c
@@ -1790,6 +1790,7 @@
 	struct usb_endpoint_ss_comp_descriptor *essd;
 	uint32_t interval;
 	int ret, i, ps;
+	int fmt_seen = 0;
 
 	if (data->iface->idesc->bInterfaceSubClass != UISUBCLASS_STREAMING) {
 		return EINVAL;
@@ -1840,6 +1841,8 @@
 		UDESC_CS_INTERFACE, 0xFF, 0, 0)) != NULL) {
 		switch (desc->bDescriptorSubtype) {
 		case UDESCSUB_VS_COLORFORMAT:
+			if (!fmt_seen)
+				break;
 			cld = (struct uvc_vs_color_desc *)desc;
 			fmt->colorspace
 				= uvc_drv_get_colorspace(cld->bColorPris);
@@ -1873,6 +1876,7 @@
 				}
 				fmt->bpp = raw->bBpp;
 			}
+			fmt_seen = 1;
 			break;
 		case UDESCSUB_VS_FORMAT_FRAME_BASED:
 			fmt++;
@@ -1893,11 +1897,14 @@
 			fmt->bpp = fbraw->bBitsPerpixel;
 			if (fbraw->bVariableSize)
 				fmt->flags = UVC_FMT_FLAG_COMPRESSED;
+			fmt_seen = 1;
 			break;
 		case UDESCSUB_VS_FRAME_UNCOMPRESSED:
 			if (sc->quirks & UVC_DROP_UNCOMPRESS_FORMAT)
 				break;
 		case UDESCSUB_VS_FRAME_MJPEG:
+			if (!fmt_seen)
+				break;
 			frmd = (struct uvc_vs_frame_desc *)desc;
 			frm->index = frmd->bFrameIndex;
 			frm->width = UGETW(frmd->wWidth);
@@ -1925,6 +1932,8 @@
 			frm++;
 			break;
 		case UDESCSUB_VS_FRAME_FRAME_BASED:
+			if (!fmt_seen)
+				break;
 			fbrmd = (struct uvc_vs_frame_based_desc *)desc;
 			frm->index = fbrmd->bFrameIndex;
 			frm->width = UGETW(fbrmd->wWidth);