⬢ DragonFlyBSD Kernel Audit
DF-2573 / run_df2573_panic.sh
← back to finding ↓ download raw
#!/bin/sh
# run_df2573_panic.sh -- DF-2573 verification.  Two variants of the same
# root cause (SLIST_REMOVE on a connection never inserted;
# ng_device.c:290 and :300):
#
#   variant B (run first, needs a healthy boot): NON-EMPTY list +
#     injected readq kmalloc(10240, M_DEVBUF) failure  -> ng_device.c:300
#   variant A (after vm.sh down/up): EMPTY list + injected make_dev
#     failure                                              -> ng_device.c:290
#
# Each variant is expected to panic the vulnerable kernel; the console is
# captured from the host-side serial log.
set -u
cd "$(dirname "$0")"
VM=../../../dfbsd-qemu/vm.sh

echo "=== DF-2573 variant B: non-empty list, readq kmalloc failure ==="
$VM run_root 'sysctl -n kern.ngdpoc.stats; sysctl -n "kern.ngdpoc.trigger=mkpeer keepB"; sysctl -n kern.ngdpoc.stats; ls -l /dev/ngd*' 2>&1
echo "--- arming one-shot kmalloc(10240, M_DEVBUF) failure and driving newhook (expect PANIC at ng_device.c:300) ---"
$VM run_root 'sysctl -n "kern.ngdpoc.trigger=mkpeer_failreadq tB"' 2>&1 || true
sleep 10
$VM log 150 > run.panicB.console.txt 2>&1 || true
tail -60 run.panicB.console.txt

echo "=== guest state after variant B ==="
$VM status || true

echo "=== recovering guest (down/up; disk and NGDPOC kernel are preserved) ==="
$VM down >/dev/null 2>&1 || true
$VM up >/dev/null 2>&1 || true
sleep 5
$VM run_root 'uname -i' 2>&1

echo "=== DF-2573 variant A: EMPTY list, make_dev failure ==="
$VM run_root 'sysctl -n kern.ngdpoc.stats' 2>&1
$VM run_root 'sysctl kern.ngdpoc.fail_makedev=1' 2>&1
echo "--- driving newhook with make_dev failing (expect PANIC at ng_device.c:290) ---"
$VM run_root 'sysctl -n "kern.ngdpoc.trigger=mkpeer tA"' 2>&1 || true
sleep 10
$VM log 150 > run.panicA.console.txt 2>&1 || true
tail -60 run.panicA.console.txt
echo "=== guest state after variant A ==="
$VM status || true