AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/09/16 09:28 flow patch-triage
34m Args:
null

Results:
{
  "EnableConfigs": [
    "USB_VIDEO_CLASS",
    "MEDIA_SUPPORT",
    "MEDIA_CAMERA_SUPPORT",
    "USB"
  ],
  "FocusSymbols": [
    "uvc_parse_control",
    "uvc_parse_standard_control",
    "uvc_parse_vendor_control",
    "uvc_probe"
  ],
  "KMSANReasoning": "The patch enhances bounds checking and descriptor length validation in `uvc_parse_control()`:\n1. It validates that `buffer[0] \u003e= 3` and `buffer[0] \u003c= buflen`, preventing infinite loops or buffer underflow/out-of-bounds memory accesses when stepping through USB descriptors.\n2. It passes the individual descriptor length `buffer[0]` instead of the remaining total buffer length `buflen` to `uvc_parse_vendor_control()` and `uvc_parse_standard_control()`, preventing reading beyond the descriptor boundary.\n\nThese changes address out-of-bounds reads and loop bounds errors on USB descriptor buffers. No stack or heap structures are copied to user space, no uninitialized variables or paddings are exposed or branched upon, and all entity allocations use kzalloc(). Any potential bugs related to these bounds checks are within KASAN's detection capabilities (OOB access). Therefore, a dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false,
  "Reasoning": "The patch modifies descriptor bounds checking in uvc_parse_control() within the USB Video Class (UVC) driver, ensuring descriptor length buffer[0] is within buflen and at least 3 bytes, and passing the descriptor-specific length rather than the remaining buffer length to uvc_parse_vendor_control() and uvc_parse_standard_control(). This code is executed during USB device probe and is fully reachable via USB gadget emulation (e.g., syz_usb_connect or raw-gadget).",
  "WorthFuzzing": true
}

1/1 2026/09/16 09:28 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit cd1f319b30e622f5ed0d43897f2ef734a04d8f25\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Wed Sep 16 09:28:42 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c\nindex e289cc71ba986..429f1ab19a2ac 100644\n--- a/drivers/media/usb/uvc/uvc_driver.c\n+++ b/drivers/media/usb/uvc/uvc_driver.c\n@@ -1248,11 +1248,14 @@ static int uvc_parse_control(struct uvc_device *dev)\n \t */\n \n \twhile (buflen \u003e 2) {\n-\t\tif (uvc_parse_vendor_control(dev, buffer, buflen) ||\n+\t\tif (buflen \u003c buffer[0] || buffer[0] \u003c 3)\n+\t\t\treturn -EINVAL;\n+\n+\t\tif (uvc_parse_vendor_control(dev, buffer, buffer[0]) ||\n \t\t    buffer[1] != USB_DT_CS_INTERFACE)\n \t\t\tgoto next_descriptor;\n \n-\t\tret = uvc_parse_standard_control(dev, buffer, buflen);\n+\t\tret = uvc_parse_standard_control(dev, buffer, buffer[0]);\n \t\tif (ret \u003c 0)\n \t\t\treturn ret;\n \n"
}

2/1 2026/09/16 09:28 agent patch-evaluator
29m Model:
core

Args:
null

Results:
{
  "EnableConfigs": [
    "USB_VIDEO_CLASS",
    "MEDIA_SUPPORT",
    "MEDIA_CAMERA_SUPPORT",
    "USB"
  ],
  "FocusSymbols": [
    "uvc_parse_control",
    "uvc_parse_standard_control",
    "uvc_parse_vendor_control",
    "uvc_probe"
  ],
  "Reasoning": "The patch modifies descriptor bounds checking in uvc_parse_control() within the USB Video Class (UVC) driver, ensuring descriptor length buffer[0] is within buflen and at least 3 bytes, and passing the descriptor-specific length rather than the remaining buffer length to uvc_parse_vendor_control() and uvc_parse_standard_control(). This code is executed during USB device probe and is fully reachable via USB gadget emulation (e.g., syz_usb_connect or raw-gadget).",
  "WorthFuzzing": true
}

Instruction:
You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.

================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.

- REACHABILITY IS THE PRIMARY GATE:
  Fuzzing can only discover bugs in code that can actually execute in standard virtualized
  environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
  If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
  regardless of whether it adds assertions or complex logic.

- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
  Patch authors routinely label changes as "cleanups", "refactorings", or state
  "No functional change intended". Do NOT take these claims at face value.
  Code refactorings that rearrange logic, introduce helper functions, or alter state management
  in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
  If reachable executable code is modified or refactored, it MUST be fuzzed.

- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
  When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
  BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
  Even if the author believes the invariant always holds, fuzzing is essential to verify whether
  an unusual sequence of operations can violate it.

================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:

- Non-kernel and non-executable changes:
  * Modifications to Documentation/, comments, or spelling fixes.
  * User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
    that do not affect the compiled kernel image (vmlinux) or kernel modules.
  * Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
    that do not alter control flow or data structures.
  * Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
  * Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
    ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
  * Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
    physical PCI hot-unplug or manual sysfs driver unbinding.
  * Code paths exclusive to architectures other than the target architecture.

================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
  * Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
    BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
  * Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
  * Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
  * Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).

================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:

- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
  Do NOT list generic, ubiquitous functions called by almost every program in the corpus
  (including, but not limited to: general memory allocators and deallocators, page fault
  and trap handlers, or core synchronization primitives; this is not an exhaustive list).
  Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
  which severely dilutes fuzzing effort away from the actual changes.

- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
  List functions that specifically implement the logic being added or altered, or direct API entrypoints
  for the subsystem feature under review.

- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
  Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
  distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
  If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
  functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).

================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
Target architecture: amd64

