⬢ DragonFlyBSD Kernel Audit
DF-3211 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3211",
  "status": "untested",
  "reproduced": 0,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "md_lookup_swap reads only word [6] (low 32 bits) of the 64-bit NFSv3 fattr.size into a signed int (nfs_mountrpc.c:286; layout nfsproto.h:325: size spans words [5..6]) and divides it into the int swap_nblks (:296): a 2-4 GiB swap file yields a negative swap_nblks, >=4 GiB wraps mod 2^32 (8 GiB -> swap silently disabled); the v2 twin at :292 lands a >=2 GiB u32 size in the same signed int. nfs_mountroot then treats the negative count as truthy, doubles it, sets a negative n_size on the swap vnode, and passes it to swaponvps u_quad_t parameter where it sign-extends to ~2^64 blocks (nfs_vfsops.c:666-701, vm_swap.c) \u2014 corrupt swap geometry/boot failure. Arithmetic is certain; not runtime-testable because the code runs only during an NFS-root boot and the audit guest boots hammer2 from disk.",
  "exploit_chain": "",
  "evidence": "findings/poc/DF-3211/VERDICT.md steps 1-5; decisive lines: nfs_mountrpc.c:286 (v3[6] only, into signed int), :292 (v2 signed landing), :295-296 (swap_nblks = size/1024), nfsdiskless.h:70 (int swap_nblks), nfs_vfsops.c:691-692 (negative n_size), :701 + vm_swap.c swaponvp(u_quad_t) (sign extension), xdr_subs.h:83 (fxdr_hyper is the intended decoder)",
  "kernel_refs": [
    "sys/vfs/nfs/nfs_mountrpc.c:286",
    "sys/vfs/nfs/nfs_mountrpc.c:292",
    "sys/vfs/nfs/nfs_mountrpc.c:295",
    "sys/vfs/nfs/nfsproto.h:325",
    "sys/vfs/nfs/nfs_vfsops.c:691",
    "sys/vfs/nfs/nfs_vfsops.c:701",
    "sys/vfs/nfs/xdr_subs.h:83"
  ],
  "poc_changes": "none \u2014 seed not runnable (boot path); verdict is a wire-layout + signedness derivation cross-checked against nfsproto.h fattr layout and the fxdr_hyper macro",
  "attempts": 0,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 (X86_64_GENERIC; hammer2 disk root \u2014 boot path never executes)",
  "runtime_sec": 0,
  "guest_dirty": 0,
  "build_cmd": "",
  "run_cmd": "",
  "code_hash": "",
  "notes": "Trigger: legitimate server exporting a >2 GiB swap file, or DF-3205 forged LOOKUP reply (deterministic xid, unfiltered source). Downstream corruption is described from source; exact panic-vs-weird-failure at boot was not observable on the disk-root guest. Ceiling identical to the krpc pass-2 findings.",
  "recommended_fix": "decode fattr.size with fxdr_hyper(&fattribs.v3[5]) into u_quad_t and only accept sizes <= INT_MAX before storing into swap_nblks (fix.diff applies clean)"
}