DragonFlyBSD Kernel Audit
DF-0766 / live_test.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-0766 live NFS READDIR/READDIRPLUS corroboration.
# Sets up the NFS server (rpcbind/mountd/nfsd), exports /export, mounts it over
# loopback, and runs many directory listings (as the unprivileged user where
# possible) over a directory full of files whose name lengths are NOT multiples
# of 4 (so XDR padding rem in {1,2,3}).  Watches for any kernel panic / OOB /
# slab corruption.  Run as root on the guest.
#
# Because the XDR 4-byte alignment invariant keeps name-ends off cluster
# boundaries whenever rem>0, the claimed OOB is unreachable, so this script is
# expected to complete cleanly with the guest still up on BOTH the unpatched
# baseline (#0) and the single-fix kernel (#1).
set -e
echo "kernel: $(sysctl -n kern.version | head -1)"

# 1. populate an export directory with varied-name-length files (rem in 1..3)
mkdir -p /export/readdirtest
rm -f /export/readdirtest/* 2>/dev/null || true
for len in 1 2 3 5 6 7 9 10 11 13 14 15 17 18 19 21 22 23 25 26 27 29 30 31; do
    k=0
    while [ $k -lt 30 ]; do
        base=""
        c=0
        while [ $c -lt $len ]; do base="${base}x"; c=$((c+1)); done
        base="${base}${k}"
        : > "/export/readdirtest/${base}" 2>/dev/null || true
        k=$((k+1))
    done
done
chmod -R 755 /export
NFILES=$(ls /export/readdirtest | wc -l)
echo "created $NFILES files in /export/readdirtest (name lengths not mult of 4)"

# 2. exports + daemons
grep -q 'export' /etc/exports 2>/dev/null || \
    echo "/export -alldirs -maproot=root -network 127.0.0.0 -mask 255.0.0.0" >> /etc/exports
rpcbind 2>/dev/null || true
sleep 1
nfsd -u -t -n 4 2>/dev/null || true
mountd 2>/dev/null || true
sleep 2

# 3. mount over loopback
mkdir -p /mnt/nfstest
mount | grep -q nfstest || mount -t nfs -o tcp 127.0.0.1:/export /mnt/nfstest
echo "mounted: $(mount | grep nfstest)"

# 4. readdir stress as root (drives nfsrv_readdir AND nfsrv_readdirplus via getdents)
i=0
while [ $i -lt 400 ]; do
    ls -f /mnt/nfstest/readdirtest >/dev/null
    ls -la /mnt/nfstest/readdirtest >/dev/null 2>&1 || true
    i=$((i+1))
done
echo "READDIR stress: 800 ls passes over $NFILES-file dir -- DONE, no panic"

# 5. also do a READDIRPLUS-flavored listing (ls -l forces full attr fetch)
ls -la /mnt/nfstest/readdirtest | wc -l >/dev/null
echo "READDIRPLUS-style listing OK"

echo "RESULT: guest still up, no kernel panic / OOB / slab corruption observed"