Heap underflow write when VS_COLORFORMAT or VS_FRAME precedes any VS_FORMAT descriptor
Summary
uvc_drv_parse_data at uvc_drv.c:1836 fmt=data->fmt-1 (96 bytes before allocation start). VS_COLORFORMAT :1842 writes fmt->colorspace at offset 30 (data->fmt-66). VS_FRAME :1924 increments fmt->nfrm at offset 8 (data->fmt-88). Both WITHOUT checking fmt has been advanced past data->fmt-1 by a prior VS_FORMAT case. Spec violation (COLORFORMAT/FRAME before FORMAT) causes heap underflow write 66-88 bytes before allocation. init_data_fmt counts these descriptors without ordering checks. Malicious USB webcam with reordered descriptor list. Corrupts slab metadata/free-list pointers -> write-what-where primitive. Fix: track fmt_seen, skip COLORFORMAT/FRAME writes until first FORMAT.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1012 Β· 11 files| File | Type | Description | Size | |
|---|---|---|---|---|
| poc.c | trigger-source | documentation harness (no live trigger possible on guest) | 3.6 KB | view raw |
| build.sh | build-script | cc -O -pipe -Wall -o poc poc.c | 140 B | view raw |
| run.sh | run-script | ./poc | 63 B | view raw |
| build.log | build-log | harness compile output, full | 13 B | view raw |
| run.log | run-log | harness run output | 1.1 KB | view raw |
| fix.diff | suggested-fix | fmt_seen flag: skip COLORFORMAT/FRAME writes before first VS_FORMAT | 1.4 KB | view raw |
| fix_build.log | build-log | uvc.ko module compile with fix applied, full output (clean, -Werror) | 19.5 KB | view raw |
| env.txt | environment | uname, cc, kldstat, pciconf, modules | 1.7 KB | view raw |
| VERDICT.md | verdict | narrative analysis | 4.3 KB | β raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
DF-1012 β VERDICT
Verdict
NOT REPRODUCED (live) β bug CONFIRMED via code trace, fix.diff compiles cleanly.
The heap-underflow bug claimed in the finding is real and the cited
line numbers are exact, but it cannot be exercised on the audit guest
because there is no USB UVC device (the QEMU/KVM guest's only USB is
the ehci/xhci controllers with no devices attached) and therefore no
code path that reaches uvc_drv_parse_data(). The bug is latent on
this guest and live on any physical host into which a (potentially
malicious) USB UVC webcam is plugged.
Mechanism (code trace)
uvc_drv_parse_data() parses a USB UVC Video Streaming interface's
class-specific descriptors. The relevant lines:
-
sys/bus/u4b/uvc/uvc_drv.c:1836c fmt = data->fmt - 1;data->fmtis a heap allocation ofdata->nfmtstruct uvc_data_formatobjects (96 bytes each on x86_64). Settingfmt = data->fmt - 1deliberately points fmt one slot BEFORE the allocation, intending that the firstVS_FORMAT_*descriptor will executefmt++to advance fmt onto slot 0. -
sys/bus/u4b/uvc/uvc_drv.c:1842-1846c case UDESCSUB_VS_COLORFORMAT: cld = (struct uvc_vs_color_desc *)desc; fmt->colorspace = uvc_drv_get_colorspace(cld->bColorPris); break;colorspaceis at byte offset 30 instruct uvc_data_format(verified fromuvc_drv.h:629-643). So if aVS_COLORFORMATdescriptor appears in the descriptor list BEFORE anyVS_FORMAT_*descriptor has executedfmt++, this writesdata->fmt - 96 + 30 == data->fmt - 66β a heap underflow 66 bytes before thedata->fmtallocation. -
sys/bus/u4b/uvc/uvc_drv.c:1924and:1955c fmt->nfrm++;in theVS_FRAME_UNCOMPRESSED/VS_FRAME_MJPEG/VS_FRAME_FRAME_BASEDcases.nfrmis at byte offset 8, so the same spec violation causes an 88-byte-underflow write.
uvc_drv_init_data_fmt() (which sizes data->fmt) counts descriptors
without any ordering check, so a malicious webcam can present a
descriptor list whose counts match but whose order violates the UVC
spec (COLORFORMAT/FRAME before any FORMAT) and overflow the parser.
Why it does not reproduce on this guest
| Audit-guest fact | Evidence |
|---|---|
| No USB device attached (only ehci/xhci controllers load) | kldstat shows only kernel + ehci.ko + xhci.ko; usbconfig list shows no devices |
| uvc.ko is shipped but never matches a device | kldstat does not list uvc.ko; ls /boot/kernel/uvc.ko shows it is available but unloaded |
uvc_drv_parse_data is only called from uvc_attach, which only runs when USB matches a UVC device |
sys/bus/u4b/uvc/uvc_drv.c:1776 + driver attach table |
There is no userspace or hardware path that reaches the vulnerable function on the audit guest.
Exploit chain
none β not a memory-corruption primitive we can drive on this guest.
The finding correctly identifies this as a heap underflow with
attacker-controlled content (the bColorPris byte flows through
uvc_drv_get_colorspace() into the underflow write) on a real host,
which would corrupt adjacent slab objects. On a default-GENERIC host
the slab INVARIANTS checks would likely catch the cross-type write and
panic (DoS); on a noinv host a write-what-where primitive may be
constructable by grooming the slab bucket holding data->fmt. Neither
is exercisable here.
Fix
fix.diff adds a fmt_seen flag that is set after the first
VS_FORMAT_* descriptor advances fmt, and guards the COLORFORMAT and
both FRAME_* cases with if (!fmt_seen) break;. This is a minimal,
targeted change at the root cause (unconditional writes to the
intentionally-undersized fmt pointer) and matches the finding's
recommended fix verbatim.
Fix validation
fix.diffapplies cleanly to/usr/src/sys/bus/u4b/uvc/uvc_drv.cwithpatch -p1(5 hunks all succeeded).- The patched
uvc.komodule compiles cleanly with-Werror(seefix_build.log). - Not live-tested (no USB UVC HW to attach a device to).
fix_status: not_testable (no live trigger available).
PoC changes
The finding folder was empty; this run authored:
- poc.c β documentation harness explaining the trigger precondition
and the vulnerable code path
- fix.diff β the verified fix
- build.sh, run.sh, build.log, run.log, env.txt,
fix_build.log, manifest.json, VERDICT.md
Fix verification
not_testablecompile validated
module/kernel build rc=0 -Werror
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. UVC COLORFORMAT/FRAME before FORMAT -> fmt=data->fmt-1 heap underflow write. No USB HW. Fix compiles.
No comments yet.