#!/bin/sh
# DF-5115 trigger — ips_pci_detach() state corruption on EBUSY
#
# REQUIRES: physical IBM ServeRAID controller (PCI 1014:01bd / 1014:002e /
# 9005:0250) with at least one configured logical drive.
# On a machine without the hardware this script exits 42 (untestable).
#
# Success criterion (on real hardware): the SECOND kldunload returns success
# while the adapter IRQ is still installed; subsequent disk IO or the next
# adapter interrupt panics the kernel in ips_morpheus_intr/ips_copperhead_intr
# operating on freed softc memory.  dcons/db> backtrace shows ips_*_intr.

set -u

if ! pciconf -l 2>/dev/null | grep -qE 'chip=0x(01bd|002e)1014|chip=0x02509005'; then
	echo "DF-5115: no IBM/Adaptec ServeRAID controller present - untestable here"
	exit 42
fi

# 1. make the first detach fail EBUSY (busy ipsd disk)
dd if=/dev/zero of=/dev/serno/ipsd0s0 bs=64k count=100000 2>/dev/null &
DDPID=$!
sleep 1

# 2. first unload: fails EBUSY *after* sc->configured was cleared
kldunload ips; echo "first kldunload rc=$? (expect nonzero, EBUSY)"

# 3. stop the holder; state is already corrupted so the retry skips ALL
#    cleanup (ips_adapter_free + ips_pci_free) and returns success with the
#    IRQ handler still registered against sc.
kill $DDPID 2>/dev/null; wait $DDPID 2>/dev/null
kldunload ips; echo "second kldunload rc=$? (BUG: 0 while IRQ is live)"

echo "DF-5115: if the second unload returned 0, the softc is freed at unit"
echo "destruction with the interrupt handler installed - next IRQ = UAF."
