UAC2.0 Feature Unit descriptor accepted too short causing OOB read of bmaControls[0]
Summary
uaudio20_mixer_verify_desc only requires bLength>=6 for UAC2 Feature Unit (sizeof(*u.fu)=5 +1=6) but uaudio20_mixer_add_feature unconditionally reads UGETDW(d->bmaControls[0]) a 4-byte field at offset 5 requiring bLength>=9. Malicious USB audio device presenting UAC2.0 Audio Control interface with Feature Unit bLength 6-8 passes verification stored in node tree triggers 1-3 byte OOB read. If malformed FU is last descriptor in config descriptor read crosses end of kmalloc buffer into adjacent kernel heap. Contrast EFFECT case uses +4 correctly. Attacker: malicious USB audio device automatic enumeration on plug-in. Impact: small heap OOB read panic at page boundary or indirect info leak.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2333 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | verdict | gate analysis + too-short FU descriptor trace | 3.2 KB | β raw |
| fix.diff | suggested-fix | require bLength >= sizeof(fu)+4+1 in verifier | 362 B | view raw |
| build.sh | build-script | documents HW gate | 153 B | view raw |
| run.sh | run-script | prints gate proof | 290 B | view raw |
| env.txt | environment | guest env | 1.1 KB | view raw |
| usb_gate.txt | gate-proof | usbconfig empty, no /dev/ugen*/uaudio* | 375 B | view raw |
DF-2333 β UAC2.0 Feature Unit descriptor accepted too short (uaudio.c)
Verdict: NOT REPRODUCED (HW-gated); REAL BUG IN SOURCE (defense-in-depth fix warranted)
Hardware gate (why the PoC cannot run on this guest)
uaudio attaches only to a USB audio device plugged into the bus. The audit
QEMU/KVM guest has USB host controllers loaded (ehci.ko, xhci.ko) but no
USB device of any kind attached:
$ usbconfig list # No device match or lack of permissions. $ ls /dev/ugen* /dev/uaudio* # No such file or directory $ ls /dev/usb* # only /dev/usbctl (operator-readable; maxx not in operator) $ ifconfig -l # vtnet0 lo0 (no usb wlan)
With no USB audio device the uaudio driver never probes/attaches, so its
descriptor-parsing path (uaudio20_mixer_verify_desc /
uaudio20_mixer_add_feature) is never executed. The unprivileged maxx user
cannot plug a USB device into the QEMU guest, and even if a controller could be
made to enumerate, maxx is not in the operator group and cannot open
/dev/usbctl for device control. The bug requires a malicious physical USB
audio device.
Source trace β the bug is REAL (sys/bus/u4b/audio/uaudio.c)
struct usb_audio20_feature_unit (uaudioreg.h:690-698):
struct usb_audio20_feature_unit {
uByte bLength; uByte bDescriptorType; uByte bDescriptorSubtype;
uByte bUnitId; uByte bSourceId;
uDWord bmaControls[0]; /* flexible array; each entry is 4 bytes */
/* uByte iFeature; */
} __packed; /* sizeof == 5 */
Verification (uaudio.c:4000-4002):
case UDESCSUB_AC_FEATURE:
len += sizeof(*u.fu) + 1; /* requires bLength >= 5 + 1 = 6 only */
break;
Contrast UDESCSUB_AC_EFFECT (uaudio.c:4004-4005) which correctly adds
sizeof(*u.ef) + 4.
Consumer (uaudio.c:3563, inside uaudio20_mixer_add_feature):
if (UGETDW(d->bmaControls[0]) == 0) /* reads 4 bytes at offset 5: needs bLength >= 9 */
return;
...
mmask = UGETDW(d->bmaControls[0]); /* uaudio.c:3569 */
bmaControls[0] lives at offset 5 and is 4 bytes wide, so a well-formed Feature
Unit needs bLength >= 9. The verifier only demands bLength >= 6. A malicious
USB audio device presenting a UAC2 Feature Unit with bLength in 6..8 passes
verification, is stored in the mixer node tree, and then
uaudio20_mixer_add_feature performs a 1-3 byte OOB read at offset 5 of the
descriptor. If the truncated FU is the last descriptor in the config descriptor,
the read crosses the end of the kmalloc'd config buffer into adjacent kernel
heap β small heap OOB read / panic at a page boundary / latent info leak.
Trigger: malicious USB audio device, automatic enumeration on plug-in. No privilege, no user interaction.
Exploit chain status
Not pursuable β primitive (small OOB read) behind absent USB audio hardware (valid Phase-6 hard blocker: dead path at runtime on this guest). Read-only-ish bug; no escalation.
PoC changes
None. No USB audio device on guest; verified by source trace only.
Recommended fix
Require bLength >= sizeof(*u.fu) + 4 + 1 (room for bmaControls[0] + the
trailing iFeature byte). See fix.diff (supersedes finding proposal by
clamping to the actual first-control-field requirement).
Fix verification
not_testablenot_testable: PoC cannot run on this guest (HW-gated, no target device). fix.diff validated by git apply --check (clean) + line-accurate source trace confirming it closes the cited path.
git apply --check findings/poc/DF-2333/fix.diff -> OK (clean apply). No runtime test possible (HW-gated).
Confirmed kernel references
Detail
Exploit chain
none β valid hard blocker (driver/device path dead at runtime on this guest: no target HW / no attached device). No unprivileged->root path.
Evidence (decisive lines)
usbconfig list -> No device match or lack of permissions.; pciconf -l -> no target controller HW; ifconfig -l -> vtnet0 lo0; kldstat -> kernel/ehci/xhci only; ls /dev/<target> -> No such file or directory; id maxx -> uid=1001 groups=1001 (not operator). Source confirmed at cited lines.
PoC changes
Created findings/poc/DF-2333/{VERDICT.md,fix.diff,build.sh,run.sh,env.txt,gate_proof.txt,manifest.json}. No PoC source (HW-gated).
Verified recommended fix
verifier requires sizeof(*u.fu)+4+1 (room for bmaControls[0]+iFeature). Full git-apply-able diff in findings/poc/DF-2333/fix.diff (git apply --check OK).
Verdict
NOT REPRODUCED (HW-gated). The bug is REAL in source (traced line-by-line). uaudio UAC2.0 Feature Unit descriptor accepted too short (1-3 byte OOB read); no USB audio device. Gate confirmed via usbconfig list (No device match / no /dev/ugen*), pciconf -l (no target controller HW), ifconfig (vtnet0 lo0 only), kldstat (no target module), and ls /dev (no target nodes). maxx (uid 1001, not in operator) cannot reach any /dev/usbctl write path.
No comments yet.