DF-4140 / verdict.json
{ "finding_id": "DF-4140", "status": "reproduced", "reproduced": 1, "impact": "panic", "confidence": "certain", "verdict": "drive->freelist is allocated once with 16 entries (256 bytes, vinumio.c:143-145, INITIAL_DRIVE_FREELIST=16) and freelist_size is never checked again; give_sd_to_drive case 3 (vinumconfig.c:429-439) and return_drive_space case 3 (:696-705) increment freelist_entries and write 16-byte {u64 offset, u64 sectors} entries with no bound. Reproduced: a crafted config placing 60 one-sector subdisks at 2-sector pitch grows the list to ~61 entries (~720 bytes past the 256-byte kmalloc); after the following zone reuse the kernel dereferenced one of the attacker-written values (fault VA 0x163 == sdend of sd f27) in prop_object_release -> Fatal trap 12. Root/operator config path and crafted-disk read path both reach it.", "exploit_chain": "config with N fragmented sd placements -> freelist_entries grows 1->N+1 in a 16-slot array -> 16-byte OOB writes of chosen u64 pairs past kmalloc(256) -> adjacent 256-byte zone objects (e.g. libprop objects) corrupted with small-integer pointers -> crash on use (0x163 deref). Ceiling: controlled heap corruption; the written offsets/lengths are config-chosen u64s.", "evidence": "panic.txt (fault VA == our sdend value), serial_full.txt, cfgfrag2.sec, README.md", "kernel_refs": [ "sys/dev/raid/vinum/vinumio.c:143", "sys/dev/raid/vinum/vinumconfig.c:429", "sys/dev/raid/vinum/vinumconfig.c:436", "sys/dev/raid/vinum/vinumconfig.c:696", "sys/dev/raid/vinum/vinumconfig.c:702", "sys/dev/raid/vinum/vinumvar.h:191" ], "poc_changes": "Used space-separated kernel config grammar; sizespec suffix s=sectors (first attempt with len 512b created 512-sector sds that overlapped); crash needed a second resetconfig+read cycle to consume the corrupted zone.", "attempts": 3, "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": 600, "guest_dirty": 0, "build_cmd": "n/a (crafted disk config; helper binaries from DF-4133 pack)", "run_cmd": "vinum read /dev/vn0s1a (crafted drive with cfgfrag2.sec)", "code_hash": "ce312e0a69d53848b9e89238e1cbc8133cdbf2b34084050374118d24a96bb416", "notes": "Adjacent object corruption demonstrated: the faulting pointer value equals the attacker-written freelist entry.", "recommended_fix": "EXPAND drive->freelist when freelist_entries reaches freelist_size before both insertion sites (field already exists for this).", "fix_status": "not_tested", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "Fix not built in this run (fix-validation kernel carried DF-4132/4133 only); proposed EXPAND guard in README.", "fix_evidence": "panic.txt baseline." } |