{
  "finding_id": "DF-3179",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "REPRODUCED on stock INVARIANTS X86_64_GENERIC: an unprivileged user (uid 1001) running a plain link(2) flood in the default-boot /tmp tmpfs panics the kernel with tmpfs dirent: malloc limit exceeded (kern_link -> tmpfs_nlink -> tmpfs_alloc_dirent -> _kmalloc_obj) once the mounts per-mount dirent zone hits its default ks_limit = kmem_lim/10 = 390MB on the 4GB guest (~3.19M dirents; observed between 3.0M and 3.2M links, ~90s). Root cause is mount-side: tmpfs_mount (tmpfs_vfsops.c:200-207) raises ONLY the node zone limit; the dirent zone keeps the malloc default and tmpfs_alloc_dirent (tmpfs_subr.c:306-307) allocates with M_WAITOK and no M_NULLOK, so the allocator PANICs on limit exhaustion instead of returning NULL; tmpfs_nlink has no dirent budget. fix.diff (raise dirent+name zone limits with nodes_max + M_NULLOK/ENOSPC in tmpfs_alloc_dirent) validated in-guest on a rebuilt kernel: same flood terminates with ENOSPC, guest stays up, filesystem recovers after freeing dirents.",
  "exploit_chain": "",
  "evidence": [
    "run.log (links=...3.0M then guest dies)",
    "panic.txt (full serial panic + backtrace tmpfs_alloc_dirent+0x38 <- tmpfs_nlink+0x11a <- kern_link+0x252)",
    "run.fixed.log (patched kernel: link(): No space left on device at ~3.12M, no panic)",
    "fix_validation.log",
    "env.txt"
  ],
  "kernel_refs": [
    "sys/vfs/tmpfs/tmpfs_vfsops.c:200",
    "sys/vfs/tmpfs/tmpfs_vfsops.c:206",
    "sys/vfs/tmpfs/tmpfs_subr.c:306",
    "sys/kern/kern_slaballoc.c:371",
    "sys/kern/kern_slaballoc.c:877",
    "sys/kern/kern_kmalloc.c:706",
    "sys/vfs/tmpfs/tmpfs_vnops.c:1170"
  ],
  "poc_changes": "initial draft needed sys/statfs.h include removed (DragonFly declares statfs in sys/mount.h); otherwise the seeded concept (link flood) worked as-is",
  "attempts": 2,
  "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": 90,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -o linkflood linkflood.c",
  "run_cmd": "mkdir -p /tmp/df3179 && ./linkflood /tmp/df3179   (as unprivileged user)",
  "code_hash": "d00312504e39bb9b05a58e1504d68530e6e75520ae6e45087188c965a3ed42de",
  "notes": "Also reachable by root on any tmpfs via creat/mkdir/symlink when nodes_max exceeds (RAM/10)/sizeof(tmpfs_dirent), and unprivileged on usermounts (vfs.usermount=1); link() is the zero-budget path (no nodes/pages consumed). Fix validation: nativekernel BUILD_RC=0, installkernel INSTALL_RC=0, reboot into kernel #1, re-run -> ENOSPC + guest up.",
  "recommended_fix": "raise dirent+name zone limits in proportion to tm_nodes_max at mount and allocate dirents with M_NULLOK returning ENOSPC",
  "fix_status": "fixed",
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1: Mon Sep  7 22:45:12 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "baseline panics at ~3.1M links; patched kernel with fix.diff returns ENOSPC from link(2) at the same threshold, no panic, filesystem remains usable and recovers after dirent free; guest reset to clean snapshot afterwards",
  "fix_evidence": [
    "fix_validation.log",
    "run.fixed.log"
  ]
}