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)
PoC verification
Evidence pack
findings/poc/DF-4133 Β· 12 files| File | Type | Description | Size | |
|---|---|---|---|---|
| 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
fixedApplied 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.
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.
No comments yet.