⬢ DragonFlyBSD Kernel Audit
DF-2573 / run_df2574_leak.sh
← back to finding ↓ download raw
#!/bin/sh
# run_df2574_leak.sh -- DF-2574 verification (run on a HEALTHY X86_64_NGDPOC
# boot, BEFORE any panic experiments).  Demonstrates the struct
# ngd_connection leak in ng_device_disconnect (ng_device.c:411 region):
# every real newhook->disconnect cycle permanently loses one
# kmalloc(sizeof(struct ngd_connection), M_DEVBUF) allocation (40 bytes).
set -u
cd "$(dirname "$0")"
VM=../../../dfbsd-qemu/vm.sh

log() { echo "== $* =="; }

log "env"
$VM run_root 'uname -a; sysctl -n kern.ngdpoc.stats' 2>&1

log "control: M_DEVBUF noise floor without ngd activity (3 samples, 6s apart)"
$VM run_root 'for i in 1 2 3; do sysctl -n kern.ngdpoc.stats; sleep 6; done' 2>&1

log "warmup: 100 in-kernel cycles (real ng_mkpeer/ng_destroy_hook paths)"
$VM run_root 'sysctl -n "kern.ngdpoc.trigger=cycle 100"; sysctl -n kern.ngdpoc.stats' 2>&1

log "leak run 1: 20000 connect/disconnect cycles via the REAL netgraph path"
$VM run_root 'sysctl -n "kern.ngdpoc.trigger=cycle 20000"; sysctl -n kern.ngdpoc.stats' 2>&1

log "leak run 2: 20000 more cycles (linearity)"
$VM run_root 'sysctl -n "kern.ngdpoc.trigger=cycle 20000"; sysctl -n kern.ngdpoc.stats' 2>&1

log "userland real path: 500 cycles driven by ngctl (mkpeer + rmhook)"
$VM run_root '
set -e
sysctl -n kern.ngdpoc.stats
i=0
while [ $i -lt 500 ]; do
	ngctl mkpeer device: echo a$i b$i >/dev/null 2>&1 || true
	# exactly one of the two hooks landed on the device node
	ngctl rmhook device: a$i >/dev/null 2>&1 || ngctl rmhook device: b$i >/dev/null 2>&1 || true
	i=$((i+1))
done
sysctl -n kern.ngdpoc.stats
ngctl list 2>/dev/null | head -5 || true
' 2>&1

log "sanity: one live connection end-to-end through /dev/ngd0"
$VM run_root '
sysctl -n "kern.ngdpoc.trigger=mkpeer keep0"
sysctl -n kern.ngdpoc.stats
ls -l /dev/ngd0
printf DF2574 > /dev/ngd0
sleep 1
echo "read back from /dev/ngd0: [$(dd if=/dev/ngd0 bs=64 2>/dev/null)]"
sysctl -n "kern.ngdpoc.trigger=rmhook keep0"
sysctl -n kern.ngdpoc.stats
ls /dev/ngd0 2>&1 || true
' 2>&1

log "dmesg cycle BEGIN/END accounting lines"
$VM run_root 'dmesg | grep -E "NGDPOC: cycle" | tail -8' 2>&1