# VERDICT — DF-3211

**status: untested** (boot-path-only; not runtime-testable on the audit guest)
**impact: dos** (boot-path: corrupt/negative swap geometry, boot failure; forged-reply vector covered by DF-3205's ceiling)
**confidence: certain** (arithmetic proof; downstream behavior described from source)

## Proof chain (path:line)

1. `sys/vfs/nfs/nfsproto.h:306-335` — v3 fattr wire layout: `fa_type[0], fa_mode[1], fa_nlink[2], fa_uid[3],
   fa_gid[4], nfsv3fa_size[5..6] (nfsuint64)`, … — size is a 64-bit hyper spanning words 5-6.
2. `sys/vfs/nfs/nfs_mountrpc.c:283-286` — reply fattr decoded into `fattribs.v3[21]`, then
   `size = fxdr_unsigned(u_int32_t, fattribs.v3[6]);` — **only word [6] (low 32 bits) is read**, high word [5]
   discarded; destination `int size` (:227) is **signed**.
   * low word ∈ [2^31, 2^32) → `size < 0` (e.g. swap file of 3 GiB → low word 0xC0000000 → size = -1073741824).
   * file ≥ 4 GiB → wraps mod 2^32 (8 GiB → low word 0 → swap "disabled").
3. `sys/vfs/nfs/nfs_mountrpc.c:295-296` — `nfsv3_diskless.swap_nblks = size / 1024;` — `swap_nblks` is
   `int` (`sys/vfs/nfs/nfsdiskless.h:70`) → negative KB for the 2–4 GiB window.
   v2 twin at :292: `fxdr_unsigned(u_int32_t, fattribs.v2[5])` into the same signed `size` (v2 fattr size is
   u32 at word [5], nfsproto.h:314) — same negative landing for ≥2 GiB.
4. Consumer `sys/vfs/nfs/nfs_vfsops.c:666-701` — `if (nd->swap_nblks)` (negative = true) →
   `nd->swap_nblks *= 2` (:669) → `VTONFS(vp)->n_size = VTONFS(vp)->n_vattr.va_size = nd->swap_nblks *
   DEV_BSIZE;` (:691-692) — **negative size on a VREG swap vnode** → `swaponvp(td, vp, nd->swap_nblks)`
   (:701) where the parameter is `u_quad_t nblks` (`sys/vm/vm_swap.c`) — sign extension to ≈2^64 blocks
   feeding the swap bitmap/accounting.
5. `sys/vfs/nfs/xdr_subs.h:83-84` — `fxdr_hyper(f)` exists and is the intended decoder for words [5..6];
   other consumers (e.g. nfs_subs.c attribute handling) use it for exactly this field.

## Why untested
Executes only during `nfs_mountroot` boot with an NFS root + swap path (`#if BOOTP||NFS_ROOT`). Audit guest
(DragonFly 6.5-DEVELOPMENT #0, X86_64_GENERIC) boots hammer2 from disk; no runtime path reaches
`md_lookup_swap`. Trigger on a real diskless client requires either a >2 GiB server swap file (plausible
misconfig) or the DF-3205 forged-LOOKUP vector.

## Impact assessment
Worst realistic: corrupt swap geometry at boot (negative vnode size, ~2^64-block swap claim) → boot failure /
vm accounting corruption — boot-path DoS ceiling. No post-boot runtime reachability, no memory-safety
primitive (values flow into sizes/counts, not pointers or copy lengths).

## Recommended fix
Decode the full 64-bit size and range-check before storing (see fix.diff).

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
