# 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`):
```c
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`):
```c
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`):
```c
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).
