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

vinum_scandisk() copies on-disk config lines into config_line[2048] with no length bound: ~129 KB kernel heap overflow from crafted media, before any validation

Summary

vinum_scandisk reads 128KB of raw disk config and splits it into lines with an unbounded copy loop into a 2048-byte heap buffer. A vinum-labelled disk holding one 131071-byte line overflows the kernel heap by ~129KB with attacker-chosen bytes; the copy runs before parse_config so the content need not be valid config. LIVE-REPRODUCED with a crafted drive: Fatal trap 12 'Stopped at vinum_scandisk' - the faulting instruction is the vulnerable loop itself. Fix validated on rebuilt kernel: 6 read iterations complete with clean errors. Crafted-disk threat model (vinum read / boot autodetect over attacker media).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4133 Β· 12 files
FileTypeDescriptionSize
vinum_linemash2.c β€” 1.8 KB view raw
vinum_linemash.c β€” 1.8 KB view raw
lbl.bin β€” 512 B ↓ download
cfg_overflow.bin β€” 58.6 KB ↓ download
cfg_overflow_big.bin β€” 128.0 KB ↓ download
cfg_ok.bin β€” 87 B ↓ download
panic.txt β€” 665 B view raw
serial_full.txt β€” 189.6 KB view raw
run.log β€” 969 B view raw
fix.diff β€” 708 B view raw
verdict.json β€” 3.6 KB view raw
env.txt β€” 388 B view raw

Fix verification

fixed
baseline reproduced→ patch + rebuild →patched clean

Applied fix.diff to guest /usr/src, rebuilt kernel+vinum.ko (#1 Fri Sep 18 04:22), rebooted, re-created the crafted disk (131071-byte line), ran 6 read iterations: all parse cleanly ('Invalid configuration information', config updates disabled) and the guest stays up. Overflow gone.

run.log fixed section (survived 6 iterations, RC=0); dmesg showing 12x clean parse errors; build.log BUILD_RC=0.
↓ fix.diffper-fix-DF-4133

Confirmed kernel references

Detail

Exploit chain

crafted disk image (MBR slice + disklabel partition fstype vinum + vinum label magic at 4096 + 131071-byte 'A' line at VINUM_CONFIG_OFFSET=4608) -> vinum read /dev/vn0s1a -> vinum_scandisk reads 2xMAXCONFIG raw bytes -> unbounded eptr++ = cptr++ copies 131071 bytes into config_line[2048] -> ~129KB linear heap overwrite with 0x41 -> zone freelist/metadata corruption consumed on the next Malloc(2048) -> page fault in vinum_scandisk (RIP = the vulnerable loop).

Evidence (decisive lines)

panic.txt (Fatal trap 12, Stopped at vinum_scandisk+0x590), serial_full.txt (incl. kernel kvprintf of the 60KB 'A' line), run.log (control + baseline + fixed), fix.diff, vinum_linemash2.c, lbl.bin/cfg artifacts

PoC changes

Crafted label+config generated on host; disklabel64 with fstype 'vinum' required (FS_VINUM=14 checked by init_drive); VINUM_RESETCONFIG between iterations + relabel because remove_drive obliterates the on-disk magic; sector-aligned dd (bs=1 writes to the block device are rejected).

Verified recommended fix

Clamp the copy loop to &config_line[MAXCONFIGLINE*2 - 1] (fix.diff).

Verdict

vinum_scandisk() copies the on-disk configuration line into config_line (a 2048-byte kmalloc, vinumio.c:763) with no length bound (vinumio.c:795-797), stopping only at newline/NUL in the raw 128KB config read. A crafted vinum-labelled disk whose config area holds a single 131071-byte line overflows the kernel heap by ~129KB with attacker-chosen bytes BEFORE any parsing. Reproduced: page fault inside the vulnerable loop itself (Stopped at vinum_scandisk+0x590: cmpb $0xa,(%rax)) after the overflow corrupts the scan state; control run with a valid 87-byte config reads cleanly. Crafted-media threat model: any path that runs 'vinum read' / boot autodetect (vinum.drives) over attacker media. Fix (clamp the copy to the buffer) validated on a rebuilt kernel: 6 iterations of the identical crafted-disk read complete with clean 'Invalid configuration information' errors and no crash.