⬢ DragonFlyBSD Kernel Audit
DF-5838 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5838",
  "status": "untested",
  "verdict": "Contract defect confirmed statically: cluster_collectbufs() documents that only buffers whose block size matches blksize are collected (sys/kern/vfs_cluster.c:1719-1721), but the getcacheblk SZMATCH filter at sys/kern/vfs_cluster.c:1746-1748 uses last_bp->b_bcount instead, while len (1737), the collection stride (1745) and cluster_writes endbp/teardown (1312-1342) are all computed in blksize units. A caller passing bp->b_bcount != blksize would hand ffs_reallocblks a mixed-size children list; ffs walks the block maps one fs_bsize block per child (sys/vfs/ufs/ffs_alloc.c:470-497) and frees every childs old block as a full fs_bsize block (ffs_alloc.c:535-541), so fragment-backed children corrupt the cylinder-group allocation bitmap - and the DIAGNOSTIC guards that would panic (ffs_alloc.c:375-388) are compiled out of release kernels. Not executed on the guest: every current caller (UFS sys/vfs/ufs/ufs_readwrite.c:377-380 full-block gate; HAMMER1 sys/vfs/hammer/hammer_vnops.c:841; HAMMER2 sys/vfs/hammer2/hammer2_vnops.c:1177; tmpfs sys/vfs/tmpfs/tmpfs_vnops.c:864-881) passes b_bcount == blksize, and an unprivileged user cannot decouple the two values through any VOP path, so the defect is latent. One-line fix authored.",
  "reproduced": false,
  "impact": "none",
  "confidence": "likely",
  "exploit_chain": "",
  "evidence": "findings/poc/DF-5838/VERDICT.md (full path:line analysis); findings/poc/DF-5838/fix.diff (one-line contract alignment); decisive lines: sys/kern/vfs_cluster.c:1746-1748 (b_bcount used) vs :1719-1721 (contract) vs :1737/:1745 (blksize arithmetic); sys/vfs/ufs/ffs_alloc.c:470-497+535-541 (full-block assumption downstream); sys/kern/vfs_bio.c:2799-2802 (SZMATCH semantics)",
  "kernel_refs": [
    "sys/kern/vfs_cluster.c:1746",
    "sys/kern/vfs_cluster.c:1719",
    "sys/kern/vfs_cluster.c:1737",
    "sys/vfs/ufs/ffs_alloc.c:470",
    "sys/vfs/ufs/ffs_alloc.c:535",
    "sys/kern/vfs_bio.c:2799"
  ],
  "poc_changes": "no PoC built - latent defect with no reachable trigger in this tree (all callers pass b_bcount == blksize); verification intentionally skipped per contract for Low hardening findings",
  "attempts": 0,
  "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": 0,
  "guest_dirty": 0,
  "build_cmd": "",
  "run_cmd": "",
  "code_hash": "",
  "notes": "Adjacent safe behavior noted: gap compaction keeps only buffers after the LAST gap (sys/kern/vfs_cluster.c:1750-1775) - conservative and correct for VOP_REALLOCBLKS contiguity, just an optimization-window shrink, not filed.",
  "recommended_fix": "Pass blksize (not last_bp->b_bcount) to getcacheblk in cluster_collectbufs so the SZMATCH filter matches the documented contract and the surrounding blksize-based cluster arithmetic.",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff authored against the read-only sys/ tree (one line); not built on the guest because behavior is byte-identical for every existing caller (b_bcount == blksize in all reachable paths) - nothing observable to measure (fix_status not_testable).",
  "fix_evidence": "findings/poc/DF-5838/fix.diff"
}