DF-3035 / manifest.json
{ "finding_id": "DF-3035", "title": "FFS allocator uses unvalidated on-disk cylinder-group header fields as kernel-memory offsets/indexes — crafted image gives attacker-offset OOB read/write on first allocation", "file": "sys/vfs/ufs/ffs_alloc.c", "verdict": "reproduced", "impact": "memcorrupt", "confidence": "certain", "reproduce": { "build": "tar czf /tmp/p.tgz -C findings/poc/DF-3035 cgxtool.c setup3035.sh fs.h dinode.h; ssh -F dfbsd-qemu/config dfbsd '/bin/sh -c \"mkdir -p /root/poc && cat > /tmp/p.tgz && tar xzf /tmp/p.tgz -C /root/poc && cc -O -o /tmp/cgxtool /root/poc/cgxtool.c\"'", "run": "guest# sh /root/poc/setup3035.sh cgx 0x40000000 (write fault in ffs_clusteracct)\nguest# sh /root/poc/setup3035.sh iusedoff 0x20000000 (read fault in ffs_nodealloccg)\nguest# sh /root/poc/setup3035.sh cgx 0 (control: allocation succeeds)", "expected": "stock kernel: Fatal trap 12, supervisor write / page not present, Stopped at ffs_clusteracct.isra.0+0x1eb: movl %eax,(%rdx,%rcx,4); with fix.diff: no panic, dd fails ENOSPC, control image still allocates" }, "kernel_refs": [ "sys/vfs/ufs/ffs_alloc.c:1127", "sys/vfs/ufs/ffs_alloc.c:1213", "sys/vfs/ufs/ffs_alloc.c:1215", "sys/vfs/ufs/ffs_alloc.c:1218", "sys/vfs/ufs/ffs_alloc.c:1257", "sys/vfs/ufs/ffs_alloc.c:1294", "sys/vfs/ufs/ffs_alloc.c:1383", "sys/vfs/ufs/ffs_alloc.c:1415", "sys/vfs/ufs/ffs_alloc.c:1463", "sys/vfs/ufs/ffs_alloc.c:1532", "sys/vfs/ufs/ffs_alloc.c:1836", "sys/vfs/ufs/ffs_alloc.c:1963", "sys/vfs/ufs/ffs_alloc.c:1010", "sys/vfs/ufs/fs.h:394", "sys/vfs/ufs/fs.h:398", "sys/vfs/ufs/ffs_vfsops.c:642" ], "fix": "fix.diff (ffs_chkcg validator + ffs_hashalloc cg clamp)", "artifacts": [ "README.md", "VERDICT.md", "cgxtool.c", "setup3035.sh", "fs.h", "dinode.h", "fix.diff", "build.log", "run.log", "run.setup.log", "run.patched.log", "panic1.txt", "panic2.txt", "panic3.txt", "panic4.txt", "env.txt", "manifest.json", "verdict.json" ] } |