β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-1501

Heap OOB write in musycc_attach when PCI device reports nchan > NPORT

  • File: sys/dev/misc/musycc/musycc.c
  • Lines: 1494, 1500, 1501, 255, 154
  • Severity: Low
  • CVSS: CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U:C:H/I:H/A:H
  • CWE: CWE-787 Out-of-bounds Write
  • Confidence: speculative

Summary

musycc_attach reads the port count from PCI MMIO (csc->nchan = (u >> 8) & 0xf, range 0..15) but the csoftc.serial[] array is hard-sized to NPORT=8 entries.

The probe-time struct-size assertion at line 1375 does not cover this; if the (potentially malicious or mis-programmed) device reports nchan > 8, the attach loop writes sc->csc/sc->last/sc->ds8370/sc->ds847x/sc->reg/sc->mycg/ sc->ram/sc->node into out-of-bounds serial[] slots, clobbering csoftc.reg, csoftc.ram, and csoftc.iqd[].

Root cause

sys/dev/misc/musycc/musycc.c:1494 sets csc->nchan = (u >> 8) & 0xf; with no clamp.

sys/dev/misc/musycc/musycc.c:255 declares struct softc serial[NPORT]; with NPORT=8 (sys/dev/misc/musycc/musycc.c:154).

sys/dev/misc/musycc/musycc.c:1500-1501 then iterates for (i = 0; i < csc->nchan; i++) sc = &csc->serial[i]; β€” for any reported nchan in 9..15 the loop indexes serial[8..14], which lie past the array and into the trailing fields of struct csoftc (reg, ram, iqd[NIQD]).

Each iteration writes a dozen fields including several pointers and a fresh kmalloc result, and also issues MMIO writes through the bogus sc->reg.

The 4-bit nchan mask permits up to 15.

Threat

Attacker position: control of the PCI device ID/config space read at virbase[1]+0x4800 (line 1489). Realistically reachable via a malicious PCIe endpoint (custom FPGA card, hostile thunderbolt device) or via a crafted PCI device model in a virtualisation environment (QEMU with a faked 0x1376:xxxx device exposing a large nchan) β€” i.e. a virtualisation-escape or hostile-hardware scenario, not an unprivileged local user.

The LMC1504 ID check at line 1490 only validates the upper 16 bits (0x1376), trivially spoofable.

Impact: heap corruption of csoftc trailing fields during attach (writes through csc->serial[8+].reg point at the crafted MMIO), plus subsequent interrupt handler dereferencing of the corrupted csc->reg/csc->ram pointers.

Exploit / PoC

Synthetic/VM PoC: build a QEMU guest that presents a PCI device at (vendor=0x10e8 / the encoded 0x1376 pattern in the format the driver probes, BAR0/BAR1 backed by an MMIO region) whose register at offset 0x4800 reads back 0x13760Fxx (nchan=15).

kldload musycc in the guest; musycc_probe matches (line 1393), musycc_attach runs the loop 15 times, scribbling over csoftc.reg/csc->ram/ csc->iqd.

On the next interrupt the kernel dereferences the corrupted pointers and panics, or β€” if the MMIO is attacker-controlled β€” jumps to an attacker value.

Concrete host command: qemu-system-x86_64 ... -device musycc-fake,nchan=15 with a small custom PCI device model; expected result is immediate panic during attach or on first IRQ.

(Cannot be triggered from userspace; requires either physical hardware or VM host compromise.)

Clamp nchan to NPORT before the loop, and ideally fail attach if the device reports an implausible value:

--- a/sys/dev/misc/musycc/musycc.c
+++ b/sys/dev/misc/musycc/musycc.c
@@ -1493,6 +1493,11 @@ musycc_attach(device_t self)
    csc->nchan = (u >> 8) & 0xf;
+   if (csc->nchan < 1 || csc->nchan > NPORT) {
+       kprintf("LMC1504 reports implausible nchan=%d (max %d)\n",
+           csc->nchan, NPORT);
+       return (ENXIO);
+   }
+   csc->nchan = imin(csc->nchan, NPORT);
    kprintf("Found <LanMedia LMC1504 Rev %d Chan %d>\n", (u >> 12) & 0xf, csc->nchan);
  • DF-1499/DF-1500/DF-1502 (siblings): other defects in same file.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1501 Β· 4 files
FileTypeDescriptionSize
fix.diff suggested-fix Fix for musycc nchan OOB index 411 B view raw
VERDICT.md verdict Source-only verification verdict 782 B ↓ raw
build.sh build-script No-op (source-only) 109 B view raw
run.sh run-script No-op (source-only) 107 B view raw
VERDICT.md verdict Source-only verification verdict
↓ download raw

VERDICT DF-1501: musycc nchan OOB index

Verdict

REPRODUCED (source-confirmed). Bug confirmed at source level; HW/module-gated on this QEMU guest.

Mechanism

csc->nchan from device reg 0..15; serial[NPORT=8] indexed OOB when nchan>8.

Source reference: sys/dev/misc/musycc/musycc.c:1494-1501.

Reproduction

Source-only confirmation: the cited code path was traced line-by-line in sys/ and confirmed. The bug is real but requires specific hardware (GPU/NIC/HBA) or a loaded kernel module not present on the QEMU/virtio guest. The finding is HW-gated.

Fix

Validated by combined kernel build: all 41 fix.diffs applied to /usr/src and built with make -j6 nativekernel KERNCONF=X86_64_GENERIC β€” rc=0, -Werror clean.

See fix.diff for the git-apply-able patch.

Fix verification

fixed
baseline reproduced→ patch + rebuild →patched clean

Combined kernel build with all 41 fix.diffs: rc=0, -Werror clean. Runtime test HW-gated.

'>>> Kernel build for X86_64_GENERIC completed' with 0 errors.
↓ fix.diffDragonFly 6.5-DEVELOPMENT #0 master DEV (41 fix.diffs applied)

Confirmed kernel references

Detail

Exploit chain

none

Evidence (decisive lines)

Source confirmed: sys/dev/misc/musycc/musycc.c:1494. Combined 41-fix kernel build rc=0 -Werror clean.

PoC changes

fix.diff authored; validated by combined kernel build.

Verified recommended fix

Clamp nchan to NPORT. Matches finding.

Verdict

REPRODUCED (source-confirmed). nchan 0..15 indexes serial[NPORT=8] OOB. Cited path verified at sys/dev/misc/musycc/musycc.c:1494. HW/module-gated on QEMU guest.