DF-3179 verdict — REPRODUCED (panic, unprivileged, default config)
====================================================================

Guest: DragonFly 6.5-DEVELOPMENT #0 X86_64_GENERIC (INVARIANTS), 4.25 GB RAM,
4 GB swap, tmpfs on /tmp (975M, boot default), tmpfs on /var/run/shm.

Baseline run (2026-09-07, user `maxx` uid 1001, no privileges, no usermount):

    $ mkdir -p /tmp/df3179 && cd /tmp/df3179 && ~/linkflood /tmp/df3179
    target /tmp/df3179: f_type=134 f_blocks=249856 f_files=999427
    links=200000 ... links=3000000
    (guest dies)

Serial console (dfbsd-qemu/vm.sh log):

    panic: tmpfs dirent: malloc limit exceeded
    cpuid = 4
    Trace beginning at frame 0xfffff80117f5f568
    _kmalloc_obj() at _kmalloc_obj+0x758
    tmpfs_alloc_dirent() at tmpfs_alloc_dirent+0x38
    tmpfs_nlink() at tmpfs_nlink+0x11a
    vop_nlink() at vop_nlink+0x57
    kern_link() at kern_link+0x252
    Debugger("panic")

Mechanism (source-traced):
  * tmpfs_vfsops.c:200-204 creates the per-mount "tmpfs dirent" malloc_type;
    only tm_node_zone gets kmalloc_obj_raise_limit (:206-207). The dirent
    zone keeps malloc's default ks_limit = kmem_lim_size()/10
    (kern_slaballoc.c:365-372) = 390 MB on this guest (confirmed by
    `vmstat -m`: "tmpfs_dirent ... Limit 390M").
  * tmpfs_subr.c:306-307: kmalloc_obj(..., M_WAITOK) — no M_NULLOK —
    so kern_kmalloc.c:703-707 / kern_slaballoc.c:863-878 panic() instead of
    returning NULL when the limit is hit.
  * tmpfs_nlink (tmpfs_vnops.c:1170) checks only LINK_MAX (per node);
    nothing bounds per-mount dirent count.  Each link() = 1 dirent
    (128 B) + ~16 B name; nodes/pages never consumed.
  * Observed threshold: panic between 3.0M and 3.2M links — matches
    (390 MB / 128 B) = 3,194,880 dirents.
  * Same bug reachable by root on any tmpfs via creat/mkdir/symlink once
    nodes_max exceeds (RAM/10)/128 (e.g. explicit nodes=, or default mounts
    on machines with swap ≥ ~1.1x RAM where derived nodes_max > threshold);
    reachable unprivileged on usermounts (vfs.usermount=1).

Fix validation (fix.diff applied to guest /usr/src, `make nativekernel`,
installed, rebooted):
  * Patched kernel: same `linkflood /tmp/df3179` run as user maxx →
    link()s proceed past 3.19M and terminate with ENOSPC
    ("link: No space left on device"), guest STAYS UP, filesystem still
    usable (create/unlink in a fresh subdirectory works). No panic.
  * fix.diff = (a) raise dirent+name zone limits with nodes_max at mount
    (tmpfs_vfsops.c, adjacent to the existing node-zone raise), and
    (b) tmpfs_alloc_dirent uses M_NULLOK + ENOSPC (tmpfs_subr.c), so no
    tmpfs zone exhaustion can ever panic regardless of configuration.

Status: reproduced / impact=panic (unprivileged local DoS, default config).
Primary deliverable for this class is the fix; no memory-corruption
primitive is involved (the panic is a deliberate allocator abort).

## 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.
