⬢ DragonFlyBSD Kernel Audit
DF-4100 / run1.sh
← back to finding ↓ download raw
#!/bin/sh
# run1.sh -- clean-boot verification run (production-handler rig).
# Sections: DF-4097 (opcode clobber), DF-4100 (dead recovery branch +
# hard-reset escalation), DF-4101 (stale callout race), DF-4099 (unknown
# comp_code leak + exhaustion wedge).  Paced with sleep+snap because the
# XPT device queue dispatches to btaction asynchronously.
R=/root/rig/dfbt_ctl
VH="sysctl -n kern.dfbt_vhba_hard_resets kern.dfbt_vhba_mbox_starts kern.dfbt_vhba_last_ctl"

echo "=============== DF-4097: XPT_RESET_DEV opcode clobber ==============="
echo "--- control: normal XPT_SCSI_IO TUR, CAM_DIR_NONE"
$R queue io 60000
sleep 1
$R snap 0
echo "--- XPT_RESET_DEV through the SAME production xpt_action path."
echo "    btaction stores opcode 0x81 INITIATOR_BUS_DEV_RESET (bt.c:1062)"
echo "    but btexecuteccb's nseg==0 path overwrites it with 0x00"
echo "    INITIATOR_CCB (bt.c:1285), leaving cmd_len=0 sense_len=0"
$R queue rst 60000
sleep 1
$R snap 1
echo "--- clean-complete both"
$R comp 0
$R comp 1
sleep 1

echo
echo "=============== DF-4100: recovery BCCB never BCCB_ACTIVE ==============="
echo "--- queue one I/O, then fire the production bttimeout() on it"
$R queue io 60000
sleep 1
$R snap 2
$R timeout 2
echo "--- recovery_bccb flags at BDR-arm time: rec_flags=0 == BCCB_FREE;"
echo "    nothing ever sets BCCB_ACTIVE on it (only bt.c:1302 does, and the"
echo "    recovery BCCB never transits btexecuteccb)"
echo "--- firmware completes the BDR mailbox with BMBI_OK -> production"
echo "    btdone must hit the bt.c:1388 guard and return early"
$R comprec
sleep 1
$R snap 2
echo "--- AC_SENT_BDR must NOT fire (async_bdr stays 0); the pending CCB's"
echo "    timer must stay stopped -> recovery branch dead"
echo "--- 3s later the 2s re-arm (bt.c:2215) fires bttimeout again ->"
echo "    BCCB_DEVICE_RESET -> hard reset branch (bt.c:2199-2200)"
sleep 3
$R snap 2
echo "vhba counters (hard_resets mbox_starts last_ctl): $VH"
$VH
dmesg | grep -E "btdone - Attempt|timed out|No longer in timeout|async event" | tail -6
$R simqrel

echo
echo "=============== DF-4101: stale bttimeout on recycled CCB ==============="
echo "--- queue ccb-A (healthy, 60s timeout); hold bt->lock; fire the"
echo "    production bttimeout on a kthread which blocks acquiring the"
echo "    lock -- the in-progress handler callout_stop cannot cancel"
$R queue io 60000
sleep 1
$R snap 3
$R hold
$R racefire 3
echo "--- with the stale handler blocked: complete ccb-A (BMBI_OK) and"
echo "    queue ccb-B; production btgetccb recycles the SAME bccb"
$R comp 3
$R queue io 60000
sleep 1
echo "--- ccb-B dispatched on the recycled bccb (bccb_kva must equal A's):"
$R snap 4
echo "--- release the lock: the stale bttimeout proceeds on ccb-B"
$R rel
sleep 1
echo "--- ccb-B (healthy, 60s) misreported as timed out: DEVICE_RESET flag,"
echo "    SIM frozen, BDR mailbox armed; ccb-A completed CAM_REQ_CMP:"
$R snap 3
$R snap 4
sleep 3
echo "--- 2s later: hard bus reset on the healthy bus; ccb-B completes"
echo "    CAM_CMD_TIMEOUT (0x0b):"
$R snap 4
$VH
dmesg | grep -E "timed out|No longer in timeout|stale handler" | tail -6
$R simqrel

echo
echo "=============== DF-4099: unknown comp_code leaks the BCCB/CCB ==============="
echo "--- queue a CAM_DIR_IN command (512B, real dmamap)"
$R queuein 60000 512
sleep 1
echo "--- firmware replies comp_code=0x42 (unknown; no default at"
echo "    bt.c:1451); callout_stop already ran at bt.c:1449"
$R compx 5 0x42 0x00 0x00
sleep 3
echo "--- 3s later: comp=0, flags=1 (ACTIVE), on_pending=1, timer=0:"
echo "    the BCCB and the CAM command are leaked forever"
$R snap 5
echo "--- exhaust every remaining BCCB the same way"
i=6
while [ $i -le 19 ]; do
	$R queue io 60000 >/dev/null
	sleep 1
	$R compx $i 0x42 0x00 0x00 >/dev/null
	i=$((i+1))
done
echo "--- all BCCBs leaked; the next I/O is CAM_REQUEUE_REQ'd (btgetccb"
echo "    NULL, resource_shortage, simq frozen) -> all I/O on the bus wedges"
$R queue io 60000
sleep 1
$R snap 20
$R snap 5
$R simqrel
echo "=============== run1 complete ==============="