DF-0604 / race_live.sh
#!/bin/sh # DF-0604 โ Live cross-CPU race trigger (corrected approach) # # The original finding claimed concurrent SIOCAIFADDR calls race on pfi_buffer. # That's WRONG: SIOCAIFADDR dispatches ALL work to netisr0 (in.c:248), so # all ifaddr_events serialize on netisr0 โ no cross-CPU overlap. # # The REAL race window is between: # (A) pfioctl path: DIOCADDRULE -> pfi_dynaddr_setup -> pfi_kif_update # -> pfi_dynaddr_update -> pfi_table_update โ runs on CALLER'S CPU # (pfioctl does NOT dispatch to netisr0) # (B) ifaddr_event path: SIOCAIFADDR (dispatched to netisr0) -> # pfi_ifaddr_event -> pfi_kif_update -> pfi_table_update โ runs on NETISR0 # # These two paths CAN overlap: CPU X is inside pfi_table_update (blocked on # netisr_domsg to fill the buffer), while netisr0 is running its own # pfi_table_update for the ifaddr_event. Both modify the shared globals. # # This script runs both churners in parallel to trigger the race. # Must be run as root with pf loaded. PFCONF=/tmp/pf_0604.conf PFDEV=/dev/pf cat > "$PFCONF" << 'PFEOF' pass quick on vtnet0 inet from (vtnet0) to any pass quick on vtnet0 inet6 from (vtnet0) to any block in quick from (vtnet0:network) to any PFEOF echo "DF-0604 corrected race trigger: pfctl churn + ifaddr churn" echo " (A) pfctl -f loop on caller CPU (triggers pfi_table_update on caller CPU)" echo " (B) ifconfig alias/-alias loop (triggers pfi_table_update on netisr0)" echo "" DURATION=${1:-30} # (A) pfctl rule churn: flush + reload rules with dynamic interface expansion # Each reload calls pfi_dynaddr_setup -> pfi_table_update on the calling CPU ( while true; do pfctl -d >/dev/null 2>&1 pfctl -F all >/dev/null 2>&1 pfctl -f "$PFCONF" >/dev/null 2>&1 pfctl -e >/dev/null 2>&1 done ) & PFCTL_PID=$! echo "pfctl churn pid=$PFCTL_PID" # (B) ifaddr churn: SIOCAIFADDR alias/-alias on vtnet0 # Dispatched to netisr0, triggers ifaddr_event -> pfi_table_update on netisr0 ( s=$(socket -dgram -inet 2>/dev/null) || true COUNT=0 while true; do ifconfig vtnet0 alias 10.0.99.1/32 2>/dev/null ifconfig vtnet0 -alias 10.0.99.1 2>/dev/null COUNT=$((COUNT + 1)) done ) & IFADDR_PID=$! echo "ifaddr churn pid=$IFADDR_PID" echo "running for ${DURATION}s..." sleep "$DURATION" kill $PFCTL_PID $IFADDR_PID 2>/dev/null wait $PFCTL_PID $IFADDR_PID 2>/dev/null # Clean up pf state pfctl -d >/dev/null 2>&1 pfctl -F all >/dev/null 2>&1 echo "race trigger complete" |