From 26ec74ac987bf91976edbc6896caaeb71b6d6e84 Mon Sep 17 00:00:00 2001 From: Andres Cera Date: Mon, 15 Jun 2026 18:03:29 -0500 Subject: [PATCH 1/2] fix(stream): accept smaller max payloads than requested (backport upstream 047920b) --- src/stream.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/stream.c b/src/stream.c index 3f3752f..a86ac6a 100644 --- a/src/stream.c +++ b/src/stream.c @@ -599,7 +599,9 @@ static int _uvc_stream_params_negotiated( uvc_stream_ctrl_t *actual) { return required->bFormatIndex == actual->bFormatIndex && required->bFrameIndex == actual->bFrameIndex && - required->dwMaxPayloadTransferSize == actual->dwMaxPayloadTransferSize; + /* Backport upstream 047920b (#273): the #178 equality check was too strict. + * Some HighSpeed USB cameras return a smaller Max payload than requested. */ + required->dwMaxPayloadTransferSize >= actual->dwMaxPayloadTransferSize; } /** @internal From 90cc67993047cd61d0b0a6c5bb62c4d61125cf80 Mon Sep 17 00:00:00 2001 From: Andres Cera Date: Mon, 15 Jun 2026 19:01:06 -0500 Subject: [PATCH 2/2] fix(security): guard uvc_scan_streaming NULL-deref (CVE-2026-1991) + backport e001f04 --- src/device.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/device.c b/src/device.c index aa09a39..2c63b6f 100644 --- a/src/device.c +++ b/src/device.c @@ -1072,12 +1072,13 @@ uvc_error_t uvc_scan_control(uvc_device_handle_t *devh, uvc_device_info_t *info) uvc_device_descriptor_t* dev_desc; int haveTISCamera = 0; - get_device_descriptor ( devh, &dev_desc ); - if ( 0x199e == dev_desc->idVendor && ( 0x8101 == dev_desc->idProduct || - 0x8102 == dev_desc->idProduct )) { - haveTISCamera = 1; + if ( get_device_descriptor ( devh, &dev_desc ) == UVC_SUCCESS ) { + if ( 0x199e == dev_desc->idVendor && ( 0x8101 == dev_desc->idProduct || + 0x8102 == dev_desc->idProduct )) { + haveTISCamera = 1; + } + uvc_free_device_descriptor ( dev_desc ); } - uvc_free_device_descriptor ( dev_desc ); for (interface_idx = 0; interface_idx < info->config->bNumInterfaces; ++interface_idx) { if_desc = &info->config->interface[interface_idx].altsetting[0]; @@ -1342,6 +1343,23 @@ uvc_error_t uvc_scan_streaming(uvc_device_t *dev, ret = UVC_SUCCESS; + /* CeraLive (CVE-2026-1991, libuvc issue #300): interface_idx arrives straight + * from an attacker-controlled VideoControl HEADER byte (baInterfaceNr, see + * uvc_parse_vc_header) with no validation. A malformed descriptor can name an + * interface index past config->bNumInterfaces (out-of-bounds read of the + * interface[] array) or one whose interface carries no altsetting + * (altsetting == NULL / num_altsetting == 0). Either way the unguarded + * info->config->interface[interface_idx].altsetting[0] dereference below + * faults. Reject both before any dereference. */ + if (interface_idx < 0 || interface_idx >= info->config->bNumInterfaces) { + UVC_EXIT(UVC_ERROR_INVALID_DEVICE); + return UVC_ERROR_INVALID_DEVICE; + } + if (info->config->interface[interface_idx].num_altsetting < 1) { + UVC_EXIT(UVC_ERROR_INVALID_DEVICE); + return UVC_ERROR_INVALID_DEVICE; + } + if_desc = &(info->config->interface[interface_idx].altsetting[0]); buffer = if_desc->extra; buffer_left = if_desc->extra_length;