DragonFlyBSD Kernel Audit
DF-0032 / baseline_run.log
← back to finding ↓ download raw
DF-0032 baseline reproduction on UNPATCHED 6.5-DEVELOPMENT #0 (Thu Jul  2 06:02:54 UTC 2026)
Guest: DragonFly dfbsd 6.5-DEVELOPMENT #0 x86_64, KVM 6 vCPU / 4 GB RAM
       kern.maxproc=8132  kern.maxprocperuid=2033

=== BEFORE exhaust.c (as uid 1001 maxx) ===
               proc      24   0.99M       0    390M      887
                lwp      33   20.6K       0    390M      897
            subproc      46    112K       0    390M    1.73K
          file_desc      25   23.1K       0    390M      904
ps ax | wc -l = 197

=== ./exhaust ===
[*] RLIMIT_NPROC(cur) = 2033
[*] Phase 1: grow this proc's fd_files[] table via dup2()
[*] grew fd table to fd=14976 (fd_files[] ~234KB per fdcopy)
[*] Phase 2: fork() children (RFFDG) to accumulate M_FILEDESC
[*] watching for fork()==ENOMEM (the fdcopy-failure leak marker)
[!!!] ENOMEM from fork() -- fdcopy failure leak TRIGGERED at child 519
[!] first EAGAIN after 519 children (RLIMIT_NPROC / maxproc)
[*] summary: ok=519 eagain=51 enomem=1452 other=0
[!!!] BUG TRIGGERED: fork() returned ENOMEM (fdcopy failure)

=== AFTER exhaust.c (exhaust + its 519 children exited) ===
               proc   1.44K   2.76M       0    390M    2.81K   <- +1416 leaked struct proc
                lwp      33   20.6K       0    390M    1.40K   <- FLAT (leak is before lwp_fork1)
            subproc   2.88K   7.03M       0    390M    5.61K   <- +2834 leaked p_uidpcpu
          file_desc      25   23.1K       0    390M    3.34K   <- FLAT (newfdp M_NULLOK returned NULL)
ps ax | wc -l = 197   <- FLAT (leaked SIDL orphans invisible to ps)

FINGERPRINT MATCHES THE CODE TRACE EXACTLY:
  - proc Count up by ~1452 (== enomem count)  -> p2 kmalloc'd + on allproc, never freed
  - lwp flat  -> leak is at fdcopy (kern_fork.c:551), BEFORE lwp_fork1 (:674)
  - file_desc flat -> fdcopy's M_NULLOK newfdp returned NULL (kern_descrip.c:2481-2486)
  - ps flat   -> SIDL orphans skipped by allproc scans

The leaked nprocs / per-uid chgproccnt slots are PERMANENT (survive exhaust's
exit). Repeating across ~4-6 unprivileged uids exhausts maxproc=8132 and
fork-DoSes the whole system (root included) until reboot.