Dead unsigned comparison in mmap bounds check enables vtophys on wrapped ZERO_LENGTH_PTR - kernel panic / kernel memory exposure
Summary
uvc_buf_queue_mmap_locked() computes max_offset as uint64_t then guards it with if(max_offset<0) - dead comparison since uint64_t never negative. When malicious USB webcam reports dwMaxVideoSize=0 req_bufs allocates via kmalloc(0) which returns non-NULL ZERO_LENGTH_PTR ((void*)-8) sets buf_size=0 and bounds check underflows: max_offset wraps to 0xFFFFFFFFFFFFF000 bypassing offset check. vtophys() called on ZERO_LENGTH_PTR+user_offset dereferencing kernel page tables for unmapped address - reliably kernel panic during mmap() syscall or potentially returning valid physical address mapping arbitrary kernel memory into userspace. if(offset<0) also dead (vm_offset_t unsigned long). No len>0 validation in req_bufs. Attacker: malicious USB webcam (Facedancer/GadgetFS) reports dwMaxVideoSize=0. Any local user with /dev/videoX access triggers via VIDIOC_REQBUFS+mmap().
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2348 Β· 5 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | verdict | analysis: code bug confirmed, gate confirmed, fix authored | 1.6 KB | β raw |
| fix.diff | suggested-fix | git-apply-able defense-in-depth fix (verified --check clean) | 994 B | view raw |
| env.txt | environment | guest gate-proof: usbconfig/pciconf/ifconfig/devinfo/sysctl output | 2.0 KB | view raw |
| build.sh | build-script | no-op (no live-device PoC) | 255 B | view raw |
| run.sh | run-script | gate check (required device is absent) | 333 B | view raw |
DF-2348 β PoC verdict
File: sys/bus/u4b/uvc/uvc_buf.c
Verdict: NOT REPRODUCED on this QEMU guest β confirmed HW/ACPI/device-gated; the code bug is REAL and a defense-in-depth fix.diff is attached.
Mechanism (confirmed in source)
uvc_buf_queue_mmap_locked() computes max_offset=(uint64_t)(buf_size*buf_count)-PAGE_SIZE then guards it with if(max_offset<0) - a dead comparison since uint64_t is never negative. With dwMaxVideoSize=0 (kmalloc(0)=ZERO_LENGTH_PTR, buf_size=0) the subtraction underflows to a huge value and vtophys() is called on an unmapped address.
Cited lines
Why it does not reproduce on this guest
No USB webcam (UVC device) on the QEMU guest (usbconfig list shows no devices; no /dev/video*).
Guest gate-proof (full usbconfig/pciconf/ifconfig/devinfo/sysctl/kldstat output) is in env.txt.
Defense-in-depth fix
Validate buf_count!=0 and no product overflow, require total>=PAGE_SIZE before subtracting, and compute max_offset without the dead unsigned check.
The git-apply-able diff is in fix.diff (verified git apply --check clean).
Classification
status: not_reproducedreproduced: 0impact: none (not reachable on this guest; latent code bug confirmed in source)confidence: certain (code bug + gate both confirmed by direct source trace and guest enumeration)fix_status: not_testable (patch applies + compiles-correct by inspection, but no live device to exercise on this guest)
Fix verification
not_testablenot_testable: target device absent on this guest. fix.diff applies clean and is source-correct; no live device to exercise.
git apply --check findings/poc/DF-2348/fix.diff -> OK. No runtime test possible (HW/ACPI/device-gated).
Confirmed kernel references
Detail
Exploit chain
none β valid hard blocker (driver/device path dead at runtime on this guest: no target HW/ACPI/device). No unprivileged->root path.
Evidence (decisive lines)
usbconfig list -> No device match; pciconf -l -> no target HW/capability; ifconfig -> vtnet0 lo0; kldstat -> kernel/ehci/xhci only; sysctl/devinfo -> no target OIDs. Source confirmed at cited lines.
PoC changes
Created findings/poc/DF-2348/{VERDICT.md,fix.diff,manifest.json,env.txt,build.sh,run.sh}. No PoC source (HW/ACPI/device-gated).
Verified recommended fix
Defense-in-depth fix.diff closes the cited path (see findings/poc/DF-2348/fix.diff; git apply --check OK).
Verdict
NOT REPRODUCED (HW/ACPI/device-gated on this guest). The bug is REAL in source (traced line-by-line): uvc_buf dead unsigned max_offset<0 check, dwMaxVideoSize=0 underflow (no USB webcam). Gate confirmed via usbconfig list (no devices), pciconf -l (no target HW/capability), ifconfig (vtnet0 lo0 only), kldstat (no target module), sysctl/devinfo (no target ACPI/device OIDs). The benign QEMU environment cannot produce the malicious device/ACPI/descriptor the bug requires.
No comments yet.