{
  "finding_id": "DF-3048",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "s_inodes_count is never validated against s_groups_count*s_inodes_per_group at mount; a crafted dirent with ino in (gcount*ipg, icount] makes ext2_vget/ino_to_fsba index fs->e2fs_gd[(ino-1)/ipg] far out of bounds. Reproduced: fatal kernel page fault with RIP in e2fs_gd_get_i_tables from a single stat() of the patched 'lost+found' entry. Fixed module rejects the image at mount.",
  "exploit_chain": "crafted ext2 image (icount=0x7ffffff0, dirent ino=0x40000002) -> root/usermount mount -> stat /mnt/lost+found -> ext2_lookup:809 passes (ino<=icount) -> VFS_VGET -> ext2_vget:1358 ino_to_fsba -> fs->e2fs_gd[1048576] (64MB past 1KB alloc) -> kernel page fault -> panic. Wild-read primitive: cg=(ino-1)/ipg attacker-chosen; unmapped->panic (demonstrated), mapped->garbage i_tables steers subsequent bread (not pursued to leak).",
  "evidence": "run.log (full session), panic.txt (console: RIP=e2fs_gd_get_i_tables), fix_run.txt (fixed module: mount EINVAL, guest alive)",
  "kernel_refs": ["sys/vfs/ext2fs/ext2_vfsops.c:606", "sys/vfs/ext2fs/ext2_vfsops.c:1358", "sys/vfs/ext2fs/fs.h:111", "sys/vfs/ext2fs/ext2_lookup.c:809", "sys/vfs/ext2fs/ext2_inode_cnv.c:116"],
  "poc_changes": "seed sketch had no working image: crafted with mke2fs 1.47 (-O ^metadata_csum,^64bit, -I 128), patched s_inodes_count and the root-dir lost+found dirent inode directly; guest lacks vnconfig so vntool.c (VNIOCATTACH) was written; mount(8) needed no changes.",
  "attempts": 1,
  "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": 95,
  "guest_dirty": 0,
  "build_cmd": "python3 craft.py df3048.img ; cc -O2 -o /root/vntool /root/vntool.c",
  "run_cmd": "kldload ext2fs; /root/vntool attach 0 /root/df3048.img; mount -t ext2fs -o ro /dev/vn0 /mnt/e2; stat /mnt/e2/lost+found",
  "code_hash": "3b9c6bab3c0f24d79cbf1b11f34ab8d40ae0b428a2c9a0077b2d79b6a4723944",
  "notes": "impact classified panic (reliable DoS from mounted image; OOB read primitive characterized). fhtovp path is NOT affected (bounds by gcount*ipg). Fix validated on rebuilt ext2fs.ko: mount denied EINVAL, no panic; pristine RW mount regression-checked.",
  "recommended_fix": "reject s_inodes_count > (uint64_t)gcount * ipg in ext2_compute_sb_data()",
  "fix_status": "fixed",
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0 (same kernel; ext2fs.ko module rebuilt with fix.diff hunk 2, 2026-09-05)",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "with the clamp the crafted image is rejected at mount (EINVAL 'inode count exceeds groups x inodes per group'); stat is harmless; guest healthy; identical-geometry reload and pristine RW mounts still work (regression checks in DF-3047/fix_run.txt console capture).",
  "fix_evidence": "findings/poc/DF-3048/fix_run.txt; findings/poc/DF-3047/fix.diff (hunk 2); fix console capture findings/poc/DF-3047/fix_run.txt"
}
