#!/bin/sh
# DF-5630 guest driver — run as ROOT on the guest.
# The crafted binaries are run as the unprivileged user 'maxx'.
cd /tmp/df5630

echo "== builds =="
cc -o make_note make_note.c
./make_note bug      /tmp/df5630/note_bug.bin
./make_note control  /tmp/df5630/note_ctl.bin
./make_note nonote   /tmp/df5630/note_none.bin
chmod 755 note_bug.bin note_ctl.bin note_none.bin
(cd kld && make clean >/dev/null 2>&1; make) || exit 1
kldload /tmp/df5630/kld/df_osrel.ko || { kldstat | grep df_osrel || exit 1; }

echo "== case 1: nonote (EI_OSABI=255, no PT_NOTE) — expect ENOEXEC =="
su -m maxx -c '/tmp/df5630/note_none.bin' 2>&1 && echo "UNEXPECTED: exec succeeded" || echo "-> exec failed as expected (ENOEXEC)"

echo "== case 2: control note (descriptor present) — expect p_osrel=0x44332211 =="
su -m maxx -c '/tmp/df5630/note_ctl.bin & echo PID=$!' > ctl.pid
sleep 1
CPID=$(grep '^PID=' ctl.pid | cut -d= -f2)
echo "ctl pid=$CPID (spinning)"
sysctl debug.df_osrel_pid=$CPID
echo "ctl p_osrel=$(sysctl -n debug.df_osrel_val) (expect 1144201745 = 0x44332211)"
kill -9 "$CPID" 2>/dev/null

echo "== case 3: BUG note (descriptor read fully past page end) =="
for i in 1 2 3; do
  su -m maxx -c '/tmp/df5630/note_bug.bin & echo PID=$!' > bug.pid
  sleep 1
  BPID=$(grep '^PID=' bug.pid | cut -d= -f2)
  echo "run $i: bug pid=$BPID (spinning)"
  sysctl debug.df_osrel_pid=$BPID >/dev/null
  sysctl -n debug.df_osrel_val | awk '{printf "  bug p_osrel=%d (0x%08x)\n", $1, $1}'
  kill -9 "$BPID" 2>/dev/null
done
kldunload df_osrel 2>/dev/null
echo done
