DF-4133 / verdict.json
{ "finding_id": "DF-4133", "status": "reproduced", "reproduced": 1, "impact": "panic", "confidence": "certain", "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.", "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": "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", "kernel_refs": [ "sys/dev/raid/vinum/vinumio.c:763", "sys/dev/raid/vinum/vinumio.c:775", "sys/dev/raid/vinum/vinumio.c:795", "sys/dev/raid/vinum/vinumio.c:803", "sys/dev/raid/vinum/vinumvar.h:63", "sys/dev/raid/vinum/vinumconfig.c:1621" ], "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).", "attempts": 4, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "runtime_sec": 1200, "guest_dirty": 0, "build_cmd": "cc -O -o vinum_linemash2 vinum_linemash2.c", "run_cmd": "vnconfig -c /dev/vn0 /root/vin.img; vinum read /dev/vn0s1a (or ./vinum_linemash2 /dev/vn0s1a 6)", "code_hash": "d2fb4acb2211bb55e19ac1a32bda6cf9562349c2c1f29493d222045bcbcb3a8f", "notes": "Single 60KB overflow on an idle guest survived (landed in free zone space); the resetconfig+relabel+re-read loop makes the next kmalloc(2048) consume the corrupted zone and faults deterministically at the vulnerable instruction.", "recommended_fix": "Clamp the copy loop to &config_line[MAXCONFIGLINE*2 - 1] (fix.diff).", "fix_status": "fixed", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "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.", "fix_evidence": "run.log fixed section (survived 6 iterations, RC=0); dmesg showing 12x clean parse errors; build.log BUILD_RC=0." } |