DF-3253 / manifest.json
{ "finding_id": "DF-3253", "verdict": "reproduced", "impact": "dos", "confidence": "certain", "reproduce": { "build": "cd findings/poc/DF-3253 && ./build.sh", "run": "cd findings/poc/DF-3253 && REPS=1 NTHR=8 ITERS=120 ./run.sh badmagic", "expected": "baseline: 'DF-3253 SUMMARY: wins=N ebadf(poisoned handoffs seen by stat)=N' + 'UTIMES WIN ... utimes()=0 on a fnode the kernel ALWAYS rejects'; kernel console 'DF3253H: *** INVAL HANDOFF #N ***'; umount panics 'unmount: dangling vnode' intermittently (2/4 runs). With fix.diff applied: wins=0 ebadf=0 einval=960/960, UMOUNT_OK." }, "kernel_refs": [ "sys/vfs/hpfs/hpfs_hash.c:104", "sys/vfs/hpfs/hpfs_hash.c:116", "sys/vfs/hpfs/hpfs_hash.c:122", "sys/vfs/hpfs/hpfs_hash.c:135", "sys/vfs/hpfs/hpfs_vfsops.c:488", "sys/vfs/hpfs/hpfs_vfsops.c:506", "sys/vfs/hpfs/hpfs_vfsops.c:525", "sys/vfs/hpfs/hpfs_vfsops.c:529", "sys/vfs/hpfs/hpfs_vfsops.c:538", "sys/vfs/hpfs/hpfs_vnops.c:463", "sys/vfs/hpfs/hpfs_vnops.c:530", "sys/vfs/hpfs/hpfs_vnops.c:1056", "sys/kern/vfs_lock.c:589", "sys/kern/vfs_vnops.c:894" ], "artifacts": [ "README.md", "VERDICT.md", "poc.c", "craft_df3253.py", "build.sh", "run.sh", "fix.diff", "instrument_applied.diff", "stats_applied.diff", "instrument_df3253.diff", "run.baseline3.badmagic.log", "run.unhashonly.badmagic.log", "panic.console.txt", "panic.txt", "panic2.console.txt", "panic2.txt", "panic3.console.txt", "env.txt", "verdict.json", "manifest.json" ], "notes": "Race shape: namei's per-directory vnode lock serializes same-directory lookups (measured 1451 publishes / 0 waiter hits); the handoff needs two dirents in two directories pointing at the same fnode — provided by the crafted image. stat() observes the handoff as EBADF (VNON reaches cvn_stat's type switch, sys/kern/vfs_vnops.c:894); utimes() on the handed-off vnode is a full syscall success (hpfs_setattr has no v_type check). Unmount-after-racing panics 'unmount: dangling vnode' in 2/4 baseline runs. Fix attribution: creator-side hpfs_hphashrem on both post-publish error paths is load-bearing (validated alone: 0 handoffs); hash-side H_INVAL retry is defense-in-depth." } |