#!/bin/sh
# DF-0032 run script -- reproduces the fdcopy-failure nprocs leak as an
# UNPRIVILEGED user, and prints the before/after kernel malloc-type counts
# that prove the permanent leak.
#
# Run on the DragonFlyBSD guest. As an unprivileged user:
#     ./build.sh && ./run.sh
#
# Expected (bug present): fork() returns ENOMEM (~700 times) on the RFFDG path;
# afterwards the M_PROC ("proc") malloc-type Count is permanently elevated by
# ~that many, while M_LWP and M_FILEDESC stay flat and `ps ax|wc -l` is
# unchanged (leaked procs are invisible SIDL orphans). See VERDICT.md / run.log.
#
# CAUTION: each run permanently consumes ~700 SYSTEM-WIDE maxproc slots until
# reboot. Repeating across ~4-6 unprivileged uids fully exhausts maxproc and
# fork-DoSes the whole system (no process, incl root, can fork). This single
# run is non-fatal but leaves the guest ~18% fork-exhausted; `vm.sh reset` to
# clean up.
set -e
cd "$(dirname "$0")"

echo "=== BEFORE: kernel malloc types (proc/lwp/subproc/file_desc) ==="
vmstat -m | awk '/^[[:space:]]+(proc|lwp|subproc|file_desc)[[:space:]]/'
echo "ps ax count: $(ps ax | wc -l)"

echo
echo "=== TRIGGER: exhaust.c (grow fd table via dup2, then fork RFFDG) ==="
./exhaust

echo
echo "=== AFTER: kernel malloc types ==="
echo "(proc Count should be ~+700 permanently; lwp & file_desc unchanged;"
echo " ps ax unchanged -- leaked SIDL orphans are invisible)"
vmstat -m | awk '/^[[:space:]]+(proc|lwp|subproc|file_desc)[[:space:]]/'
echo "ps ax count: $(ps ax | wc -l)"
