⬢ DragonFlyBSD Kernel Audit
DF-3093 / run4.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-3093 run v4: NO contiguous free run >= count anywhere on the volume,
# so EVERY clusteralloc() takes the full two-pass fallback scan in
# clusteralloc1() -- the widest unsynchronized read window (whole-map
# bitmap walk) before chainalloc() sets bits.
#
# geometry: 512 MiB FAT32, 4 KiB clusters (131072 clusters).
#   setup: 500 x 1 MiB files (256-cluster runs) fill the whole volume,
#   delete every other one -> 250 free runs of 256 clusters + ~10 MiB
#   tail, NO run >= 4096 clusters.
#   race: 6 pinned procs x 2 rounds x 16 MiB (4096-cluster) writes;
#   each write = ~16 extendfile iterations = ~16 full fallback scans.
#
# detection: kernel DFDBG counters (instrumented kernel:
#   debug.df3093_overlaps = clusteralloc critical-section overlaps,
#   debug.df3093_double  = double usemap_alloc = hard cross-link),
#   offline fat_scan in-degree, foreign bytes, dmesg.
#
# usage: run4.sh [cycles] [procs] [rounds] [chunk]
set -u
ID=DF-3093
MNT=/mnt/df3093
VND=vn0
IMG=/root/df3093.img
CYCLES=${1:-2}
PROCS=${2:-6}
ROUNDS=${3:-2}
CHUNK=${4:-16777216}
DIR="$(dirname "$0")"

cleanup() {
	umount $MNT 2>/dev/null || true
	vnconfig -u $VND 2>/dev/null || true
}
trap cleanup EXIT

cd "$DIR" || exit 1
cc -O2 -o race2 race2.c || exit 1
cc -O2 -o fat_scan fat_scan.c || exit 1

c=1
while [ $c -le $CYCLES ]; do
	echo "=== cycle $c/$CYCLES: full-volume fragment + ${PROCS}p x ${ROUNDS}r x ${CHUNK}B ==="
	cleanup
	rm -f $IMG
	newfs_msdos -C 512m -c 8 $IMG >/dev/null 2>&1 || { echo newfs fail; exit 1; }
	vnconfig -c $VND $IMG
	mkdir -p $MNT
	mount_msdos -m 644 /dev/$VND $MNT || { echo mount fail; exit 1; }

	sysctl -n debug.df3093_overlaps debug.df3093_double > /tmp/dfdbg.before 2>/dev/null

	i=0
	while [ $i -lt 500 ]; do
		dd if=/dev/zero of=$MNT/F$(printf %03d $i) bs=1m count=1 \
		    >/dev/null 2>&1
		i=$((i + 1))
	done
	i=1
	while [ $i -lt 500 ]; do
		rm -f $MNT/F$(printf %03d $i)
		i=$((i + 2))
	done
	echo "fragmented: $(df $MNT | tail -1 | awk '{print $4}') 512B-secs free"

	./race2 $MNT $PROCS $ROUNDS $CHUNK 1
	sync
	echo "df after race: $(df $MNT | tail -1 | awk '{print $4}') free"
	umount $MNT
	vnconfig -u $VND
	echo "DFDBG overlaps/double before: $(cat /tmp/dfdbg.before | tr '\n' ' ')"
	sysctl -n debug.df3093_overlaps debug.df3093_double | tr '\n' ' '; echo
	dmesg | grep -c DFDBG
	if ./fat_scan $IMG; then
		:
	else
		echo "=== CYCLE $c: FAT SCAN FOUND CROSS-LINKS ==="
		cp $IMG /root/df3093-hit-$c.img
		exit 42
	fi
	c=$((c + 1))
done
echo "RESULT $ID: run4 complete, see DFDBG counters + scans above"