For your convenience, here is the diff of the changes:
commit cd1f319b30e622f5ed0d43897f2ef734a04d8f25
Author: syz-cluster <triage@syzkaller.com>
Date:   Wed Sep 16 09:28:42 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index e289cc71ba986..429f1ab19a2ac 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -1248,11 +1248,14 @@ static int uvc_parse_control(struct uvc_device *dev)
 	 */
 
 	while (buflen > 2) {
-		if (uvc_parse_vendor_control(dev, buffer, buflen) ||
+		if (buflen < buffer[0] || buffer[0] < 3)
+			return -EINVAL;
+
+		if (uvc_parse_vendor_control(dev, buffer, buffer[0]) ||
 		    buffer[1] != USB_DT_CS_INTERFACE)
 			goto next_descriptor;
 
-		ret = uvc_parse_standard_control(dev, buffer, buflen);
+		ret = uvc_parse_standard_control(dev, buffer, buffer[0]);
 		if (ret < 0)
 			return ret;
 

3/2 2026/09/16 09:28 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 2992
							output: 44
							thoughts: 393
						

Thoughts:
**Analyzing the UVC Driver Patch**

Okay, so I'm looking at this patch for the UVC driver. The change is in `uvc_driver.c`, specifically within the `uvc_parse_control` function. I see the main modification involves how we handle the parsing of control descriptors. The original code used `buflen` directly in the calls to `uvc_parse_vendor_control` and `uvc_parse_standard_control`. Now, we're using `buffer[0]` instead of the `buflen` argument in these function calls.

My initial thought is that this is likely a safety improvement. It looks like it's trying to prevent out-of-bounds reads. We're now checking if `buflen` is less than `buffer[0]` or if `buffer[0]` is less than 3, returning an error (`-EINVAL`) if so, which implies that `buffer[0]` probably specifies the length of the current descriptor. This is good practice. This also means we are now passing the length of the current descriptor block, not the remaining buffer, to the parse functions. This is potentially a big improvement. The prior code might have been vulnerable to an exploit where a malformed descriptor could cause reads beyond the allocated buffer.

I need to confirm this assumption. Let me pull up `uvc_driver.c` to examine `uvc_parse_vendor_control` and `uvc_parse_standard_control` and how they use these length parameters to be sure. Let me use `read-file` to check `uvc_driver.c`. I'm also going to check to see what the return value indicates. I need to make sure this doesn't introduce any regressions or performance impacts.



4/2 2026/09/16 09:29 tool read-file
0m Args:
{
  "File": "drivers/media/usb/uvc/uvc_driver.c",
  "FirstLine": 1240,
  "LineCount": 50
}

Results:
{
  "Contents": "1240:\t\tconst unsigned char *buffer = alts-\u003eextra;\n1241:\t\tint buflen = alts-\u003eextralen;\n1242:\t\tint ret;\n1243:\t\n1244:\t\t/*\n1245:\t\t * Parse the default alternate setting only, as the UVC specification\n1246:\t\t * defines a single alternate setting, the default alternate setting\n1247:\t\t * zero.\n1248:\t\t */\n1249:\t\n1250:\t\twhile (buflen \u003e 2) {\n1251:\t\t\tif (buflen \u003c buffer[0] || buffer[0] \u003c 3)\n1252:\t\t\t\treturn -EINVAL;\n1253:\t\n1254:\t\t\tif (uvc_parse_vendor_control(dev, buffer, buffer[0]) ||\n1255:\t\t\t    buffer[1] != USB_DT_CS_INTERFACE)\n1256:\t\t\t\tgoto next_descriptor;\n1257:\t\n1258:\t\t\tret = uvc_parse_standard_control(dev, buffer, buffer[0]);\n1259:\t\t\tif (ret \u003c 0)\n1260:\t\t\t\treturn ret;\n1261:\t\n1262:\tnext_descriptor:\n1263:\t\t\tbuflen -= buffer[0];\n1264:\t\t\tbuffer += buffer[0];\n1265:\t\t}\n1266:\t\n1267:\t\t/*\n1268:\t\t * Check if the optional status endpoint is present. Built-in iSight\n1269:\t\t * webcams have an interrupt endpoint but spit proprietary data that\n1270:\t\t * don't conform to the UVC status endpoint messages. Don't try to\n1271:\t\t * handle the interrupt endpoint for those cameras.\n1272:\t\t */\n1273:\t\tif (alts-\u003edesc.bNumEndpoints == 1 \u0026\u0026\n1274:\t\t    !(dev-\u003equirks \u0026 UVC_QUIRK_BUILTIN_ISIGHT)) {\n1275:\t\t\tstruct usb_host_endpoint *ep = \u0026alts-\u003eendpoint[0];\n1276:\t\t\tstruct usb_endpoint_descriptor *desc = \u0026ep-\u003edesc;\n1277:\t\n1278:\t\t\tif (usb_endpoint_is_int_in(desc) \u0026\u0026\n1279:\t\t\t    le16_to_cpu(desc-\u003ewMaxPacketSize) \u003e= 8 \u0026\u0026\n1280:\t\t\t    desc-\u003ebInterval != 0) {\n1281:\t\t\t\tuvc_dbg(dev, DESCR,\n1282:\t\t\t\t\t\"Found a Status endpoint (addr %02x)\\n\",\n1283:\t\t\t\t\tdesc-\u003ebEndpointAddress);\n1284:\t\t\t\tdev-\u003eint_ep = ep;\n1285:\t\t\t}\n1286:\t\t}\n1287:\t\n1288:\t\treturn 0;\n1289:\t}\n"
}

5/2 2026/09/16 09:29 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 4560
							output: 34
							thoughts: 28
						

Thoughts:
Okay, here's my take on those thoughts, tailored for an expert audience:

**Investigating the `uvcvideo` Driver Configuration**

Right, so we're dealing with the `uvcvideo` driver. Naturally, my first instinct is to dive into the Kconfig. I want to quickly ascertain the configuration prerequisites and dependencies for this driver. Are there any specific kernel features that need to be enabled before `uvcvideo` can even come into play? I'm thinking, are there any obscure flags that might be tripping things up, or maybe some core USB subsystem settings that are non-negotiable? This initial Kconfig check will give me a solid foundation for understanding the driver's build environment and any potential configuration pitfalls. I'm looking for the "gotchas" before I even start to look at source code.



6/2 2026/09/16 09:29 tool grepper
0m Args:
{
  "Expression": "config USB_VIDEO_CLASS",
  "PathPrefix": "drivers/media/usb/uvc"
}

Results:
{
  "Output": "drivers/media/usb/uvc/Kconfig-1-# SPDX-License-Identifier: GPL-2.0-only\ndrivers/media/usb/uvc/Kconfig:2:config USB_VIDEO_CLASS\ndrivers/media/usb/uvc/Kconfig-3-\ttristate \"USB Video Class (UVC)\"\n--\ndrivers/media/usb/uvc/Kconfig-12-\ndrivers/media/usb/uvc/Kconfig:13:config USB_VIDEO_CLASS_INPUT_EVDEV\ndrivers/media/usb/uvc/Kconfig-14-\tbool \"UVC input events device support\"\n"
}

7/2 2026/09/16 09:29 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 4955
							output: 37
							thoughts: 17
						

Thoughts:
Here's a summary of my thought process, as if I were considering the provided text:

**Analyzing the Kconfig for UVC Driver Configuration**

Okay, time to dive into `drivers/media/usb/uvc/Kconfig`. I'm going to quickly scan this and understand how the UVC (USB Video Class) driver is configured within the kernel. My primary focus is on the various options presented, the dependencies between them, and how they relate to the broader media subsystem. I want to see:

*   **Main Configuration:** The top-level `UVC` option itself. Is it a module, or built-in? What does enabling/disabling it imply for the overall kernel configuration?
*   **Sub-Options:** What granular features can be enabled? Are there specific camera models or sensor types that can be selected? What about support for different UVC versions or extensions?
*   **Dependencies:** What other kernel components or drivers must be enabled or configured for the UVC driver to work correctly? Are there dependencies on USB core components, or specific media frameworks?
*   **Default Values and Help Text:** The default values are important, and the help text will tell me what specific circumstances might dictate a change.
*   **Conditional Compilation:** Any `select` statements that control whether specific features or modules are compiled into the kernel. What does this reveal about module relationships?

Essentially, I'm trying to mentally construct a configuration "map" for this driver. This will help me understand how to best configure UVC support for a given use case, and to debug any issues that might arise during the build or runtime. Knowing the dependencies helps me understand how any bugs or features might interact with other drivers and the media subsystem. I will be sure to note any unusual or unexpected configuration options.



8/2 2026/09/16 09:30 tool read-file
0m Args:
{
  "File": "drivers/media/usb/uvc/Kconfig",
  "FirstLine": 1,
  "LineCount": 40
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: GPL-2.0-only\n   2:\tconfig USB_VIDEO_CLASS\n   3:\t\ttristate \"USB Video Class (UVC)\"\n   4:\t\tdepends on VIDEO_DEV\n   5:\t\tselect VIDEOBUF2_VMALLOC\n   6:\t\tselect UVC_COMMON\n   7:\t\thelp\n   8:\t\t  Support for the USB Video Class (UVC).  Currently only video\n   9:\t\t  input devices, such as webcams, are supported.\n  10:\t\n  11:\t\t  For more information see: \u003chttp://linux-uvc.berlios.de/\u003e\n  12:\t\n  13:\tconfig USB_VIDEO_CLASS_INPUT_EVDEV\n  14:\t\tbool \"UVC input events device support\"\n  15:\t\tdefault y\n  16:\t\tdepends on USB_VIDEO_CLASS\n  17:\t\tdepends on USB_VIDEO_CLASS=INPUT || INPUT=y\n  18:\t\thelp\n  19:\t\t  This option makes USB Video Class devices register an input device\n  20:\t\t  to report button events.\n  21:\t\n  22:\t\t  If you are in doubt, say Y.\n"
}

9/2 2026/09/16 09:30 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 5689
							output: 27
							thoughts: 34
						

Thoughts:
Okay, here's my take on those thoughts, framed as my own:

**Investigating the VIDEO_DEV Configuration Option**

Right, let's get down to brass tacks. I need to figure out where the `VIDEO_DEV` configuration option is defined. My first instinct, and a pretty solid starting point, is to dive straight into the relevant Kconfig files. Considering the context, `drivers/media/v4l2-core/Kconfig` seems like the most likely candidate, since it's core to the v4l2 framework. If that doesn't pan out, the parent `drivers/media/Kconfig` is the fallback. These are the usual suspects when you're tracking down kernel configuration options related to media devices. Time to dig in and see what's what.



10/2 2026/09/16 09:30 tool grepper
0m Args:
{
  "Expression": "config VIDEO_DEV",
  "PathPrefix": "drivers/media"
}

Results:
{
  "Output": "drivers/media/Kconfig=157=menu \"Media core support\"\n--\ndrivers/media/Kconfig-159-\ndrivers/media/Kconfig:160:config VIDEO_DEV\ndrivers/media/Kconfig-161-\ttristate \"Video4Linux core\"\n"
}

11/2 2026/09/16 09:30 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 6003
							output: 34
							thoughts: 19
						

Thoughts:
Here's my take on the thought process, as requested:

**Navigating the Kernel's Media Subsystem Configuration**

Okay, so I need to dive into the kernel configuration for media-related drivers. My initial thought is to zero in on `drivers/media/Kconfig`. That's usually the go-to spot for the top-level configuration options. Let's see... and I'm guessing that line 160 is where I should focus. I bet that's a key entry point or a branching point for a particular set of devices or configurations. Time to get my hands dirty and investigate what's described there. Let's start from there and see where the trail leads.



12/2 2026/09/16 09:30 tool read-file
0m Args:
{
  "File": "drivers/media/Kconfig",
  "FirstLine": 150,
  "LineCount": 40
}

Results:
{
  "Contents": " 150:\t\t  Say Y if you want to use some virtual test driver.\n 151:\t\n 152:\t\t  In case of doubts, say N.\n 153:\t\t  Say Y when you have a software defined radio device.\n 154:\tendmenu # media device types\n 155:\t\n 156:\t\n 157:\tmenu \"Media core support\"\n 158:\t\tvisible if !MEDIA_SUPPORT_FILTER\n 159:\t\n 160:\tconfig VIDEO_DEV\n 161:\t\ttristate \"Video4Linux core\"\n 162:\t\tdefault MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT || MEDIA_SDR_SUPPORT || MEDIA_PLATFORM_SUPPORT || MEDIA_TEST_SUPPORT\n 163:\t\tdepends on (I2C || I2C=n)\n 164:\t\tselect RATIONAL\n 165:\t\tselect VIDEOBUF2_V4L2 if VIDEOBUF2_CORE\n 166:\t\thelp\n 167:\t\t  Enables the V4L2 API, used by cameras, analog TV, video grabbers,\n 168:\t\t  radio devices and by some input devices.\n 169:\t\n 170:\tconfig MEDIA_CONTROLLER\n 171:\t\tbool \"Media Controller API\"\n 172:\t\tdefault MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_PLATFORM_SUPPORT\n 173:\t\thelp\n 174:\t\t  Enable the media controller API used to query media devices internal\n 175:\t\t  topology and configure it dynamically.\n 176:\t\n 177:\t\t  This API is mostly used by camera interfaces in embedded platforms.\n 178:\t\n 179:\t#\n 180:\t# DVB Core\n 181:\t#\tOnly enables if one of DTV is selected\n 182:\t#\n 183:\t\n 184:\tconfig DVB_CORE\n 185:\t\ttristate \"DVB Core\"\n 186:\t\tdepends on MEDIA_DIGITAL_TV_SUPPORT\n 187:\t\tdepends on (I2C || I2C=n)\n 188:\t\tdefault MEDIA_DIGITAL_TV_SUPPORT\n 189:\t\tselect CRC32\n"
}

13/2 2026/09/16 09:30 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 6809
							output: 32
							thoughts: 16
						

Thoughts:
Here's my take on those thoughts:

**Checking the MEDIA_SUPPORT Configuration Option**

Okay, so I need to get my bearings. Let's start with `drivers/media/Kconfig`. I need to figure out how this specific media support feature is configured within the kernel. I'm assuming there's a corresponding configuration option for it, likely named `MEDIA_SUPPORT`, and I need to verify that. This is the first logical step, making sure the broader media framework is even enabled before I dig into anything more specific. I need to understand the relationship between this and the other, more specific configurations. The `Kconfig` files are the bread and butter of understanding the kernel's build system and dependencies, and that's where I need to be. Knowing where this is defined will help me immensely.



14/2 2026/09/16 09:30 tool read-file
0m Args:
{
  "File": "drivers/media/Kconfig",
  "FirstLine": 1,
  "LineCount": 40
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: GPL-2.0-only\n   2:\t#\n   3:\t# Multimedia device configuration\n   4:\t#\n   5:\t\n   6:\t#\n   7:\t# NOTE: CEC and Remote Controller support should not depend on MEDIA_SUPPORT\n   8:\t#\n   9:\tsource \"drivers/media/rc/Kconfig\"\n  10:\tsource \"drivers/media/cec/Kconfig\"\n  11:\t\n  12:\tmenuconfig MEDIA_SUPPORT\n  13:\t\ttristate \"Multimedia support\"\n  14:\t\tdepends on HAS_IOMEM\n  15:\t\thelp\n  16:\t\t  If you want to use media devices, including Webcams, Video grabber\n  17:\t\t  devices and/or TV devices, V4L2 codecs, etc, enable this option\n  18:\t\t  and other options below.\n  19:\t\n  20:\t\t  Additional info and docs are available on the web at\n  21:\t\t  \u003chttps://linuxtv.org\u003e\n  22:\t\n  23:\tif MEDIA_SUPPORT\n  24:\t\n  25:\tconfig MEDIA_SUPPORT_FILTER\n  26:\t\tbool \"Filter media drivers\"\n  27:\t\tdefault y if !EXPERT\n  28:\t\thelp\n  29:\t\t   Configuring the media subsystem can be complex, as there are\n  30:\t\t   hundreds of drivers and other config options.\n  31:\t\n  32:\t\t   This menu offers option that will help the Kernel's config\n  33:\t\t   system to hide drivers that are out of the scope of the\n  34:\t\t   user needs, and disabling core support for unused APIs.\n  35:\t\n  36:\t\t   If not selected, all non-optional media core functionality\n  37:\t\t   needed to support media drivers will be enabled. Also, all\n  38:\t\t   media device drivers should be shown.\n  39:\t\n  40:\tconfig MEDIA_SUBDRV_AUTOSELECT\n"
}

15/2 2026/09/16 09:30 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 7541
							output: 34
							thoughts: 36
						

Thoughts:
**Examining USB Video Class Requirements**

Okay, so I need to figure out why USB is required for USB_VIDEO_CLASS, specifically in the kernel's media/usb drivers. Let's dig into the `drivers/media/usb/Kconfig` file. That's the logical place to start – the Kconfig files usually hold the dependency information for configuration options. I need to understand the relationship and any potential implications here. Time to get my hands dirty.



16/2 2026/09/16 09:30 tool read-file
0m Args:
{
  "File": "drivers/media/usb/Kconfig",
  "FirstLine": 1,
  "LineCount": 40
}

Results:
{
  "Contents": "   1:\t# SPDX-License-Identifier: GPL-2.0-only\n   2:\t\n   3:\tif USB \u0026\u0026 MEDIA_SUPPORT\n   4:\t\n   5:\tmenuconfig MEDIA_USB_SUPPORT\n   6:\t\tbool \"Media USB Adapters\"\n   7:\t\thelp\n   8:\t\t  Enable media drivers for USB bus.\n   9:\t\t  If you have such devices, say Y.\n  10:\t\n  11:\tif MEDIA_USB_SUPPORT\n  12:\t\n  13:\tif MEDIA_CAMERA_SUPPORT\n  14:\t\tcomment \"Webcam devices\"\n  15:\t\n  16:\tsource \"drivers/media/usb/gspca/Kconfig\"\n  17:\tsource \"drivers/media/usb/pwc/Kconfig\"\n  18:\tsource \"drivers/media/usb/s2255/Kconfig\"\n  19:\tsource \"drivers/media/usb/usbtv/Kconfig\"\n  20:\tsource \"drivers/media/usb/uvc/Kconfig\"\n  21:\t\n  22:\tendif\n  23:\t\n  24:\tif MEDIA_ANALOG_TV_SUPPORT\n  25:\t\tcomment \"Analog TV USB devices\"\n  26:\t\n  27:\tsource \"drivers/media/usb/go7007/Kconfig\"\n  28:\tsource \"drivers/media/usb/hdpvr/Kconfig\"\n  29:\tsource \"drivers/media/usb/pvrusb2/Kconfig\"\n  30:\tsource \"drivers/media/usb/stk1160/Kconfig\"\n  31:\t\n  32:\tendif\n  33:\t\n  34:\tif (MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT)\n  35:\t\tcomment \"Analog/digital TV USB devices\"\n  36:\t\n  37:\tsource \"drivers/media/usb/au0828/Kconfig\"\n  38:\tsource \"drivers/media/usb/cx231xx/Kconfig\"\n  39:\t\n  40:\tendif\n"
}

17/2 2026/09/16 09:30 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 8248
							output: 34
							thoughts: 131
						

Thoughts:
**My Analysis of USB Video Class Fuzzing**

Okay, so the landscape here is pretty clear. We're talking about fuzzing USB Video Class, and the entry point is definitely USB emulation. We're getting to UVC through tools like syzkaller, either via raw gadget emulation or the vusb approach with `/dev/raw-gadget` or directly through the syz_usb_connect call. That's a solid start. The power of syzkaller in this context is pretty impressive – we can define and connect emulated USB devices with *any* descriptor, which is crucial for uncovering vulnerabilities.

And, of course, syzkaller has built-in UVC definitions and the more generic `syz_usb_connect` function for descriptor injection. The critical trigger is when a device descriptor triggers the matching of UVC class interface descriptors. Once that's detected, the `uvc_probe` function gets called. Now, where the real analysis begins: I need to delve into how `uvc_probe` subsequently calls `uvc_parse_control`. This is where I'll be looking for parsing bugs and potential vulnerabilities. That's the key: the path from emulated descriptors to the critical `uvc_parse_control` function is where the fuzzing campaign focuses.



18/2 2026/09/16 09:31 tool grepper
0m Args:
{
  "Expression": "uvc_parse_control",
  "PathPrefix": "drivers/media/usb/uvc"
}

Results:
{
  "Output": "drivers/media/usb/uvc/uvc_driver.c=968=static int uvc_parse_standard_control(struct uvc_device *dev,\n--\ndrivers/media/usb/uvc/uvc_driver.c-1236-\ndrivers/media/usb/uvc/uvc_driver.c:1237:static int uvc_parse_control(struct uvc_device *dev)\ndrivers/media/usb/uvc/uvc_driver.c-1238-{\n--\ndrivers/media/usb/uvc/uvc_driver.c=2189=static int uvc_probe(struct usb_interface *intf,\n--\ndrivers/media/usb/uvc/uvc_driver.c-2264-\t/* Parse the Video Class control descriptor. */\ndrivers/media/usb/uvc/uvc_driver.c:2265:\tret = uvc_parse_control(dev);\ndrivers/media/usb/uvc/uvc_driver.c-2266-\tif (ret \u003c 0) {\n"
}

19/2 2026/09/16 09:31 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 8963
							output: 43
							thoughts: 428
						

Thoughts:
**Analyzing the UVC Control Parsing Logic**

Okay, let's dive into this `uvc_probe` and specifically `uvc_parse_control` routine. I need to understand what's changed in how the descriptor lengths are handled.

Initially, I see the loop in `uvc_parse_control` used to look like this: the code was passing `buflen` to `uvc_parse_vendor_control` and `uvc_parse_standard_control`. Now, after the patch, the code passes `buffer[0]` (the length field from the descriptor) instead. Also, they've added this crucial check: `if (buflen < buffer[0] || buffer[0] < 3) return -EINVAL;`. This is significant! This check ensures the descriptor length in `buffer[0]` is valid – that it doesn't exceed the remaining buffer length (`buflen`) and that it's at least the minimum valid length of 3. That's a very good safety check. I need to understand why this was done.

To get the complete picture, I need to see how these length parameters are *actually* used within the `uvc_parse_standard_control` and `uvc_parse_vendor_control` functions. I'll read through lines 968-1050 of `uvc_driver.c` to see how the code handles `buflen` there. That should shed some light on the potential issue this patch is addressing.



20/2 2026/09/16 09:31 tool read-file
0m Args:
{
  "File": "drivers/media/usb/uvc/uvc_driver.c",
  "FirstLine": 965,
  "LineCount": 80
}

Results:
{
  "Contents": " 965:\t\treturn handled;\n 966:\t}\n 967:\t\n 968:\tstatic int uvc_parse_standard_control(struct uvc_device *dev,\n 969:\t\tconst unsigned char *buffer, int buflen)\n 970:\t{\n 971:\t\tstruct usb_device *udev = dev-\u003eudev;\n 972:\t\tstruct uvc_entity *unit, *term;\n 973:\t\tstruct usb_interface *intf;\n 974:\t\tstruct usb_host_interface *alts = dev-\u003eintf-\u003ecur_altsetting;\n 975:\t\tunsigned int i, n, p, len;\n 976:\t\tconst char *type_name;\n 977:\t\tunsigned int id;\n 978:\t\tu16 type;\n 979:\t\n 980:\t\tswitch (buffer[2]) {\n 981:\t\tcase UVC_VC_HEADER:\n 982:\t\t\tn = buflen \u003e= 12 ? buffer[11] : 0;\n 983:\t\n 984:\t\t\tif (buflen \u003c 12 + n) {\n 985:\t\t\t\tuvc_dbg(dev, DESCR,\n 986:\t\t\t\t\t\"device %d videocontrol interface %d HEADER error\\n\",\n 987:\t\t\t\t\tudev-\u003edevnum, alts-\u003edesc.bInterfaceNumber);\n 988:\t\t\t\treturn -EINVAL;\n 989:\t\t\t}\n 990:\t\n 991:\t\t\tdev-\u003euvc_version = get_unaligned_le16(\u0026buffer[3]);\n 992:\t\t\tdev-\u003eclock_frequency = get_unaligned_le32(\u0026buffer[7]);\n 993:\t\n 994:\t\t\t/* Parse all USB Video Streaming interfaces. */\n 995:\t\t\tfor (i = 0; i \u003c n; ++i) {\n 996:\t\t\t\tintf = usb_ifnum_to_if(udev, buffer[12+i]);\n 997:\t\t\t\tif (intf == NULL) {\n 998:\t\t\t\t\tuvc_dbg(dev, DESCR,\n 999:\t\t\t\t\t\t\"device %d interface %d doesn't exists\\n\",\n1000:\t\t\t\t\t\tudev-\u003edevnum, i);\n1001:\t\t\t\t\tcontinue;\n1002:\t\t\t\t}\n1003:\t\n1004:\t\t\t\tuvc_parse_streaming(dev, intf);\n1005:\t\t\t}\n1006:\t\t\tbreak;\n1007:\t\n1008:\t\tcase UVC_VC_INPUT_TERMINAL:\n1009:\t\t\tif (buflen \u003c 8) {\n1010:\t\t\t\tuvc_dbg(dev, DESCR,\n1011:\t\t\t\t\t\"device %d videocontrol interface %d INPUT_TERMINAL error\\n\",\n1012:\t\t\t\t\tudev-\u003edevnum, alts-\u003edesc.bInterfaceNumber);\n1013:\t\t\t\treturn -EINVAL;\n1014:\t\t\t}\n1015:\t\n1016:\t\t\t/*\n1017:\t\t\t * Reject invalid terminal types that would cause issues:\n1018:\t\t\t *\n1019:\t\t\t * - The high byte must be non-zero, otherwise it would be\n1020:\t\t\t *   confused with a unit.\n1021:\t\t\t *\n1022:\t\t\t * - Bit 15 must be 0, as we use it internally as a terminal\n1023:\t\t\t *   direction flag.\n1024:\t\t\t *\n1025:\t\t\t * Other unknown types are accepted.\n1026:\t\t\t */\n1027:\t\t\ttype = get_unaligned_le16(\u0026buffer[4]);\n1028:\t\t\tif ((type \u0026 0x7f00) == 0 || (type \u0026 0x8000) != 0) {\n1029:\t\t\t\tuvc_dbg(dev, DESCR,\n1030:\t\t\t\t\t\"device %d videocontrol interface %d INPUT_TERMINAL %d has invalid type 0x%04x, skipping\\n\",\n1031:\t\t\t\t\tudev-\u003edevnum, alts-\u003edesc.bInterfaceNumber,\n1032:\t\t\t\t\tbuffer[3], type);\n1033:\t\t\t\treturn 0;\n1034:\t\t\t}\n1035:\t\n1036:\t\t\tn = 0;\n1037:\t\t\tp = 0;\n1038:\t\t\tlen = 8;\n1039:\t\n1040:\t\t\tif (type == UVC_ITT_CAMERA) {\n1041:\t\t\t\tn = buflen \u003e= 15 ? buffer[14] : 0;\n1042:\t\t\t\tlen = 15;\n1043:\t\n1044:\t\t\t} else if (type == UVC_ITT_MEDIA_TRANSPORT_INPUT) {\n"
}

21/2 2026/09/16 09:31 llm patch-evaluator
23m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 11001
							output: 35
							thoughts: 511
						

Thoughts:
**Analyzing a UVC Descriptor Parsing Change**

Okay, so I'm looking at this change in `uvc_parse_standard_control`, and it's a subtle but important fix. Previously, `buflen` was passed around, which represented the *total* remaining buffer length containing all concatenated descriptors. Now, there are three key changes: a length check `if (buflen < buffer[0] || buffer[0] < 3) return -EINVAL;`, and the calls to `uvc_parse_vendor_control` and `uvc_parse_standard_control` are now using `buffer[0]` as the length argument. Each descriptor's length is defined by `buffer[0]` (the `bLength` field in the standard USB descriptor format).

Before, passing the total remaining length (`buflen`) meant that checks within the parsing functions like `if (buflen < 12 + n)` were effectively checking against the entire *remaining* buffer, not just the current descriptor's intended size. That's a problem! A descriptor might have a smaller `bLength` than the structure expected, but the `buflen` might indicate that there are other descriptors following it, leading to a potential out-of-bounds read. This change restricts the parsing to the descriptor's actual `bLength`, preventing that vulnerability.

The next question is always, "is this reachable in fuzzing?". Well, the good news is that syzkaller *does* have USB emulation capabilities, specifically through raw-gadget or the Dummy HCD.  It can feed USB descriptors to probe USB drivers, including `uvcvideo`. When a USB device, particularly one with the Video class, is attached, `uvc_probe()` is executed, which in turn calls `uvc_parse_control()`.  This means it is very likely reachable, and there is an explicit "WorthFuzzing=true" in the documentation for USB gadget emulation.

Now, let's nail down what specifically changed. I see that `uvc_parse_control` was directly modified, and `uvc_parse_standard_control` and `uvc_parse_vendor_control` *received* the modified length argument. `uvc_probe` is the driver's entry point, of course. I should check the git log for the commit for more context on the author's intent.



22/2 2026/09/16 09:54 tool grepper
0m Args:
{
  "Expression": "uvc_parse_control",
  "PathPrefix": "drivers/media/usb/uvc/"
}

Results:
{
  "Output": "drivers/media/usb/uvc/uvc_driver.c=968=static int uvc_parse_standard_control(struct uvc_device *dev,\n--\ndrivers/media/usb/uvc/uvc_driver.c-1236-\ndrivers/media/usb/uvc/uvc_driver.c:1237:static int uvc_parse_control(struct uvc_device *dev)\ndrivers/media/usb/uvc/uvc_driver.c-1238-{\n--\ndrivers/media/usb/uvc/uvc_driver.c=2189=static int uvc_probe(struct usb_interface *intf,\n--\ndrivers/media/usb/uvc/uvc_driver.c-2264-\t/* Parse the Video Class control descriptor. */\ndrivers/media/usb/uvc/uvc_driver.c:2265:\tret = uvc_parse_control(dev);\ndrivers/media/usb/uvc/uvc_driver.c-2266-\tif (ret \u003c 0) {\n"
}

23/2 2026/09/16 09:54 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 12337
							output: 37
							thoughts: 193
						

Thoughts:
**Analyzing UVC Control Parsing**

Okay, let's dive into this. I need to understand how these UVC control parsing functions work. Specifically, I want to look at `uvc_parse_control`, `uvc_parse_standard_control`, `uvc_parse_vendor_control`, and the `uvc_probe` function. The first thing I'm curious about is whether `uvc_parse_control`, `uvc_parse_standard_control`, and `uvc_parse_vendor_control` are static functions. If they are, that gives us an important piece of the puzzle right away. Also, I need to consider whether the compiler might be inlining them.

From what I can tell, `uvc_parse_control` is called only once, inside `uvc_probe`. My gut tells me it's *likely* the compiler will inline it directly into `uvc_probe` for performance. However, I need to confirm this. Looking at `uvc_probe` itself, it doesn't appear to be inlined since it's passed as a function pointer within the `struct usb_driver uvc_driver` structure.

Now, for `uvc_parse_standard_control` and `uvc_parse_vendor_control`, I see they're both static functions, defined within `uvc_driver.c`. This tells me their scope is limited to this specific file, which is important for understanding how they interact with the rest of the driver.

Next step: I need to closely examine the definitions and callers of each of these functions. I'll get a better picture of their roles and dependencies if I do this.



24/2 2026/09/16 09:55 tool grepper
0m Args:
{
  "Expression": "uvc_parse_vendor_control",
  "PathPrefix": "drivers/media/usb/uvc/"
}

Results:
{
  "Output": "drivers/media/usb/uvc/uvc_driver.c=871=static void uvc_entity_set_name(struct uvc_device *dev, struct uvc_entity *entity,\n--\ndrivers/media/usb/uvc/uvc_driver.c-892-/* Parse vendor-specific extensions. */\ndrivers/media/usb/uvc/uvc_driver.c:893:static int uvc_parse_vendor_control(struct uvc_device *dev,\ndrivers/media/usb/uvc/uvc_driver.c-894-\tconst unsigned char *buffer, int buflen)\n--\ndrivers/media/usb/uvc/uvc_driver.c=1237=static int uvc_parse_control(struct uvc_device *dev)\n--\ndrivers/media/usb/uvc/uvc_driver.c-1253-\ndrivers/media/usb/uvc/uvc_driver.c:1254:\t\tif (uvc_parse_vendor_control(dev, buffer, buffer[0]) ||\ndrivers/media/usb/uvc/uvc_driver.c-1255-\t\t    buffer[1] != USB_DT_CS_INTERFACE)\n"
}

25/2 2026/09/16 09:55 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 13236
							output: 44
							thoughts: 10
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Analyzing the `uvc_probe` Function**

Okay, time to dive into `uvc_probe`. My initial thought is to quickly refresh my understanding of how this critical function works within the UVC driver context. I need to be efficient here – I'm looking for the key entry points, the initial device setup stages, and the crucial interactions with the UVC specification. I'm immediately focusing on where it detects supported formats, sets up endpoints, handles the descriptor parsing, and potentially allocates internal data structures related to the device's capabilities. I expect it's the gatekeeper to a successful UVC device initialization. Are there any known areas where it handles quirks or workarounds for specific chipsets or device revisions? I need to be mindful of any platform-specific dependencies as well, in case there are subtle differences between how this is handled on different architectures. I'll be looking for potential optimization opportunities during the scan. Let's dig in.



26/2 2026/09/16 09:56 tool read-file
0m Args:
{
  "File": "drivers/media/usb/uvc/uvc_driver.c",
  "FirstLine": 2189,
  "LineCount": 40
}

Results:
{
  "Contents": "2189:\tstatic int uvc_probe(struct usb_interface *intf,\n2190:\t\t\t     const struct usb_device_id *id)\n2191:\t{\n2192:\t\tstruct usb_device *udev = interface_to_usbdev(intf);\n2193:\t\tstruct uvc_device *dev;\n2194:\t\tconst struct uvc_device_info *info =\n2195:\t\t\t(const struct uvc_device_info *)id-\u003edriver_info;\n2196:\t\tint function;\n2197:\t\tint ret;\n2198:\t\n2199:\t\t/* Allocate memory for the device and initialize it. */\n2200:\t\tdev = kzalloc_obj(*dev);\n2201:\t\tif (dev == NULL)\n2202:\t\t\treturn -ENOMEM;\n2203:\t\n2204:\t\tINIT_LIST_HEAD(\u0026dev-\u003eentities);\n2205:\t\tINIT_LIST_HEAD(\u0026dev-\u003echains);\n2206:\t\tINIT_LIST_HEAD(\u0026dev-\u003estreams);\n2207:\t\tkref_init(\u0026dev-\u003eref);\n2208:\t\tatomic_set(\u0026dev-\u003enmappings, 0);\n2209:\t\n2210:\t\tdev-\u003eudev = usb_get_dev(udev);\n2211:\t\tdev-\u003eintf = usb_get_intf(intf);\n2212:\t\tdev-\u003eintfnum = intf-\u003ecur_altsetting-\u003edesc.bInterfaceNumber;\n2213:\t\tdev-\u003einfo = info ? info : \u0026uvc_quirk_none;\n2214:\t\tdev-\u003equirks = uvc_quirks_param == -1\n2215:\t\t\t    ? dev-\u003einfo-\u003equirks : uvc_quirks_param;\n2216:\t\n2217:\t\tif (id-\u003eidVendor \u0026\u0026 id-\u003eidProduct)\n2218:\t\t\tuvc_dbg(dev, PROBE, \"Probing known UVC device %s (%04x:%04x)\\n\",\n2219:\t\t\t\tudev-\u003edevpath, id-\u003eidVendor, id-\u003eidProduct);\n2220:\t\telse\n2221:\t\t\tuvc_dbg(dev, PROBE, \"Probing generic UVC device %s\\n\",\n2222:\t\t\t\tudev-\u003edevpath);\n2223:\t\n2224:\t\tif (udev-\u003eproduct != NULL)\n2225:\t\t\tstrscpy(dev-\u003ename, udev-\u003eproduct, sizeof(dev-\u003ename));\n2226:\t\telse\n2227:\t\t\tsnprintf(dev-\u003ename, sizeof(dev-\u003ename),\n2228:\t\t\t\t \"UVC Camera (%04x:%04x)\",\n"
}

27/2 2026/09/16 09:56 llm patch-evaluator
1m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 14203
							output: 27
							thoughts: 90
						

Thoughts:
Here's my thought process, as I analyze these configuration files:

**Configuration Dependency Analysis for USB Video Devices**

Okay, let's dive into these configurations. First, I need to understand the dependencies for `USB_VIDEO_CLASS`. I see it's defined in `drivers/media/usb/uvc/Kconfig`. Right, it directly depends on `VIDEO_DEV`. That makes sense; it needs the general video device framework.

Now, let's back up a bit and see where `USB_VIDEO_CLASS` is *conditionally* included. Looking at `drivers/media/usb/Kconfig`, I see a nested structure of dependencies. It's under `if USB && MEDIA_SUPPORT`. Okay, that's pretty broad – a USB device and overall media support are required. I see a couple other conditions, `if MEDIA_USB_SUPPORT` and `if MEDIA_CAMERA_SUPPORT`. These are more specific, which is good. We'll have to investigate what those macros represent later.

Now, my next move is to check the `Makefile` in `drivers/media/usb/` so I can see what files are actually compiled under these conditions. Knowing the structure of the `Kconfig` files and the relevant `Makefile` is how you understand the architecture of any driver!



28/2 2026/09/16 09:57 tool grepper
0m Args:
{
  "Expression": "uvc",
  "PathPrefix": "drivers/media/usb"
}

Results:
{
  "Output": "\nFull output is too long, showing 500 out of 5146 lines.\nUse more precise expression if possible.\n\ndrivers/media/usb/Kconfig=19=source \"drivers/media/usb/usbtv/Kconfig\"\ndrivers/media/usb/Kconfig:20:source \"drivers/media/usb/uvc/Kconfig\"\ndrivers/media/usb/Kconfig-21-\n--\ndrivers/media/usb/Makefile=23=obj-$(CONFIG_USB_PWC) += pwc/\ndrivers/media/usb/Makefile:24:obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/\ndrivers/media/usb/Makefile-25-obj-$(CONFIG_VIDEO_AU0828) += au0828/\n--\ndrivers/media/usb/pwc/Kconfig=2=config USB_PWC\n--\ndrivers/media/usb/pwc/Kconfig-25-\t  Some newer logitech webcams are not handled by this driver but by the\ndrivers/media/usb/pwc/Kconfig:26:\t  Usb Video Class driver (linux-uvc).\ndrivers/media/usb/pwc/Kconfig-27-\n--\ndrivers/media/usb/s2255/s2255drv.c=2342=static void s2255_disconnect(struct usb_interface *interface)\n--\ndrivers/media/usb/s2255/s2255drv.c-2350-\tmutex_unlock(\u0026dev-\u003elock);\ndrivers/media/usb/s2255/s2255drv.c:2351:\t/*see comments in the uvc_driver.c usb disconnect function */\ndrivers/media/usb/s2255/s2255drv.c-2352-\trefcount_inc(\u0026dev-\u003enum_channels);\n--\ndrivers/media/usb/stk1160/stk1160-video.c=301=static void stk1160_isoc_irq(struct urb *urb)\n--\ndrivers/media/usb/stk1160/stk1160-video.c-311-\tcase -ESHUTDOWN:\ndrivers/media/usb/stk1160/stk1160-video.c:312:\t\t/* TODO: check uvc driver: he frees the queue here */\ndrivers/media/usb/stk1160/stk1160-video.c-313-\t\treturn;\n--\ndrivers/media/usb/uvc/Kconfig=2=config USB_VIDEO_CLASS\n--\ndrivers/media/usb/uvc/Kconfig-10-\ndrivers/media/usb/uvc/Kconfig:11:\t  For more information see: \u003chttp://linux-uvc.berlios.de/\u003e\ndrivers/media/usb/uvc/Kconfig-12-\n--\ndrivers/media/usb/uvc/Makefile-1-# SPDX-License-Identifier: GPL-2.0\ndrivers/media/usb/uvc/Makefile:2:uvcvideo-objs  := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \\\ndrivers/media/usb/uvc/Makefile:3:\t\t  uvc_status.o uvc_isight.o uvc_debugfs.o uvc_metadata.o\ndrivers/media/usb/uvc/Makefile-4-ifeq ($(CONFIG_MEDIA_CONTROLLER),y)\ndrivers/media/usb/uvc/Makefile:5:uvcvideo-objs  += uvc_entity.o\ndrivers/media/usb/uvc/Makefile-6-endif\ndrivers/media/usb/uvc/Makefile:7:obj-$(CONFIG_USB_VIDEO_CLASS) += uvcvideo.o\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-2-/*\ndrivers/media/usb/uvc/uvc_ctrl.c:3: *      uvc_ctrl.c  --  USB Video Class driver - Controls\ndrivers/media/usb/uvc/uvc_ctrl.c-4- *\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-16-#include \u003clinux/usb.h\u003e\ndrivers/media/usb/uvc/uvc_ctrl.c:17:#include \u003clinux/usb/uvc.h\u003e\ndrivers/media/usb/uvc/uvc_ctrl.c-18-#include \u003clinux/videodev2.h\u003e\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-24-\ndrivers/media/usb/uvc/uvc_ctrl.c:25:#include \"uvcvideo.h\"\ndrivers/media/usb/uvc/uvc_ctrl.c-26-\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-38-\ndrivers/media/usb/uvc/uvc_ctrl.c:39:static const struct uvc_control_info uvc_ctrls[] = {\ndrivers/media/usb/uvc/uvc_ctrl.c-40-\t{\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-482-\ndrivers/media/usb/uvc/uvc_ctrl.c:483:static const u32 uvc_control_classes[] = {\ndrivers/media/usb/uvc/uvc_ctrl.c-484-\tV4L2_CID_CAMERA_CLASS,\n--\ndrivers/media/usb/uvc/uvc_ctrl.c=489=static const int cros_colorfx_mapping[] = {\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-502-\ndrivers/media/usb/uvc/uvc_ctrl.c:503:static bool uvc_ctrl_mapping_is_compound(struct uvc_control_mapping *mapping)\ndrivers/media/usb/uvc/uvc_ctrl.c-504-{\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-507-\ndrivers/media/usb/uvc/uvc_ctrl.c:508:static s32 uvc_mapping_get_s32(struct uvc_control_mapping *mapping,\ndrivers/media/usb/uvc/uvc_ctrl.c-509-\t\t\t       u8 query, const void *data_in)\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-517-\ndrivers/media/usb/uvc/uvc_ctrl.c:518:static void uvc_mapping_set_s32(struct uvc_control_mapping *mapping,\ndrivers/media/usb/uvc/uvc_ctrl.c-519-\t\t\t\ts32 data_in, void *data_out)\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-537- */\ndrivers/media/usb/uvc/uvc_ctrl.c:538:static int uvc_mapping_get_menu_value(const struct uvc_control_mapping *mapping,\ndrivers/media/usb/uvc/uvc_ctrl.c-539-\t\t\t\t      u32 idx)\n--\ndrivers/media/usb/uvc/uvc_ctrl.c=550=static const char *\ndrivers/media/usb/uvc/uvc_ctrl.c:551:uvc_mapping_get_menu_name(const struct uvc_control_mapping *mapping, u32 idx)\ndrivers/media/usb/uvc/uvc_ctrl.c-552-{\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-561-\ndrivers/media/usb/uvc/uvc_ctrl.c:562:static int uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping, u8 query,\ndrivers/media/usb/uvc/uvc_ctrl.c:563:\t\t\t     const void *uvc_in, size_t v4l2_size,\ndrivers/media/usb/uvc/uvc_ctrl.c-564-\t\t\t     void *v4l2_out)\ndrivers/media/usb/uvc/uvc_ctrl.c-565-{\ndrivers/media/usb/uvc/uvc_ctrl.c:566:\tu8 value = ((u8 *)uvc_in)[2];\ndrivers/media/usb/uvc/uvc_ctrl.c:567:\ts8 sign = ((s8 *)uvc_in)[0];\ndrivers/media/usb/uvc/uvc_ctrl.c-568-\ts32 *out = v4l2_out;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-588-\ndrivers/media/usb/uvc/uvc_ctrl.c:589:static int uvc_ctrl_set_zoom(struct uvc_control_mapping *mapping,\ndrivers/media/usb/uvc/uvc_ctrl.c-590-\t\t\t     size_t v4l2_size, const void *v4l2_in,\ndrivers/media/usb/uvc/uvc_ctrl.c:591:\t\t\t     void *uvc_out)\ndrivers/media/usb/uvc/uvc_ctrl.c-592-{\ndrivers/media/usb/uvc/uvc_ctrl.c:593:\tu8 *out = uvc_out;\ndrivers/media/usb/uvc/uvc_ctrl.c-594-\ts32 value;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-605-\ndrivers/media/usb/uvc/uvc_ctrl.c:606:static int uvc_ctrl_get_rel_speed(struct uvc_control_mapping *mapping,\ndrivers/media/usb/uvc/uvc_ctrl.c:607:\t\t\t\t  u8 query, const void *uvc_in,\ndrivers/media/usb/uvc/uvc_ctrl.c-608-\t\t\t\t  size_t v4l2_size, void *v4l2_out)\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-610-\tunsigned int first = mapping-\u003eoffset / 8;\ndrivers/media/usb/uvc/uvc_ctrl.c:611:\tu8 value = ((u8 *)uvc_in)[first + 1];\ndrivers/media/usb/uvc/uvc_ctrl.c:612:\ts8 sign = ((s8 *)uvc_in)[first];\ndrivers/media/usb/uvc/uvc_ctrl.c-613-\ts32 *out = v4l2_out;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-632-\ndrivers/media/usb/uvc/uvc_ctrl.c:633:static int uvc_ctrl_set_rel_speed(struct uvc_control_mapping *mapping,\ndrivers/media/usb/uvc/uvc_ctrl.c-634-\t\t\t\t  size_t v4l2_size, const void *v4l2_in,\ndrivers/media/usb/uvc/uvc_ctrl.c:635:\t\t\t\t  void *uvc_out)\ndrivers/media/usb/uvc/uvc_ctrl.c-636-{\ndrivers/media/usb/uvc/uvc_ctrl.c-637-\tunsigned int first = mapping-\u003eoffset / 8;\ndrivers/media/usb/uvc/uvc_ctrl.c:638:\tu8 *out = uvc_out;\ndrivers/media/usb/uvc/uvc_ctrl.c-639-\ts32 value;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-650-\ndrivers/media/usb/uvc/uvc_ctrl.c:651:static const struct uvc_control_mapping uvc_ctrl_power_line_mapping_limited = {\ndrivers/media/usb/uvc/uvc_ctrl.c-652-\t.id\t\t= V4L2_CID_POWER_LINE_FREQUENCY,\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-662-\ndrivers/media/usb/uvc/uvc_ctrl.c:663:static const struct uvc_control_mapping uvc_ctrl_power_line_mapping_uvc11 = {\ndrivers/media/usb/uvc/uvc_ctrl.c-664-\t.id\t\t= V4L2_CID_POWER_LINE_FREQUENCY,\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-674-\ndrivers/media/usb/uvc/uvc_ctrl.c:675:static const struct uvc_control_mapping uvc_ctrl_power_line_mapping_uvc15 = {\ndrivers/media/usb/uvc/uvc_ctrl.c-676-\t.id\t\t= V4L2_CID_POWER_LINE_FREQUENCY,\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-686-\ndrivers/media/usb/uvc/uvc_ctrl.c:687:static const struct uvc_control_mapping *uvc_ctrl_filter_plf_mapping(\ndrivers/media/usb/uvc/uvc_ctrl.c:688:\tstruct uvc_video_chain *chain, struct uvc_control *ctrl)\ndrivers/media/usb/uvc/uvc_ctrl.c-689-{\ndrivers/media/usb/uvc/uvc_ctrl.c:690:\tconst struct uvc_control_mapping *out_mapping =\ndrivers/media/usb/uvc/uvc_ctrl.c:691:\t\t\t\t\t\u0026uvc_ctrl_power_line_mapping_uvc11;\ndrivers/media/usb/uvc/uvc_ctrl.c-692-\tu8 *buf __free(kfree) = NULL;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-700-\t/* Save the current PLF value, so we can restore it. */\ndrivers/media/usb/uvc/uvc_ctrl.c:701:\tret = uvc_query_ctrl(chain-\u003edev, UVC_GET_CUR, ctrl-\u003eentity-\u003eid,\ndrivers/media/usb/uvc/uvc_ctrl.c-702-\t\t\t     chain-\u003edev-\u003eintfnum, ctrl-\u003einfo.selector,\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-710-\t*buf = V4L2_CID_POWER_LINE_FREQUENCY_DISABLED;\ndrivers/media/usb/uvc/uvc_ctrl.c:711:\tret = uvc_query_ctrl(chain-\u003edev, UVC_SET_CUR, ctrl-\u003eentity-\u003eid,\ndrivers/media/usb/uvc/uvc_ctrl.c-712-\t\t\t     chain-\u003edev-\u003eintfnum, ctrl-\u003einfo.selector,\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-714-\tif (ret)\ndrivers/media/usb/uvc/uvc_ctrl.c:715:\t\treturn \u0026uvc_ctrl_power_line_mapping_limited;\ndrivers/media/usb/uvc/uvc_ctrl.c-716-\ndrivers/media/usb/uvc/uvc_ctrl.c-717-\t/* UVC 1.1 does not define auto, we can exit. */\ndrivers/media/usb/uvc/uvc_ctrl.c:718:\tif (chain-\u003edev-\u003euvc_version \u003c 0x150)\ndrivers/media/usb/uvc/uvc_ctrl.c-719-\t\tgoto end;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-722-\t*buf = V4L2_CID_POWER_LINE_FREQUENCY_AUTO;\ndrivers/media/usb/uvc/uvc_ctrl.c:723:\tret = uvc_query_ctrl(chain-\u003edev, UVC_SET_CUR, ctrl-\u003eentity-\u003eid,\ndrivers/media/usb/uvc/uvc_ctrl.c-724-\t\t\t     chain-\u003edev-\u003eintfnum, ctrl-\u003einfo.selector,\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-726-\tif (!ret)\ndrivers/media/usb/uvc/uvc_ctrl.c:727:\t\tout_mapping = \u0026uvc_ctrl_power_line_mapping_uvc15;\ndrivers/media/usb/uvc/uvc_ctrl.c-728-\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-731-\t*buf = init_val;\ndrivers/media/usb/uvc/uvc_ctrl.c:732:\tuvc_query_ctrl(chain-\u003edev, UVC_SET_CUR, ctrl-\u003eentity-\u003eid,\ndrivers/media/usb/uvc/uvc_ctrl.c-733-\t\t       chain-\u003edev-\u003eintfnum, ctrl-\u003einfo.selector,\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-738-\ndrivers/media/usb/uvc/uvc_ctrl.c:739:static int uvc_get_rect(struct uvc_control_mapping *mapping, u8 query,\ndrivers/media/usb/uvc/uvc_ctrl.c:740:\t\t\tconst void *uvc_in, size_t v4l2_size, void *v4l2_out)\ndrivers/media/usb/uvc/uvc_ctrl.c-741-{\ndrivers/media/usb/uvc/uvc_ctrl.c:742:\tconst struct uvc_rect *uvc_rect = uvc_in;\ndrivers/media/usb/uvc/uvc_ctrl.c-743-\tstruct v4l2_rect *v4l2_rect = v4l2_out;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-747-\ndrivers/media/usb/uvc/uvc_ctrl.c:748:\tif (uvc_rect-\u003eleft \u003e uvc_rect-\u003eright ||\ndrivers/media/usb/uvc/uvc_ctrl.c:749:\t    uvc_rect-\u003etop \u003e uvc_rect-\u003ebottom)\ndrivers/media/usb/uvc/uvc_ctrl.c-750-\t\treturn -EIO;\ndrivers/media/usb/uvc/uvc_ctrl.c-751-\ndrivers/media/usb/uvc/uvc_ctrl.c:752:\tv4l2_rect-\u003etop = uvc_rect-\u003etop;\ndrivers/media/usb/uvc/uvc_ctrl.c:753:\tv4l2_rect-\u003eleft = uvc_rect-\u003eleft;\ndrivers/media/usb/uvc/uvc_ctrl.c:754:\tv4l2_rect-\u003eheight = uvc_rect-\u003ebottom - uvc_rect-\u003etop + 1;\ndrivers/media/usb/uvc/uvc_ctrl.c:755:\tv4l2_rect-\u003ewidth = uvc_rect-\u003eright - uvc_rect-\u003eleft + 1;\ndrivers/media/usb/uvc/uvc_ctrl.c-756-\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-759-\ndrivers/media/usb/uvc/uvc_ctrl.c:760:static int uvc_set_rect(struct uvc_control_mapping *mapping, size_t v4l2_size,\ndrivers/media/usb/uvc/uvc_ctrl.c:761:\t\t\tconst void *v4l2_in, void *uvc_out)\ndrivers/media/usb/uvc/uvc_ctrl.c-762-{\ndrivers/media/usb/uvc/uvc_ctrl.c:763:\tstruct uvc_rect *uvc_rect = uvc_out;\ndrivers/media/usb/uvc/uvc_ctrl.c-764-\tconst struct v4l2_rect *v4l2_rect = v4l2_in;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-768-\ndrivers/media/usb/uvc/uvc_ctrl.c:769:\tuvc_rect-\u003etop = min(0xffff, v4l2_rect-\u003etop);\ndrivers/media/usb/uvc/uvc_ctrl.c:770:\tuvc_rect-\u003eleft = min(0xffff, v4l2_rect-\u003eleft);\ndrivers/media/usb/uvc/uvc_ctrl.c:771:\tuvc_rect-\u003ebottom = min(0xffff, v4l2_rect-\u003etop + v4l2_rect-\u003eheight - 1);\ndrivers/media/usb/uvc/uvc_ctrl.c:772:\tuvc_rect-\u003eright = min(0xffff, v4l2_rect-\u003eleft + v4l2_rect-\u003ewidth - 1);\ndrivers/media/usb/uvc/uvc_ctrl.c-773-\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-776-\ndrivers/media/usb/uvc/uvc_ctrl.c:777:static const struct uvc_control_mapping uvc_ctrl_mappings[] = {\ndrivers/media/usb/uvc/uvc_ctrl.c-778-\t{\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1004-\t\t.data_type\t= UVC_CTRL_DATA_TYPE_SIGNED,\ndrivers/media/usb/uvc/uvc_ctrl.c:1005:\t\t.get\t\t= uvc_ctrl_get_zoom,\ndrivers/media/usb/uvc/uvc_ctrl.c:1006:\t\t.set\t\t= uvc_ctrl_set_zoom,\ndrivers/media/usb/uvc/uvc_ctrl.c-1007-\t},\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1033-\t\t.data_type\t= UVC_CTRL_DATA_TYPE_SIGNED,\ndrivers/media/usb/uvc/uvc_ctrl.c:1034:\t\t.get\t\t= uvc_ctrl_get_rel_speed,\ndrivers/media/usb/uvc/uvc_ctrl.c:1035:\t\t.set\t\t= uvc_ctrl_set_rel_speed,\ndrivers/media/usb/uvc/uvc_ctrl.c-1036-\t},\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1044-\t\t.data_type\t= UVC_CTRL_DATA_TYPE_SIGNED,\ndrivers/media/usb/uvc/uvc_ctrl.c:1045:\t\t.get\t\t= uvc_ctrl_get_rel_speed,\ndrivers/media/usb/uvc/uvc_ctrl.c:1046:\t\t.set\t\t= uvc_ctrl_set_rel_speed,\ndrivers/media/usb/uvc/uvc_ctrl.c-1047-\t},\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1068-\t\t.selector\t= UVC_PU_POWER_LINE_FREQUENCY_CONTROL,\ndrivers/media/usb/uvc/uvc_ctrl.c:1069:\t\t.filter_mapping\t= uvc_ctrl_filter_plf_mapping,\ndrivers/media/usb/uvc/uvc_ctrl.c-1070-\t},\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1074-\t\t.selector\t= UVC_CT_REGION_OF_INTEREST_CONTROL,\ndrivers/media/usb/uvc/uvc_ctrl.c:1075:\t\t.size\t\t= sizeof(struct uvc_rect) * 8,\ndrivers/media/usb/uvc/uvc_ctrl.c-1076-\t\t.offset\t\t= 0,\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1078-\t\t.data_type\t= UVC_CTRL_DATA_TYPE_RECT,\ndrivers/media/usb/uvc/uvc_ctrl.c:1079:\t\t.get\t\t= uvc_get_rect,\ndrivers/media/usb/uvc/uvc_ctrl.c:1080:\t\t.set\t\t= uvc_set_rect,\ndrivers/media/usb/uvc/uvc_ctrl.c-1081-\t\t.name\t\t= \"Region of Interest Rectangle\",\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1191-\ndrivers/media/usb/uvc/uvc_ctrl.c:1192:static inline u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id)\ndrivers/media/usb/uvc/uvc_ctrl.c-1193-{\ndrivers/media/usb/uvc/uvc_ctrl.c:1194:\treturn ctrl-\u003euvc_data + id * ctrl-\u003einfo.size;\ndrivers/media/usb/uvc/uvc_ctrl.c-1195-}\ndrivers/media/usb/uvc/uvc_ctrl.c-1196-\ndrivers/media/usb/uvc/uvc_ctrl.c:1197:static inline int uvc_test_bit(const u8 *data, int bit)\ndrivers/media/usb/uvc/uvc_ctrl.c-1198-{\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1201-\ndrivers/media/usb/uvc/uvc_ctrl.c:1202:static inline void uvc_clear_bit(u8 *data, int bit)\ndrivers/media/usb/uvc/uvc_ctrl.c-1203-{\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1206-\ndrivers/media/usb/uvc/uvc_ctrl.c:1207:static s32 uvc_menu_to_v4l2_menu(struct uvc_control_mapping *mapping, s32 val)\ndrivers/media/usb/uvc/uvc_ctrl.c-1208-{\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1216-\ndrivers/media/usb/uvc/uvc_ctrl.c:1217:\t\tmenu_value = uvc_mapping_get_menu_value(mapping, i);\ndrivers/media/usb/uvc/uvc_ctrl.c-1218-\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1231- */\ndrivers/media/usb/uvc/uvc_ctrl.c:1232:static int uvc_get_le_value(struct uvc_control_mapping *mapping,\ndrivers/media/usb/uvc/uvc_ctrl.c:1233:\t\t\t    u8 query, const void *uvc_in, size_t v4l2_size,\ndrivers/media/usb/uvc/uvc_ctrl.c-1234-\t\t\t    void *v4l2_out)\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1237-\tint bits = mapping-\u003esize;\ndrivers/media/usb/uvc/uvc_ctrl.c:1238:\tconst u8 *data = uvc_in;\ndrivers/media/usb/uvc/uvc_ctrl.c-1239-\ts32 *out = v4l2_out;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1265-\ndrivers/media/usb/uvc/uvc_ctrl.c:1266:\t/* If it is a menu, convert from uvc to v4l2. */\ndrivers/media/usb/uvc/uvc_ctrl.c-1267-\tif (mapping-\u003ev4l2_type != V4L2_CTRL_TYPE_MENU) {\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1274-\tcase UVC_GET_DEF:\ndrivers/media/usb/uvc/uvc_ctrl.c:1275:\t\t*out = uvc_menu_to_v4l2_menu(mapping, value);\ndrivers/media/usb/uvc/uvc_ctrl.c-1276-\t\treturn 0;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1286- */\ndrivers/media/usb/uvc/uvc_ctrl.c:1287:static int uvc_set_le_value(struct uvc_control_mapping *mapping,\ndrivers/media/usb/uvc/uvc_ctrl.c-1288-\t\t\t    size_t v4l2_size, const void *v4l2_in,\ndrivers/media/usb/uvc/uvc_ctrl.c:1289:\t\t\t    void *uvc_out)\ndrivers/media/usb/uvc/uvc_ctrl.c-1290-{\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1292-\tint bits = mapping-\u003esize;\ndrivers/media/usb/uvc/uvc_ctrl.c:1293:\tu8 *data = uvc_out;\ndrivers/media/usb/uvc/uvc_ctrl.c-1294-\ts32 value;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1303-\tcase V4L2_CTRL_TYPE_MENU:\ndrivers/media/usb/uvc/uvc_ctrl.c:1304:\t\tvalue = uvc_mapping_get_menu_value(mapping, value);\ndrivers/media/usb/uvc/uvc_ctrl.c-1305-\t\tbreak;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1336-\ndrivers/media/usb/uvc/uvc_ctrl.c:1337:static int uvc_entity_match_guid(const struct uvc_entity *entity,\ndrivers/media/usb/uvc/uvc_ctrl.c-1338-\t\t\t\t const u8 guid[16])\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1346-\ndrivers/media/usb/uvc/uvc_ctrl.c:1347:static void __uvc_find_control(struct uvc_entity *entity, u32 v4l2_id,\ndrivers/media/usb/uvc/uvc_ctrl.c:1348:\tstruct uvc_control_mapping **mapping, struct uvc_control **control,\ndrivers/media/usb/uvc/uvc_ctrl.c-1349-\tint next, int next_compound)\ndrivers/media/usb/uvc/uvc_ctrl.c-1350-{\ndrivers/media/usb/uvc/uvc_ctrl.c:1351:\tstruct uvc_control *ctrl;\ndrivers/media/usb/uvc/uvc_ctrl.c:1352:\tstruct uvc_control_mapping *map;\ndrivers/media/usb/uvc/uvc_ctrl.c-1353-\tunsigned int i;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1371-\t\t\t    (map-\u003eid \u003e v4l2_id) \u0026\u0026\ndrivers/media/usb/uvc/uvc_ctrl.c:1372:\t\t\t    (uvc_ctrl_mapping_is_compound(map) ?\ndrivers/media/usb/uvc/uvc_ctrl.c-1373-\t\t\t     next_compound : next)) {\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1380-\ndrivers/media/usb/uvc/uvc_ctrl.c:1381:static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,\ndrivers/media/usb/uvc/uvc_ctrl.c:1382:\tu32 v4l2_id, struct uvc_control_mapping **mapping)\ndrivers/media/usb/uvc/uvc_ctrl.c-1383-{\ndrivers/media/usb/uvc/uvc_ctrl.c:1384:\tstruct uvc_control *ctrl = NULL;\ndrivers/media/usb/uvc/uvc_ctrl.c:1385:\tstruct uvc_entity *entity;\ndrivers/media/usb/uvc/uvc_ctrl.c-1386-\tint next = v4l2_id \u0026 V4L2_CTRL_FLAG_NEXT_CTRL;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1395-\tlist_for_each_entry(entity, \u0026chain-\u003eentities, chain) {\ndrivers/media/usb/uvc/uvc_ctrl.c:1396:\t\t__uvc_find_control(entity, v4l2_id, mapping, \u0026ctrl, next,\ndrivers/media/usb/uvc/uvc_ctrl.c-1397-\t\t\t\t   next_compound);\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1402-\tif (!ctrl \u0026\u0026 !next \u0026\u0026 !next_compound)\ndrivers/media/usb/uvc/uvc_ctrl.c:1403:\t\tuvc_dbg(chain-\u003edev, CONTROL, \"Control 0x%08x not found\\n\",\ndrivers/media/usb/uvc/uvc_ctrl.c-1404-\t\t\tv4l2_id);\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1408-\ndrivers/media/usb/uvc/uvc_ctrl.c:1409:static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,\ndrivers/media/usb/uvc/uvc_ctrl.c:1410:\tstruct uvc_control *ctrl)\ndrivers/media/usb/uvc/uvc_ctrl.c-1411-{\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1414-\tif (ctrl-\u003einfo.flags \u0026 UVC_CTRL_FLAG_GET_DEF) {\ndrivers/media/usb/uvc/uvc_ctrl.c:1415:\t\tret = uvc_query_ctrl(chain-\u003edev, UVC_GET_DEF, ctrl-\u003eentity-\u003eid,\ndrivers/media/usb/uvc/uvc_ctrl.c-1416-\t\t\t\t     chain-\u003edev-\u003eintfnum, ctrl-\u003einfo.selector,\ndrivers/media/usb/uvc/uvc_ctrl.c:1417:\t\t\t\t     uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF),\ndrivers/media/usb/uvc/uvc_ctrl.c-1418-\t\t\t\t     ctrl-\u003einfo.size);\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1423-\tif (ctrl-\u003einfo.flags \u0026 UVC_CTRL_FLAG_GET_MIN) {\ndrivers/media/usb/uvc/uvc_ctrl.c:1424:\t\tret = uvc_query_ctrl(chain-\u003edev, UVC_GET_MIN, ctrl-\u003eentity-\u003eid,\ndrivers/media/usb/uvc/uvc_ctrl.c-1425-\t\t\t\t     chain-\u003edev-\u003eintfnum, ctrl-\u003einfo.selector,\ndrivers/media/usb/uvc/uvc_ctrl.c:1426:\t\t\t\t     uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN),\ndrivers/media/usb/uvc/uvc_ctrl.c-1427-\t\t\t\t     ctrl-\u003einfo.size);\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1431-\tif (ctrl-\u003einfo.flags \u0026 UVC_CTRL_FLAG_GET_MAX) {\ndrivers/media/usb/uvc/uvc_ctrl.c:1432:\t\tret = uvc_query_ctrl(chain-\u003edev, UVC_GET_MAX, ctrl-\u003eentity-\u003eid,\ndrivers/media/usb/uvc/uvc_ctrl.c-1433-\t\t\t\t     chain-\u003edev-\u003eintfnum, ctrl-\u003einfo.selector,\ndrivers/media/usb/uvc/uvc_ctrl.c:1434:\t\t\t\t     uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX),\ndrivers/media/usb/uvc/uvc_ctrl.c-1435-\t\t\t\t     ctrl-\u003einfo.size);\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1439-\tif (ctrl-\u003einfo.flags \u0026 UVC_CTRL_FLAG_GET_RES) {\ndrivers/media/usb/uvc/uvc_ctrl.c:1440:\t\tret = uvc_query_ctrl(chain-\u003edev, UVC_GET_RES, ctrl-\u003eentity-\u003eid,\ndrivers/media/usb/uvc/uvc_ctrl.c-1441-\t\t\t\t     chain-\u003edev-\u003eintfnum, ctrl-\u003einfo.selector,\ndrivers/media/usb/uvc/uvc_ctrl.c:1442:\t\t\t\t     uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES),\ndrivers/media/usb/uvc/uvc_ctrl.c-1443-\t\t\t\t     ctrl-\u003einfo.size);\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1453-\t\t\t */\ndrivers/media/usb/uvc/uvc_ctrl.c:1454:\t\t\tuvc_warn_once(chain-\u003edev, UVC_WARN_XU_GET_RES,\ndrivers/media/usb/uvc/uvc_ctrl.c-1455-\t\t\t\t      \"UVC non compliance - GET_RES failed on \"\ndrivers/media/usb/uvc/uvc_ctrl.c-1456-\t\t\t\t      \"an XU control. Enabling workaround.\\n\");\ndrivers/media/usb/uvc/uvc_ctrl.c:1457:\t\t\tmemset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), 0,\ndrivers/media/usb/uvc/uvc_ctrl.c-1458-\t\t\t       ctrl-\u003einfo.size);\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1465-\ndrivers/media/usb/uvc/uvc_ctrl.c:1466:static int __uvc_ctrl_load_cur(struct uvc_video_chain *chain,\ndrivers/media/usb/uvc/uvc_ctrl.c:1467:\t\t\t       struct uvc_control *ctrl)\ndrivers/media/usb/uvc/uvc_ctrl.c-1468-{\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1474-\ndrivers/media/usb/uvc/uvc_ctrl.c:1475:\tdata = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT);\ndrivers/media/usb/uvc/uvc_ctrl.c-1476-\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1488-\telse\ndrivers/media/usb/uvc/uvc_ctrl.c:1489:\t\tret = uvc_query_ctrl(chain-\u003edev, UVC_GET_CUR,\ndrivers/media/usb/uvc/uvc_ctrl.c-1490-\t\t\t\t     ctrl-\u003eentity-\u003eid, chain-\u003edev-\u003eintfnum,\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1501-\ndrivers/media/usb/uvc/uvc_ctrl.c:1502:static int __uvc_ctrl_get(struct uvc_video_chain *chain,\ndrivers/media/usb/uvc/uvc_ctrl.c:1503:\t\t\t  struct uvc_control *ctrl,\ndrivers/media/usb/uvc/uvc_ctrl.c:1504:\t\t\t  struct uvc_control_mapping *mapping,\ndrivers/media/usb/uvc/uvc_ctrl.c-1505-\t\t\t  s32 *value)\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1511-\ndrivers/media/usb/uvc/uvc_ctrl.c:1512:\tret = __uvc_ctrl_load_cur(chain, ctrl);\ndrivers/media/usb/uvc/uvc_ctrl.c-1513-\tif (ret \u003c 0)\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1515-\ndrivers/media/usb/uvc/uvc_ctrl.c:1516:\t*value = uvc_mapping_get_s32(mapping, UVC_GET_CUR,\ndrivers/media/usb/uvc/uvc_ctrl.c:1517:\t\t\t\t     uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));\ndrivers/media/usb/uvc/uvc_ctrl.c-1518-\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1521-\ndrivers/media/usb/uvc/uvc_ctrl.c:1522:static int __uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id,\ndrivers/media/usb/uvc/uvc_ctrl.c-1523-\t\t\t\t  u32 found_id)\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1530-\ndrivers/media/usb/uvc/uvc_ctrl.c:1531:\tfor (i = 0; i \u003c ARRAY_SIZE(uvc_control_classes); i++) {\ndrivers/media/usb/uvc/uvc_ctrl.c-1532-\t\tif (!(chain-\u003ectrl_class_bitmap \u0026 BIT(i)))\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1534-\t\tif (!find_next) {\ndrivers/media/usb/uvc/uvc_ctrl.c:1535:\t\t\tif (uvc_control_classes[i] == req_id)\ndrivers/media/usb/uvc/uvc_ctrl.c-1536-\t\t\t\treturn i;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1538-\t\t}\ndrivers/media/usb/uvc/uvc_ctrl.c:1539:\t\tif (uvc_control_classes[i] \u003e req_id \u0026\u0026\ndrivers/media/usb/uvc/uvc_ctrl.c:1540:\t\t    uvc_control_classes[i] \u003c found_id)\ndrivers/media/usb/uvc/uvc_ctrl.c-1541-\t\t\treturn i;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1546-\ndrivers/media/usb/uvc/uvc_ctrl.c:1547:static int uvc_query_v4l2_class(struct uvc_video_chain *chain, u32 req_id,\ndrivers/media/usb/uvc/uvc_ctrl.c-1548-\t\t\t\tu32 found_id,\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1552-\ndrivers/media/usb/uvc/uvc_ctrl.c:1553:\tidx = __uvc_query_v4l2_class(chain, req_id, found_id);\ndrivers/media/usb/uvc/uvc_ctrl.c-1554-\tif (idx \u003c 0)\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1557-\tmemset(v4l2_ctrl, 0, sizeof(*v4l2_ctrl));\ndrivers/media/usb/uvc/uvc_ctrl.c:1558:\tv4l2_ctrl-\u003eid = uvc_control_classes[idx];\ndrivers/media/usb/uvc/uvc_ctrl.c-1559-\tstrscpy(v4l2_ctrl-\u003ename, v4l2_ctrl_get_name(v4l2_ctrl-\u003eid),\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1566-\ndrivers/media/usb/uvc/uvc_ctrl.c:1567:static bool uvc_ctrl_is_readable(u32 which, struct uvc_control *ctrl,\ndrivers/media/usb/uvc/uvc_ctrl.c:1568:\t\t\t\t struct uvc_control_mapping *mapping)\ndrivers/media/usb/uvc/uvc_ctrl.c-1569-{\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1607- */\ndrivers/media/usb/uvc/uvc_ctrl.c:1608:int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,\ndrivers/media/usb/uvc/uvc_ctrl.c-1609-\t\t\t   const struct v4l2_ext_controls *ctrls, u32 which,\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1611-{\ndrivers/media/usb/uvc/uvc_ctrl.c:1612:\tstruct uvc_control_mapping *master_map = NULL;\ndrivers/media/usb/uvc/uvc_ctrl.c:1613:\tstruct uvc_control *master_ctrl = NULL;\ndrivers/media/usb/uvc/uvc_ctrl.c:1614:\tstruct uvc_control_mapping *mapping;\ndrivers/media/usb/uvc/uvc_ctrl.c:1615:\tstruct uvc_control *ctrl;\ndrivers/media/usb/uvc/uvc_ctrl.c-1616-\ts32 val;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1625-\ndrivers/media/usb/uvc/uvc_ctrl.c:1626:\tif (__uvc_query_v4l2_class(chain, v4l2_id, 0) \u003e= 0)\ndrivers/media/usb/uvc/uvc_ctrl.c-1627-\t\treturn is_which_min_max ? -EINVAL : -EACCES;\ndrivers/media/usb/uvc/uvc_ctrl.c-1628-\ndrivers/media/usb/uvc/uvc_ctrl.c:1629:\tctrl = uvc_find_control(chain, v4l2_id, \u0026mapping);\ndrivers/media/usb/uvc/uvc_ctrl.c-1630-\tif (!ctrl)\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1637-\tif (ioctl == VIDIOC_G_EXT_CTRLS)\ndrivers/media/usb/uvc/uvc_ctrl.c:1638:\t\treturn uvc_ctrl_is_readable(ctrls-\u003ewhich, ctrl, mapping);\ndrivers/media/usb/uvc/uvc_ctrl.c-1639-\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1655-\ndrivers/media/usb/uvc/uvc_ctrl.c:1656:\t__uvc_find_control(ctrl-\u003eentity, mapping-\u003emaster_id, \u0026master_map,\ndrivers/media/usb/uvc/uvc_ctrl.c-1657-\t\t\t   \u0026master_ctrl, 0, 0);\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1660-\t\treturn 0;\ndrivers/media/usb/uvc/uvc_ctrl.c:1661:\tif (WARN_ON(uvc_ctrl_mapping_is_compound(master_map)))\ndrivers/media/usb/uvc/uvc_ctrl.c-1662-\t\treturn -EIO;\ndrivers/media/usb/uvc/uvc_ctrl.c-1663-\ndrivers/media/usb/uvc/uvc_ctrl.c:1664:\tret = __uvc_ctrl_get(chain, master_ctrl, master_map, \u0026val);\ndrivers/media/usb/uvc/uvc_ctrl.c-1665-\tif (ret \u003e= 0 \u0026\u0026 val != mapping-\u003emaster_manual)\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1670-\ndrivers/media/usb/uvc/uvc_ctrl.c:1671:static const char *uvc_map_get_name(const struct uvc_control_mapping *map)\ndrivers/media/usb/uvc/uvc_ctrl.c-1672-{\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1684-\ndrivers/media/usb/uvc/uvc_ctrl.c:1685:static u32 uvc_get_ctrl_bitmap(struct uvc_control *ctrl,\ndrivers/media/usb/uvc/uvc_ctrl.c:1686:\t\t\t       struct uvc_control_mapping *mapping)\ndrivers/media/usb/uvc/uvc_ctrl.c-1687-{\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1693-\tif (ctrl-\u003einfo.flags \u0026 UVC_CTRL_FLAG_GET_RES)\ndrivers/media/usb/uvc/uvc_ctrl.c:1694:\t\treturn uvc_mapping_get_s32(mapping, UVC_GET_RES,\ndrivers/media/usb/uvc/uvc_ctrl.c:1695:\t\t\t\t\t   uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));\ndrivers/media/usb/uvc/uvc_ctrl.c-1696-\ndrivers/media/usb/uvc/uvc_ctrl.c-1697-\tif (ctrl-\u003einfo.flags \u0026 UVC_CTRL_FLAG_GET_MAX)\ndrivers/media/usb/uvc/uvc_ctrl.c:1698:\t\treturn uvc_mapping_get_s32(mapping, UVC_GET_MAX,\ndrivers/media/usb/uvc/uvc_ctrl.c:1699:\t\t\t\t\t   uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));\ndrivers/media/usb/uvc/uvc_ctrl.c-1700-\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1703-\ndrivers/media/usb/uvc/uvc_ctrl.c:1704:static bool uvc_ctrl_is_relative_ptz(__u32 ctrl_id)\ndrivers/media/usb/uvc/uvc_ctrl.c-1705-{\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1720-\ndrivers/media/usb/uvc/uvc_ctrl.c:1721:static int __uvc_queryctrl_boundaries(struct uvc_video_chain *chain,\ndrivers/media/usb/uvc/uvc_ctrl.c:1722:\t\t\t\t      struct uvc_control *ctrl,\ndrivers/media/usb/uvc/uvc_ctrl.c:1723:\t\t\t\t      struct uvc_control_mapping *mapping,\ndrivers/media/usb/uvc/uvc_ctrl.c-1724-\t\t\t\t      struct v4l2_query_ext_ctrl *v4l2_ctrl)\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1730-\t\tfor (retries = 0; retries \u003c MAX_QUERY_RETRIES; retries++) {\ndrivers/media/usb/uvc/uvc_ctrl.c:1731:\t\t\tret = uvc_ctrl_populate_cache(chain, ctrl);\ndrivers/media/usb/uvc/uvc_ctrl.c-1732-\t\t\tif (ret != -EIO)\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1740-\tif (ctrl-\u003einfo.flags \u0026 UVC_CTRL_FLAG_GET_DEF) {\ndrivers/media/usb/uvc/uvc_ctrl.c:1741:\t\tv4l2_ctrl-\u003edefault_value = uvc_mapping_get_s32(mapping,\ndrivers/media/usb/uvc/uvc_ctrl.c:1742:\t\t\t\tUVC_GET_DEF, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF));\ndrivers/media/usb/uvc/uvc_ctrl.c-1743-\t}\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1765-\t\tv4l2_ctrl-\u003eminimum = 0;\ndrivers/media/usb/uvc/uvc_ctrl.c:1766:\t\tv4l2_ctrl-\u003emaximum = uvc_get_ctrl_bitmap(ctrl, mapping);\ndrivers/media/usb/uvc/uvc_ctrl.c-1767-\t\tv4l2_ctrl-\u003estep = 0;\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1774-\tif (ctrl-\u003einfo.flags \u0026 UVC_CTRL_FLAG_GET_MAX)\ndrivers/media/usb/uvc/uvc_ctrl.c:1775:\t\tv4l2_ctrl-\u003emaximum = uvc_mapping_get_s32(mapping, UVC_GET_MAX,\ndrivers/media/usb/uvc/uvc_ctrl.c:1776:\t\t\t\tuvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));\ndrivers/media/usb/uvc/uvc_ctrl.c-1777-\telse\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1790-\t\t */\ndrivers/media/usb/uvc/uvc_ctrl.c:1791:\t\tif (uvc_ctrl_is_relative_ptz(v4l2_ctrl-\u003eid))\ndrivers/media/usb/uvc/uvc_ctrl.c-1792-\t\t\tv4l2_ctrl-\u003eminimum = -v4l2_ctrl-\u003emaximum;\ndrivers/media/usb/uvc/uvc_ctrl.c-1793-\t\telse\ndrivers/media/usb/uvc/uvc_ctrl.c:1794:\t\t\tv4l2_ctrl-\u003eminimum = uvc_mapping_get_s32(mapping,\ndrivers/media/usb/uvc/uvc_ctrl.c:1795:\t\t\t\tUVC_GET_MIN, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));\ndrivers/media/usb/uvc/uvc_ctrl.c-1796-\t} else {\n--\ndrivers/media/usb/uvc/uvc_ctrl.c-1800-\tif (ctrl-\u003einfo.flags \u0026 UVC_CTRL_FLAG_GET_RES)\n\n"
}

29/2 2026/09/16 09:57 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 28363
							output: 33
							thoughts: 1075
						

Thoughts:
**Analyzing a UVC Driver Patch for Potential Fuzzing Targets**

Okay, let's break this down. First, I wanted to quickly check the commit log to understand the context, but it looks like the available tools are limited to grepping and searching the index. No `git log`, that's fine, I've got the diff and I've seen the surrounding code in `uvc_driver.c`.

Right, let's look at this change. The `uvc_parse_control` function is being modified. Previously, the code was passing `buflen` to `uvc_parse_vendor_control` and `uvc_parse_standard_control`, which represents the remaining buffer length. The patch now checks the descriptor length `buffer[0]` and makes sure it's valid and doesn't exceed the buffer, and passes `buffer[0]` instead of `buflen` to these functions. It also returns `-EINVAL` if the length is invalid, which makes sense. I can see now, that if `buffer[0] == 0`, the loop could become infinite! Or if `buffer[0] > buflen`, it could cause an integer underflow.

The key change is the introduction of a length check and how that length is subsequently passed to the parsing functions. This is interesting because this function, `uvc_parse_control`, is called during USB device probing, which means it's definitely reachable. And I'm pretty sure syzkaller can reach it.

This is where it gets interesting, because syzkaller's whole approach for fuzzing USB drivers relies on emulating raw gadgets or dummy HCDs, which means it can inject custom USB descriptors. Therefore, malformed descriptors, precisely the type this patch is designed to mitigate, are definitely something syzkaller would likely generate! The fact that this patch guards against those malformed descriptors makes this a prime target for fuzzing.

So, is this a WorthFuzzing=true scenario? Absolutely, it is!

I need to quickly check the configuration dependencies. Based on the Kconfig files, the relevant flags appear to be `USB_VIDEO_CLASS`, `MEDIA_SUPPORT`, `MEDIA_USB_SUPPORT`, `MEDIA_CAMERA_SUPPORT`, and `VIDEO_DEV`. These configurations seem reasonable, and I'll confirm them in `drivers/media/Kconfig`. I'll skim around those lines.



30/2 2026/09/16 09:57 tool read-file
0m Args:
{
  "File": "drivers/media/Kconfig",
  "FirstLine": 50,
  "LineCount": 50
}

Results:
{
  "Contents": "  50:\t\n  51:\t\t  This is generally the right thing to do, except when there\n  52:\t\t  are strict constraints with regards to the kernel size,\n  53:\t\t  like on embedded systems.\n  54:\t\n  55:\t\t  Use this option with care, as deselecting ancillary drivers which\n  56:\t\t  are, in fact, necessary will result in the lack of the needed\n  57:\t\t  functionality for your device (it may not tune or may not have\n  58:\t\t  the needed demodulators).\n  59:\t\n  60:\t\t  If unsure say Y.\n  61:\t\n  62:\tmenu \"Media device types\"\n  63:\t\n  64:\t#\n  65:\t# Multimedia support - automatically enable V4L2 and DVB core\n  66:\t#\n  67:\tconfig MEDIA_CAMERA_SUPPORT\n  68:\t\tbool\n  69:\t\tprompt \"Cameras and video grabbers\" if MEDIA_SUPPORT_FILTER\n  70:\t\tdefault y if !MEDIA_SUPPORT_FILTER\n  71:\t\thelp\n  72:\t\t  Enable support for webcams and video grabbers.\n  73:\t\n  74:\t\t  Say Y when you have a webcam or a video capture grabber board.\n  75:\t\n  76:\tconfig MEDIA_ANALOG_TV_SUPPORT\n  77:\t\tbool\n  78:\t\tprompt \"Analog TV\" if MEDIA_SUPPORT_FILTER\n  79:\t\tdefault y if !MEDIA_SUPPORT_FILTER\n  80:\t\thelp\n  81:\t\t  Enable analog TV support.\n  82:\t\n  83:\t\t  Say Y when you have a TV board with analog support or with a\n  84:\t\t  hybrid analog/digital TV chipset.\n  85:\t\n  86:\t\t  Note: There are several DVB cards that are based on chips that\n  87:\t\t\tsupport both analog and digital TV. Disabling this option\n  88:\t\t\twill disable support for them.\n  89:\t\n  90:\tconfig MEDIA_DIGITAL_TV_SUPPORT\n  91:\t\tbool\n  92:\t\tprompt \"Digital TV\" if MEDIA_SUPPORT_FILTER\n  93:\t\tdefault y if !MEDIA_SUPPORT_FILTER\n  94:\t\thelp\n  95:\t\t  Enable digital TV support.\n  96:\t\n  97:\t\t  Say Y when you have a board with digital support or a board with\n  98:\t\t  hybrid digital TV and analog TV.\n  99:\t\n"
}

31/2 2026/09/16 09:57 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 30618
							output: 203
							thoughts: 618
						

Thoughts:
**My Analysis of the UVC Descriptor Validation Patch**

Okay, let's break this down. First, I need to confirm the relevant Kconfig options. It looks like we're dealing with the USB Video Class, so `USB_VIDEO_CLASS` is definitely key. We also have `MEDIA_SUPPORT`, `MEDIA_CAMERA_SUPPORT`, and the general `USB` option, all of which seem reasonable given the context.

Now, the core of the change appears to be in `uvc_parse_control`. I need to identify the functions directly touched by this change. It looks like it directly calls `uvc_parse_standard_control` and `uvc_parse_vendor_control`. `uvc_probe` is also mentioned, and while I need to be sure the compiler doesn't inline `uvc_parse_control` into the others, it looks like all four - `uvc_parse_control`, `uvc_parse_standard_control`, `uvc_parse_vendor_control`, and `uvc_probe` - are feature-specific functions within `drivers/media/usb/uvc/uvc_driver.c`.

My understanding is that the patch modifies descriptor validation in `uvc_parse_control`. Specifically, it validates descriptor length `buffer[0]` against buffer boundaries, and also passes the actual descriptor length to `uvc_parse_vendor_control` and `uvc_parse_standard_control` instead of the remaining buffer length. Given this context, this is reachable during USB device enumeration and is fuzzable via USB gadget emulation like `syzkaller's syz_usb_connect`.

So, to summarize, the patch is worth fuzzing because it touches descriptor validation, it's reachable and fuzzable.
My focus symbols, to ensure full coverage and focus tracking are `uvc_parse_control`, `uvc_parse_standard_control`, `uvc_parse_vendor_control`, and `uvc_probe`. My enablement configs are the ones listed above.
Now, let's call `set-results`.



32/2 2026/09/16 09:58 tool set-results
0m Args:
{
  "EnableConfigs": [
    "USB_VIDEO_CLASS",
    "MEDIA_SUPPORT",
    "MEDIA_CAMERA_SUPPORT",
    "USB"
  ],
  "FocusSymbols": [
    "uvc_parse_control",
    "uvc_parse_standard_control",
    "uvc_parse_vendor_control",
    "uvc_probe"
  ],
  "Reasoning": "The patch modifies descriptor bounds checking in uvc_parse_control() within the USB Video Class (UVC) driver, ensuring descriptor length buffer[0] is within buflen and at least 3 bytes, and passing the descriptor-specific length rather than the remaining buffer length to uvc_parse_vendor_control() and uvc_parse_standard_control(). This code is executed during USB device probe and is fully reachable via USB gadget emulation (e.g., syz_usb_connect or raw-gadget).",
  "WorthFuzzing": true
}

Results:
{
  "EnableConfigs": [
    "USB_VIDEO_CLASS",
    "MEDIA_SUPPORT",
    "MEDIA_CAMERA_SUPPORT",
    "USB"
  ],
  "FocusSymbols": [
    "uvc_parse_control",
    "uvc_parse_standard_control",
    "uvc_parse_vendor_control",
    "uvc_probe"
  ],
  "Reasoning": "The patch modifies descriptor bounds checking in uvc_parse_control() within the USB Video Class (UVC) driver, ensuring descriptor length buffer[0] is within buflen and at least 3 bytes, and passing the descriptor-specific length rather than the remaining buffer length to uvc_parse_vendor_control() and uvc_parse_standard_control(). This code is executed during USB device probe and is fully reachable via USB gadget emulation (e.g., syz_usb_connect or raw-gadget).",
  "WorthFuzzing": true
}

33/1 2026/09/16 09:58 action If
4m Args:
{
  "WorthFuzzing": true
}

Results:
null

34/2 2026/09/16 09:58 agent kmsan-evaluator
4m Model:
core

Args:
null

Results:
{
  "KMSANReasoning": "The patch enhances bounds checking and descriptor length validation in `uvc_parse_control()`:\n1. It validates that `buffer[0] \u003e= 3` and `buffer[0] \u003c= buflen`, preventing infinite loops or buffer underflow/out-of-bounds memory accesses when stepping through USB descriptors.\n2. It passes the individual descriptor length `buffer[0]` instead of the remaining total buffer length `buflen` to `uvc_parse_vendor_control()` and `uvc_parse_standard_control()`, preventing reading beyond the descriptor boundary.\n\nThese changes address out-of-bounds reads and loop bounds errors on USB descriptor buffers. No stack or heap structures are copied to user space, no uninitialized variables or paddings are exposed or branched upon, and all entity allocations use kzalloc(). Any potential bugs related to these bounds checks are within KASAN's detection capabilities (OOB access). Therefore, a dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false
}

Instruction:
You are an expert Linux kernel security engineer specializing in kernel memory
error detectors (KASAN and KMSAN). Your job is to review the provided patch series and
determine if the code changes justify spawning a dedicated KMSAN (KernelMemorySanitizer)
fuzzing session in addition to standard KASAN fuzzing.

CRITICAL DISTINCTION BETWEEN KASAN AND KMSAN:
- Standard KASAN kernel builds (upstream-apparmor-kasan.config) already enable
  a comprehensive suite of debugging tools and sanitizers, including KASAN
  (out-of-bounds accesses, use-after-free, double free, invalid free), LOCKDEP
  (locking bugs and deadlocks), UB-sanitizers, and memory corruption checks.
- KMSAN (KernelMemorySanitizer) detects reads of UNINITIALIZED memory (stack, heap,
  or page allocations) and kernel-to-user memory info-leaks.

Rule: THERE IS NO SENSE IN RUNNING A KMSAN SESSION IF A BUG CAN BE CAUGHT BY KASAN,
LOCKDEP, OR OTHER STANDARD BUG DETECTORS.
A dedicated KMSAN fuzzing session incurs significant resource costs. You must ONLY
set NeedsKMSAN=true if the code changes introduce or expose UNINITIALIZED MEMORY risks
that are detected ONLY by KMSAN.

Look holistically at the patch series and surrounding code. Even if no direct
uninitialized field accesses or new buffer allocations are added in the diff itself,
a patch may alter control flow, bounds checking, or data length calculations in ways
that change how the rest of the code operates on existing buffers (e.g. allowing
uninitialized stack/heap memory to be read, copied to user space, or used in control
flow). Do not hesitate to use your code access tools to inspect the surrounding code,
called functions, and callers.

Set NeedsKMSAN=true ONLY IF the patch introduces or modifies:
1. Kernel structures sent to user space (via copy_to_user, put_user, netlink skb
   attributes, ioctl output arguments, socket options, or BPF buffers) where fields
   or structure padding might not be fully initialized/zeroed.
2. Conditional logic or branching that depends on potentially uninitialized variables
   or struct fields.
3. Allocation or initialization of complex data structures where uninitialized fields
   could be read later in reachable code paths.
4. Bounds checks, lengths, or logic in a way that allows surrounding code to access
   uninitialized bytes of existing buffers.

Set NeedsKMSAN=false IF:
- The code changes primarily risk out-of-bounds access, array overflows, NULL pointer
  dereferences, locking deadlocks, or use-after-free bugs (these are already caught
  by KASAN, LOCKDEP, or standard bug detectors).
- All stack/heap structures touched or introduced by the patch are fully zeroed
  or initialized (e.g. using = {0}, memset, kzalloc) before being read or copied.
- The patch does not introduce any risk of uninitialized memory usage or info-leaks.

Use your code access tools to inspect the surrounding code if necessary, then provide
detailed KMSANReasoning contrasting KASAN vs KMSAN applicability for this patch.
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
Target architecture: amd64

For your convenience, here is the diff of the changes:
commit cd1f319b30e622f5ed0d43897f2ef734a04d8f25
Author: syz-cluster <triage@syzkaller.com>
Date:   Wed Sep 16 09:28:42 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index e289cc71ba986..429f1ab19a2ac 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -1248,11 +1248,14 @@ static int uvc_parse_control(struct uvc_device *dev)
 	 */
 
 	while (buflen > 2) {
-		if (uvc_parse_vendor_control(dev, buffer, buflen) ||
+		if (buflen < buffer[0] || buffer[0] < 3)
+			return -EINVAL;
+
+		if (uvc_parse_vendor_control(dev, buffer, buffer[0]) ||
 		    buffer[1] != USB_DT_CS_INTERFACE)
 			goto next_descriptor;
 
-		ret = uvc_parse_standard_control(dev, buffer, buflen);
+		ret = uvc_parse_standard_control(dev, buffer, buffer[0]);
 		if (ret < 0)
 			return ret;
 

35/3 2026/09/16 09:58 llm kmsan-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 2204
							output: 44
							thoughts: 147
						

Thoughts:
**Analyzing a Patch for KMSAN Fuzzing Necessity**

Okay, so I need to decide if this patch in `drivers/media/usb/uvc/uvc_driver.c` warrants a specific KMSAN fuzzing session. Let's dig in. My primary goal here is to assess the potential risk and determine if this change introduces any new memory safety concerns that Syzkaller, with a KMSAN-focused approach, might uncover.

First, let's look at the safety implications. From a broad perspective, we're talking about hardening the kernel and testing its security posture. This is a defensive QA task, which puts it in the "benign" severity category in my mind. We're proactively looking for issues, not reacting to a known exploit.

Now, to the code. I'll need to understand the function in question, probably `uvc_parse_control`. I'll leverage my usual toolkit – either `read-file` to get a quick overview or `grepper` to search for relevant calls and data flow within that file and potentially surrounding code. My focus will be on memory access patterns, pointer arithmetic, and potential buffer overflows – the classic areas where KMSAN excels. I'll be looking for signs of uninitialized memory usage or out-of-bounds reads/writes. This is where I'll apply my experience; I'll need to determine whether the changes introduce new attack surfaces, or modify existing functionality in a way that warrants extra scrutiny by KMSAN.



36/3 2026/09/16 09:58 tool read-file
0m Args:
{
  "File": "drivers/media/usb/uvc/uvc_driver.c",
  "FirstLine": 1235,
  "LineCount": 50
}

Results:
{
  "Contents": "1235:\t}\n1236:\t\n1237:\tstatic int uvc_parse_control(struct uvc_device *dev)\n1238:\t{\n1239:\t\tstruct usb_host_interface *alts = dev-\u003eintf-\u003ecur_altsetting;\n1240:\t\tconst unsigned char *buffer = alts-\u003eextra;\n1241:\t\tint buflen = alts-\u003eextralen;\n1242:\t\tint ret;\n1243:\t\n1244:\t\t/*\n1245:\t\t * Parse the default alternate setting only, as the UVC specification\n1246:\t\t * defines a single alternate setting, the default alternate setting\n1247:\t\t * zero.\n1248:\t\t */\n1249:\t\n1250:\t\twhile (buflen \u003e 2) {\n1251:\t\t\tif (buflen \u003c buffer[0] || buffer[0] \u003c 3)\n1252:\t\t\t\treturn -EINVAL;\n1253:\t\n1254:\t\t\tif (uvc_parse_vendor_control(dev, buffer, buffer[0]) ||\n1255:\t\t\t    buffer[1] != USB_DT_CS_INTERFACE)\n1256:\t\t\t\tgoto next_descriptor;\n1257:\t\n1258:\t\t\tret = uvc_parse_standard_control(dev, buffer, buffer[0]);\n1259:\t\t\tif (ret \u003c 0)\n1260:\t\t\t\treturn ret;\n1261:\t\n1262:\tnext_descriptor:\n1263:\t\t\tbuflen -= buffer[0];\n1264:\t\t\tbuffer += buffer[0];\n1265:\t\t}\n1266:\t\n1267:\t\t/*\n1268:\t\t * Check if the optional status endpoint is present. Built-in iSight\n1269:\t\t * webcams have an interrupt endpoint but spit proprietary data that\n1270:\t\t * don't conform to the UVC status endpoint messages. Don't try to\n1271:\t\t * handle the interrupt endpoint for those cameras.\n1272:\t\t */\n1273:\t\tif (alts-\u003edesc.bNumEndpoints == 1 \u0026\u0026\n1274:\t\t    !(dev-\u003equirks \u0026 UVC_QUIRK_BUILTIN_ISIGHT)) {\n1275:\t\t\tstruct usb_host_endpoint *ep = \u0026alts-\u003eendpoint[0];\n1276:\t\t\tstruct usb_endpoint_descriptor *desc = \u0026ep-\u003edesc;\n1277:\t\n1278:\t\t\tif (usb_endpoint_is_int_in(desc) \u0026\u0026\n1279:\t\t\t    le16_to_cpu(desc-\u003ewMaxPacketSize) \u003e= 8 \u0026\u0026\n1280:\t\t\t    desc-\u003ebInterval != 0) {\n1281:\t\t\t\tuvc_dbg(dev, DESCR,\n1282:\t\t\t\t\t\"Found a Status endpoint (addr %02x)\\n\",\n1283:\t\t\t\t\tdesc-\u003ebEndpointAddress);\n1284:\t\t\t\tdev-\u003eint_ep = ep;\n"
}

37/3 2026/09/16 09:58 llm kmsan-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 3495
							output: 37
							thoughts: 403
						

Thoughts:
**Analyzing the UVC Driver Patch**

Okay, let's take another look at this patch for the UVC driver. It seems like the core of the change lies within the `uvc_parse_control` function. Initially, the code had a while loop processing buffer data. Inside this loop, it was calling `uvc_parse_vendor_control` and `uvc_parse_standard_control` functions, but was passing in the whole `buflen` variable as size to read.

The updated code now includes a crucial check: `if (buflen < buffer[0] || buffer[0] < 3) return -EINVAL;`. This immediately flags a potential issue, it suggests there are size limits to the buffer passed to this function.

Then, there's a change in how the length is passed to the parser functions. The patch now passes `buffer[0]` as the `buflen` argument to both `uvc_parse_vendor_control` and `uvc_parse_standard_control` instead of the original `buflen`. This strongly implies the first byte of the buffer, `buffer[0]`, holds the actual length of the descriptor being processed, which is a common practice in USB descriptors.

My concern is that the original implementation could have been reading past the end of the descriptor if the parser functions didn't properly validate their input length, which could lead to memory corruption or undefined behavior. This new check and the use of `buffer[0]` likely aim to resolve that by correctly interpreting the descriptor lengths. I should quickly verify if this introduced any regressions, but the changes look sensible.



38/3 2026/09/16 09:59 tool grepper
0m Args:
{
  "Expression": "uvc_parse_vendor_control",
  "PathPrefix": "drivers/media/usb/uvc/"
}

Results:
{
  "Output": "drivers/media/usb/uvc/uvc_driver.c=871=static void uvc_entity_set_name(struct uvc_device *dev, struct uvc_entity *entity,\n--\ndrivers/media/usb/uvc/uvc_driver.c-892-/* Parse vendor-specific extensions. */\ndrivers/media/usb/uvc/uvc_driver.c:893:static int uvc_parse_vendor_control(struct uvc_device *dev,\ndrivers/media/usb/uvc/uvc_driver.c-894-\tconst unsigned char *buffer, int buflen)\n--\ndrivers/media/usb/uvc/uvc_driver.c=1237=static int uvc_parse_control(struct uvc_device *dev)\n--\ndrivers/media/usb/uvc/uvc_driver.c-1253-\ndrivers/media/usb/uvc/uvc_driver.c:1254:\t\tif (uvc_parse_vendor_control(dev, buffer, buffer[0]) ||\ndrivers/media/usb/uvc/uvc_driver.c-1255-\t\t    buffer[1] != USB_DT_CS_INTERFACE)\n"
}

39/3 2026/09/16 09:59 llm kmsan-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 4592
							output: 43
							thoughts: 42
						

Thoughts:
Here's my summary, as if I were thinking it:

**Diving into the UVC Driver's Standard Control Parsing**

Okay, time to get my hands dirty. I'm going to jump into `drivers/media/usb/uvc/uvc_driver.c`, specifically lines 892 through 950. That section is where the magic happens – it's where we parse the standard controls for the UVC device. I need to refresh my memory on the intricacies of the `uvc_parse_standard_control` function. I have a feeling I'll find the answers to my questions there. Let's see how the driver handles the descriptor parsing. I need to understand this functionality to ensure compatibility with all UVC devices.



40/3 2026/09/16 09:59 tool read-file
0m Args:
{
  "File": "drivers/media/usb/uvc/uvc_driver.c",
  "FirstLine": 892,
  "LineCount": 60
}

Results:
{
  "Contents": " 892:\t/* Parse vendor-specific extensions. */\n 893:\tstatic int uvc_parse_vendor_control(struct uvc_device *dev,\n 894:\t\tconst unsigned char *buffer, int buflen)\n 895:\t{\n 896:\t\tstruct usb_device *udev = dev-\u003eudev;\n 897:\t\tstruct usb_host_interface *alts = dev-\u003eintf-\u003ecur_altsetting;\n 898:\t\tstruct uvc_entity *unit;\n 899:\t\tunsigned int n, p;\n 900:\t\tint handled = 0;\n 901:\t\n 902:\t\tswitch (le16_to_cpu(udev-\u003edescriptor.idVendor)) {\n 903:\t\tcase 0x046d:\t\t/* Logitech */\n 904:\t\t\tif (buffer[1] != 0x41 || buffer[2] != 0x01)\n 905:\t\t\t\tbreak;\n 906:\t\n 907:\t\t\t/*\n 908:\t\t\t * Logitech implements several vendor specific functions\n 909:\t\t\t * through vendor specific extension units (LXU).\n 910:\t\t\t *\n 911:\t\t\t * The LXU descriptors are similar to XU descriptors\n 912:\t\t\t * (see \"USB Device Video Class for Video Devices\", section\n 913:\t\t\t * 3.7.2.6 \"Extension Unit Descriptor\") with the following\n 914:\t\t\t * differences:\n 915:\t\t\t *\n 916:\t\t\t * ----------------------------------------------------------\n 917:\t\t\t * 0\t\tbLength\t\t1\t Number\n 918:\t\t\t *\tSize of this descriptor, in bytes: 24+p+n*2\n 919:\t\t\t * ----------------------------------------------------------\n 920:\t\t\t * 23+p+n\tbmControlsType\tN\tBitmap\n 921:\t\t\t *\tIndividual bits in the set are defined:\n 922:\t\t\t *\t0: Absolute\n 923:\t\t\t *\t1: Relative\n 924:\t\t\t *\n 925:\t\t\t *\tThis bitset is mapped exactly the same as bmControls.\n 926:\t\t\t * ----------------------------------------------------------\n 927:\t\t\t * 23+p+n*2\tbReserved\t1\tBoolean\n 928:\t\t\t * ----------------------------------------------------------\n 929:\t\t\t * 24+p+n*2\tiExtension\t1\tIndex\n 930:\t\t\t *\tIndex of a string descriptor that describes this\n 931:\t\t\t *\textension unit.\n 932:\t\t\t * ----------------------------------------------------------\n 933:\t\t\t */\n 934:\t\t\tp = buflen \u003e= 22 ? buffer[21] : 0;\n 935:\t\t\tn = buflen \u003e= 25 + p ? buffer[22+p] : 0;\n 936:\t\n 937:\t\t\tif (buflen \u003c 25 + p + 2*n) {\n 938:\t\t\t\tuvc_dbg(dev, DESCR,\n 939:\t\t\t\t\t\"device %d videocontrol interface %d EXTENSION_UNIT error\\n\",\n 940:\t\t\t\t\tudev-\u003edevnum, alts-\u003edesc.bInterfaceNumber);\n 941:\t\t\t\tbreak;\n 942:\t\t\t}\n 943:\t\n 944:\t\t\tunit = uvc_alloc_new_entity(dev, UVC_VC_EXTENSION_UNIT,\n 945:\t\t\t\t\t\t    buffer[3], p + 1, 2 * n);\n 946:\t\t\tif (IS_ERR(unit))\n 947:\t\t\t\treturn PTR_ERR(unit);\n 948:\t\n 949:\t\t\tmemcpy(unit-\u003eguid, \u0026buffer[4], 16);\n 950:\t\t\tunit-\u003eextension.bNumControls = buffer[20];\n 951:\t\t\tmemcpy(unit-\u003ebaSourceID, \u0026buffer[22], p);\n"
}

41/3 2026/09/16 09:59 llm kmsan-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 5845
							output: 37
							thoughts: 16
						

Thoughts:
Okay, let's dive into this. Here's my perspective on that thought process:

**Diving into UVC Control Parsing**

Alright, so we're talking about UVC parsing, and my mind immediately jumps to `uvc_parse_standard_control`. We've already been through a bunch of considerations, but this function is crucial, a real cornerstone of handling Universal Video Class controls. Understanding how *that* works is going to be key to really grasping the whole control interface implementation. We need to dissect its role in interpreting the descriptors and translating that into the actual control actions. I'm keen to examine how it handles the different standard control types – get requests, set requests, all of it. Let's see how it orchestrates the parsing process and what implications that has for efficiency and error handling.



42/3 2026/09/16 09:59 tool grepper
0m Args:
{
  "Expression": "uvc_parse_standard_control",
  "PathPrefix": "drivers/media/usb/uvc/"
}

Results:
{
  "Output": "drivers/media/usb/uvc/uvc_driver.c=893=static int uvc_parse_vendor_control(struct uvc_device *dev,\n--\ndrivers/media/usb/uvc/uvc_driver.c-967-\ndrivers/media/usb/uvc/uvc_driver.c:968:static int uvc_parse_standard_control(struct uvc_device *dev,\ndrivers/media/usb/uvc/uvc_driver.c-969-\tconst unsigned char *buffer, int buflen)\n--\ndrivers/media/usb/uvc/uvc_driver.c=1237=static int uvc_parse_control(struct uvc_device *dev)\n--\ndrivers/media/usb/uvc/uvc_driver.c-1257-\ndrivers/media/usb/uvc/uvc_driver.c:1258:\t\tret = uvc_parse_standard_control(dev, buffer, buffer[0]);\ndrivers/media/usb/uvc/uvc_driver.c-1259-\t\tif (ret \u003c 0)\n"
}

43/3 2026/09/16 09:59 llm kmsan-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 6355
							output: 43
							thoughts: 21
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Diving into `uvc_parse_standard_control`**

Okay, let's zero in on `uvc_parse_standard_control` – specifically, I need to get my bearings around line 968. I'm going to quickly refresh my memory on what it's responsible for. My instinct tells me this is where the meat of the standard control parsing logic lives, so I need to understand what's happening here with the specific control I am investigating. I'm expecting to see the standard descriptors being interrogated – things like the bmAttributes, wMaxPacketSize, and bInterval fields. I'll be looking for how the routine handles different control requests, and how it handles potential error conditions. Depending on what it is reading, it might also have some logic to handle alternate interfaces and associated endpoints. The key here will be understanding how it differentiates between various standard control requests (e.g., still image capture controls vs. video streaming controls). I'm anticipating some bit-field manipulation and conditional checks based on the UVC specification.



44/3 2026/09/16 09:59 tool read-file
0m Args:
{
  "File": "drivers/media/usb/uvc/uvc_driver.c",
  "FirstLine": 968,
  "LineCount": 70
}

Results:
{
  "Contents": " 968:\tstatic int uvc_parse_standard_control(struct uvc_device *dev,\n 969:\t\tconst unsigned char *buffer, int buflen)\n 970:\t{\n 971:\t\tstruct usb_device *udev = dev-\u003eudev;\n 972:\t\tstruct uvc_entity *unit, *term;\n 973:\t\tstruct usb_interface *intf;\n 974:\t\tstruct usb_host_interface *alts = dev-\u003eintf-\u003ecur_altsetting;\n 975:\t\tunsigned int i, n, p, len;\n 976:\t\tconst char *type_name;\n 977:\t\tunsigned int id;\n 978:\t\tu16 type;\n 979:\t\n 980:\t\tswitch (buffer[2]) {\n 981:\t\tcase UVC_VC_HEADER:\n 982:\t\t\tn = buflen \u003e= 12 ? buffer[11] : 0;\n 983:\t\n 984:\t\t\tif (buflen \u003c 12 + n) {\n 985:\t\t\t\tuvc_dbg(dev, DESCR,\n 986:\t\t\t\t\t\"device %d videocontrol interface %d HEADER error\\n\",\n 987:\t\t\t\t\tudev-\u003edevnum, alts-\u003edesc.bInterfaceNumber);\n 988:\t\t\t\treturn -EINVAL;\n 989:\t\t\t}\n 990:\t\n 991:\t\t\tdev-\u003euvc_version = get_unaligned_le16(\u0026buffer[3]);\n 992:\t\t\tdev-\u003eclock_frequency = get_unaligned_le32(\u0026buffer[7]);\n 993:\t\n 994:\t\t\t/* Parse all USB Video Streaming interfaces. */\n 995:\t\t\tfor (i = 0; i \u003c n; ++i) {\n 996:\t\t\t\tintf = usb_ifnum_to_if(udev, buffer[12+i]);\n 997:\t\t\t\tif (intf == NULL) {\n 998:\t\t\t\t\tuvc_dbg(dev, DESCR,\n 999:\t\t\t\t\t\t\"device %d interface %d doesn't exists\\n\",\n1000:\t\t\t\t\t\tudev-\u003edevnum, i);\n1001:\t\t\t\t\tcontinue;\n1002:\t\t\t\t}\n1003:\t\n1004:\t\t\t\tuvc_parse_streaming(dev, intf);\n1005:\t\t\t}\n1006:\t\t\tbreak;\n1007:\t\n1008:\t\tcase UVC_VC_INPUT_TERMINAL:\n1009:\t\t\tif (buflen \u003c 8) {\n1010:\t\t\t\tuvc_dbg(dev, DESCR,\n1011:\t\t\t\t\t\"device %d videocontrol interface %d INPUT_TERMINAL error\\n\",\n1012:\t\t\t\t\tudev-\u003edevnum, alts-\u003edesc.bInterfaceNumber);\n1013:\t\t\t\treturn -EINVAL;\n1014:\t\t\t}\n1015:\t\n1016:\t\t\t/*\n1017:\t\t\t * Reject invalid terminal types that would cause issues:\n1018:\t\t\t *\n1019:\t\t\t * - The high byte must be non-zero, otherwise it would be\n1020:\t\t\t *   confused with a unit.\n1021:\t\t\t *\n1022:\t\t\t * - Bit 15 must be 0, as we use it internally as a terminal\n1023:\t\t\t *   direction flag.\n1024:\t\t\t *\n1025:\t\t\t * Other unknown types are accepted.\n1026:\t\t\t */\n1027:\t\t\ttype = get_unaligned_le16(\u0026buffer[4]);\n1028:\t\t\tif ((type \u0026 0x7f00) == 0 || (type \u0026 0x8000) != 0) {\n1029:\t\t\t\tuvc_dbg(dev, DESCR,\n1030:\t\t\t\t\t\"device %d videocontrol interface %d INPUT_TERMINAL %d has invalid type 0x%04x, skipping\\n\",\n1031:\t\t\t\t\tudev-\u003edevnum, alts-\u003edesc.bInterfaceNumber,\n1032:\t\t\t\t\tbuffer[3], type);\n1033:\t\t\t\treturn 0;\n1034:\t\t\t}\n1035:\t\n1036:\t\t\tn = 0;\n1037:\t\t\tp = 0;\n"
}

45/3 2026/09/16 09:59 llm kmsan-evaluator
1m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 7763
							output: 37
							thoughts: 815
						

Thoughts:
**Analyzing the UVC Control Parsing Bug Fix**

Okay, so I'm looking at this patch and the bug it fixes in `uvc_parse_control`. The core issue seems to be a flawed understanding of how `buflen` was used.  Initially, `buflen` represented the *remaining* length of the entire `alts->extralen` buffer, not the length of the individual USB descriptor we were currently parsing, which is correctly identified as `buffer[0]`.

The original code was incredibly vulnerable. It was calling functions (`uvc_parse_vendor_control`, `uvc_parse_standard_control`) and doing length calculations based on the *total* buffer length (`buflen`), when it should have been using the descriptor's individual length (`buffer[0]`). Critically, there were no checks to ensure that `buffer[0]` wasn't larger than `buflen` or smaller than the minimum valid descriptor size (which appears to be 3 bytes).  This meant we had potential for underflow if `buffer[0]` was greater than `buflen`, an infinite loop if `buffer[0]` was 0 (or underflow), and out-of-bounds reads. The incorrect use of `buflen` inside the parsing functions also meant they could read beyond the intended descriptor.

The patch's fix is pretty straightforward and elegant. It introduces crucial checks: `if (buflen < buffer[0] || buffer[0] < 3)` to validate that the descriptor's declared length is reasonable. It then *correctly* passes `buffer[0]` (the descriptor length) to `uvc_parse_vendor_control` and `uvc_parse_standard_control`. This restricts parsing to the actual descriptor size and prevents the out-of-bounds access.

Now, let's consider potential new issues. I need to make sure this patch isn't introducing *or* exposing any uninitialized memory risks.  The `buffer` is `alts->extra` and comes from USB descriptors parsed by the USB core. It looks like the patch itself only tightens bounds checks and modifies the length passed to these parsing functions. It doesn't initialize any new memory or modify how the descriptor is obtained. The fact that the patch restricts the length passed to the parsing functions, essentially reducing it from `buflen` to `buffer[0]`, *should* not introduce any uninitialized memory reads or writes, as `buffer` is derived from USB descriptors. I'll need to double-check whether the now limited length passed to `uvc_parse_vendor_control` and `uvc_parse_standard_control` exposes any such risks.  I'll start by checking how memory is allocated and initialized in those functions, specifically looking for any calls to `uvc_alloc_new_entity` or similar allocation routines that may read or pass potentially uninitialized data.



46/3 2026/09/16 10:01 tool grepper
0m Args:
{
  "Expression": "uvc_alloc_new_entity",
  "PathPrefix": "drivers/media/usb/uvc/"
}

Results:
{
  "Output": "drivers/media/usb/uvc/uvc_driver.c=798=static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING;\ndrivers/media/usb/uvc/uvc_driver.c-799-\ndrivers/media/usb/uvc/uvc_driver.c:800:static struct uvc_entity *uvc_alloc_new_entity(struct uvc_device *dev, u16 type,\ndrivers/media/usb/uvc/uvc_driver.c-801-\t\t\t\t\t       u16 id, unsigned int num_pads,\n--\ndrivers/media/usb/uvc/uvc_driver.c=893=static int uvc_parse_vendor_control(struct uvc_device *dev,\n--\ndrivers/media/usb/uvc/uvc_driver.c-943-\ndrivers/media/usb/uvc/uvc_driver.c:944:\t\tunit = uvc_alloc_new_entity(dev, UVC_VC_EXTENSION_UNIT,\ndrivers/media/usb/uvc/uvc_driver.c-945-\t\t\t\t\t    buffer[3], p + 1, 2 * n);\n--\ndrivers/media/usb/uvc/uvc_driver.c=968=static int uvc_parse_standard_control(struct uvc_device *dev,\n--\ndrivers/media/usb/uvc/uvc_driver.c-1056-\ndrivers/media/usb/uvc/uvc_driver.c:1057:\t\tterm = uvc_alloc_new_entity(dev, type | UVC_TERM_INPUT,\ndrivers/media/usb/uvc/uvc_driver.c-1058-\t\t\t\t\t    buffer[3], 1, n + p);\n--\ndrivers/media/usb/uvc/uvc_driver.c-1135-\ndrivers/media/usb/uvc/uvc_driver.c:1136:\t\tterm = uvc_alloc_new_entity(dev, type | UVC_TERM_OUTPUT,\ndrivers/media/usb/uvc/uvc_driver.c-1137-\t\t\t\t\t    id, 1, 0);\n--\ndrivers/media/usb/uvc/uvc_driver.c-1157-\ndrivers/media/usb/uvc/uvc_driver.c:1158:\t\tunit = uvc_alloc_new_entity(dev, buffer[2], buffer[3],\ndrivers/media/usb/uvc/uvc_driver.c-1159-\t\t\t\t\t    p + 1, 0);\n--\ndrivers/media/usb/uvc/uvc_driver.c-1180-\ndrivers/media/usb/uvc/uvc_driver.c:1181:\t\tunit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], 2, n);\ndrivers/media/usb/uvc/uvc_driver.c-1182-\t\tif (IS_ERR(unit))\n--\ndrivers/media/usb/uvc/uvc_driver.c-1209-\ndrivers/media/usb/uvc/uvc_driver.c:1210:\t\tunit = uvc_alloc_new_entity(dev, buffer[2], buffer[3],\ndrivers/media/usb/uvc/uvc_driver.c-1211-\t\t\t\t\t    p + 1, n);\n--\ndrivers/media/usb/uvc/uvc_driver.c=1340=static int uvc_gpio_parse(struct uvc_device *dev)\n--\ndrivers/media/usb/uvc/uvc_driver.c-1360-\ndrivers/media/usb/uvc/uvc_driver.c:1361:\tunit = uvc_alloc_new_entity(dev, UVC_EXT_GPIO_UNIT,\ndrivers/media/usb/uvc/uvc_driver.c-1362-\t\t\t\t    UVC_EXT_GPIO_UNIT_ID, 0, 1);\n"
}

47/3 2026/09/16 10:01 llm kmsan-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 10250
							output: 43
							thoughts: 21
						

Thoughts:
Here's my attempt at summarizing the thought process, tailored for an expert audience:

**Diving into uvc_alloc_new_entity**

Okay, let's zero in on `uvc_alloc_new_entity`. I need to refresh my memory of how this function fits into the overall UVC entity allocation scheme. Specifically, I'm thinking about line 800 - often that's a key point in these allocation functions, where the real meat of the allocation itself, or a critical initialization step, takes place. I need to understand this entity's lifecycle from creation to destruction and how it affects the overall device functionality. I'm focusing on the allocation process to spot any potential concurrency issues, resource leaks, or unexpected behavior.



48/3 2026/09/16 10:01 tool read-file
0m Args:
{
  "File": "drivers/media/usb/uvc/uvc_driver.c",
  "FirstLine": 800,
  "LineCount": 40
}

Results:
{
  "Contents": " 800:\tstatic struct uvc_entity *uvc_alloc_new_entity(struct uvc_device *dev, u16 type,\n 801:\t\t\t\t\t\t       u16 id, unsigned int num_pads,\n 802:\t\t\t\t\t\t       unsigned int extra_size)\n 803:\t{\n 804:\t\tstruct uvc_entity *entity;\n 805:\t\tunsigned int num_inputs;\n 806:\t\tunsigned int size;\n 807:\t\tunsigned int i;\n 808:\t\n 809:\t\t/* Per UVC 1.1+ spec 3.7.2, the ID should be non-zero. */\n 810:\t\tif (id == 0) {\n 811:\t\t\tdev_err(\u0026dev-\u003eintf-\u003edev, \"Found Unit with invalid ID 0\\n\");\n 812:\t\t\tid = UVC_INVALID_ENTITY_ID;\n 813:\t\t}\n 814:\t\n 815:\t\t/* Per UVC 1.1+ spec 3.7.2, the ID is unique. */\n 816:\t\tif (uvc_entity_by_id(dev, UVC_HARDWARE_ENTITY_ID(id)))\n 817:\t\t\tdev_err(\u0026dev-\u003eintf-\u003edev, \"Found multiple Units with ID %u\\n\",\n 818:\t\t\t\tUVC_HARDWARE_ENTITY_ID(id));\n 819:\t\n 820:\t\tif (uvc_entity_by_id(dev, id))\n 821:\t\t\tid = UVC_INVALID_ENTITY_ID;\n 822:\t\n 823:\t\textra_size = roundup(extra_size, sizeof(*entity-\u003epads));\n 824:\t\tif (num_pads)\n 825:\t\t\tnum_inputs = type \u0026 UVC_TERM_OUTPUT ? num_pads : num_pads - 1;\n 826:\t\telse\n 827:\t\t\tnum_inputs = 0;\n 828:\t\tsize = sizeof(*entity) + extra_size + sizeof(*entity-\u003epads) * num_pads\n 829:\t\t     + num_inputs;\n 830:\t\tentity = kzalloc(size, GFP_KERNEL);\n 831:\t\tif (entity == NULL)\n 832:\t\t\treturn ERR_PTR(-ENOMEM);\n 833:\t\n 834:\t\tentity-\u003eid = id;\n 835:\t\tentity-\u003etype = type;\n 836:\t\n 837:\t\t/*\n 838:\t\t * Set the GUID for standard entity types. For extension units, the GUID\n 839:\t\t * is initialized by the caller.\n"
}

49/3 2026/09/16 10:01 llm kmsan-evaluator
1m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 11154
							output: 234
							thoughts: 872
						

Thoughts:
**Analyzing a USB Descriptor Parsing Fix**

Okay, so I'm looking at this patch and my initial thought is: `uvc_alloc_new_entity` uses `kzalloc`, so memory allocation itself isn't a concern for uninitialized memory. Let's dig into the core change within `uvc_parse_control`. It seems we are refining the descriptor parsing logic.

Essentially, the patch focuses on input validation and bounds checking when parsing USB descriptors. The existing code had some vulnerabilities. Specifically, it wasn't verifying that the descriptor length (`buffer[0]`) was less than or equal to the remaining buffer length (`buflen`). This could lead to buffer underflows and out-of-bounds accesses when the code tried to read beyond the provided data. It also didn't check if `buffer[0]` was at least 3, which could lead to an infinite loop, or out-of-bounds reads.

The patch's key improvements are:

1.  Explicitly validating `buffer[0] <= buflen` to prevent underflows.
2.  Checking if `buffer[0] >= 3` to avoid infinite loops and OOB accesses.
3.  Passing `buffer[0]` instead of `buflen` to `uvc_parse_vendor_control` and `uvc_parse_standard_control`, effectively limiting those functions to only read the current descriptor, and preventing them from peeking into the next one.

Now, the crucial question: Does this introduce any uninitialized memory risks? Let's break it down.

*   Out-of-bounds access, array overflows, and infinite loops are all detectable by KASAN or standard detectors, so those are not a concern.
*   By passing `buffer[0]` instead of `buflen`, it's clear we're preventing reads past the boundaries.
*   The patch doesn't introduce any new allocations of uninitialized memory.
*   It doesn't touch any kernel-to-user copying.
*   There aren't any uninitialized variables or struct fields being read.
*   We're using `kzalloc` which guarantees zero-initialization.

Therefore, KMSAN is not needed here. Any boundary violations or potential memory issues that are either fixed or introduced, are well within KASAN's domain.

To be extra certain, I need to verify that this aligns with the KMSAN guidelines.

The guidelines state `NeedsKMSAN=true` only if we're dealing with:

1.  Kernel structures sent to user space where fields might not be initialized. -- Not the case.
2.  Conditional logic based on potentially uninitialized variables. -- `buffer` is initialized by the USB subsystem. Not uninitialized.
3.  Allocation of complex data structures with uninitialized fields. -- `kzalloc` handles zeroing.
4.  Bounds checks that allow access to uninitialized bytes of existing buffers. -- The patch *tightens* bounds checks.

`NeedsKMSAN=false` if:

*   The risks are out-of-bounds access, overflows, NULL pointer dereferences, locking issues, or use-after-free – these are KASAN/LOCKDEP/etc. domains.
*   All touched structures are zeroed or initialized.
*   No risk of uninitialized memory or info-leaks.

It's clear. Everything here screams `NeedsKMSAN = false`. This patch is purely tightening up bounds checking, fixing potential access violations, and doesn't introduce any new uninitialized memory vulnerabilities.

Okay, I'm confident. Time to double-check everything, make sure my reasoning is clear, and call `set-results`.



50/3 2026/09/16 10:02 tool set-results
0m Args:
{
  "KMSANReasoning": "The patch enhances bounds checking and descriptor length validation in `uvc_parse_control()`:\n1. It validates that `buffer[0] \u003e= 3` and `buffer[0] \u003c= buflen`, preventing infinite loops or buffer underflow/out-of-bounds memory accesses when stepping through USB descriptors.\n2. It passes the individual descriptor length `buffer[0]` instead of the remaining total buffer length `buflen` to `uvc_parse_vendor_control()` and `uvc_parse_standard_control()`, preventing reading beyond the descriptor boundary.\n\nThese changes address out-of-bounds reads and loop bounds errors on USB descriptor buffers. No stack or heap structures are copied to user space, no uninitialized variables or paddings are exposed or branched upon, and all entity allocations use kzalloc(). Any potential bugs related to these bounds checks are within KASAN's detection capabilities (OOB access). Therefore, a dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false
}

Results:
{
  "KMSANReasoning": "The patch enhances bounds checking and descriptor length validation in `uvc_parse_control()`:\n1. It validates that `buffer[0] \u003e= 3` and `buffer[0] \u003c= buflen`, preventing infinite loops or buffer underflow/out-of-bounds memory accesses when stepping through USB descriptors.\n2. It passes the individual descriptor length `buffer[0]` instead of the remaining total buffer length `buflen` to `uvc_parse_vendor_control()` and `uvc_parse_standard_control()`, preventing reading beyond the descriptor boundary.\n\nThese changes address out-of-bounds reads and loop bounds errors on USB descriptor buffers. No stack or heap structures are copied to user space, no uninitialized variables or paddings are exposed or branched upon, and all entity allocations use kzalloc(). Any potential bugs related to these bounds checks are within KASAN's detection capabilities (OOB access). Therefore, a dedicated KMSAN fuzzing session is not warranted.",
  "NeedsKMSAN": false
}

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)