β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-3072

tmpfs_alloc_vp KKASSERT(!TMPFS_VNODE_DOOMED) at subr.c:402 is an unguarded race window: NFS fhtovp lookups on an unlinked file during inactive's DOOMED..reclaim interval panic INVARIANTS kernels

Summary

tmpfs_inactive's tn_links==0 path sets tn_vpstate = TMPFS_VNODE_DOOMED (vnops:1799), releases the node lock, then runs tmpfs_truncate(vp, 0) - which for a large unlinked tmpfs file destroys millions of pages and can run for a long while - before vrecycle and tmpfs_reclaim finally store tn_vnode = NULL (vnops:1853). tmpfs_fhtovp (vfsops:451-462) scans tm_nodes_used by tn_id/tn_gen with no tn_links/DOOMED check and calls tmpfs_alloc_vp; any such caller taking the node lock inside that window sees node->tn_vnode != NULL (:395) and immediately trips KKASSERT((tn_vpstate & DOOMED) == 0) at :402 - panic on INVARIANTS/DEBUG builds. Name-based lookups cannot reach the window (links==0 means no dirent, namecache invalidated) - the only reachable racer is an NFS fh lookup on a root-exported tmpfs (unusual setup). Remote unauth NFS client with a stale fh hammering lookups while the server reclaims the unlinked file panics the INVARIANTS kernel - local DoS. Production kernels unaffected (assert compiled out; vhold/vget blocks on the vnode lock held through VOP_INACTIVE; list scan TMPFS_LOCK-serialized vs LIST_REMOVE - no UAF). Same assert family as DF-0779 but distinct site (fhtovp vs readdir cookie) and fix. Fix: handle the doomed-but-not-reclaimed vnode (return ENOENT + vx_put) and/or make fhtovp skip DOOMED/links==0 nodes in the scan. [VERIFIED pass2: two attempts defeated by unrelated nfsd instability incl. the incidental m_dup_data MT_DATA assert panic - target KKASSERT never reached]

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3072 Β· 10 files
FileTypeDescriptionSize
README.md β€” 308 B ↓ raw
VERDICT.md β€” 1.4 KB ↓ raw
df3072.c β€” 1.1 KB view raw
env.txt β€” 248 B view raw
fix.diff β€” 183 B view raw
incidental_nfsd_panic.txt β€” 32.6 KB view raw
manifest.json β€” 734 B view raw
run.log β€” 248 B view raw
run3072.sh β€” 774 B view raw
verdict.json β€” 1.8 KB view raw

DF-3072 - tmpfs fhtovp during inactive DOOMED..reclaim window KKASSERTs

Severity Low | verdict: not_reproduced | impact: none

Reproduce

Sources in this directory; build with cc -O2 -o <bin> <src> -pthread on the guest.

See VERDICT.md for the full narrative and run.log for the decisive output.

VERDICT.md
↓ download raw

DF-3072 verification

Kernel: DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64

Two attempts, both defeated by unrelated NFS-server instability before the target assert could fire. Attempt 1 (fstat-by-fh hammer at full speed against a 400MB tmpfs-backed exported file while root rm-ed it server-side): the guest panicked in the kernel NFS SERVER receive path instead - assertion "m->m_type == MT_DATA" failed in m_dup_data (uipc_mbuf.c:1806) via nfs_realign/nfsrv_rcv - an independent nfsd bug (panic captured in the pack). Attempt 2 (fstat throttled to ~3K/s): no panic; the guest WEDGED in namecache lock contention (cache_lock_shared diagnostics, nfs server not responding) requiring a hard reset. The tmpfs_alloc_vp DOOMED KKASSERT (tmpfs_subr.c:402) was never reached; the window requires an NFS-exported tmpfs which is itself an unusual configuration. Mechanism remains code-verified.

Kernel references

Fix

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.

Fix verification

not_testable
↓ fix.diffper-fix-DF-3072

Confirmed kernel references

Detail

Evidence (decisive lines)

VERDICT.md + run.log + sources

PoC changes

adjusted from finding sketch to guest syscall/layout reality

Verified recommended fix

diff: tmpfs_fhtovp scan skips nodes with tn_vpstate DOOMED or tn_links==0 (return ESTALE), and tmpfs_alloc_vp handles doomed-but-unreclaimed vnodes with ENOENT instead of KKASSERT.

Verdict

Two attempts, both defeated by unrelated NFS-server instability before the target assert could fire. Attempt 1 (fstat-by-fh hammer at full speed against a 400MB tmpfs-backed exported file while root rm-ed it server-side): the guest panicked in the kernel NFS SERVER receive path instead - assertion "m->m_type == MT_DATA" failed in m_dup_data (uipc_mbuf.c:1806) via nfs_realign/nfsrv_rcv - an independent nfsd bug (panic captured in the pack). Attempt 2 (fstat throttled to ~3K/s): no panic; the guest WEDGED in namecache lock contention (cache_lock_shared diagnostics, nfs server not responding) requiring a hard reset. The tmpfs_alloc_vp DOOMED KKASSERT (tmpfs_subr.c:402) was never reached; the window requires an NFS-exported tmpfs which is itself an unusual configuration. Mechanism remains code-verified.