DF-2801 / run.sh
#!/bin/sh # DF-2801 run โ root. Floor-comparison design: # The leaked namecache reference (cache_copy at kern_jail.c:206, never # cache_drop'ed on the error paths) permanently pins one namecache entry # per failed jail(). Lazy reclaim confounds instantaneous deltas, so we # compare settled floors: # F0 - settled baseline # control cycle -> F1 (jail fails BEFORE kern_jail: EFAULT at # copyinstr; no cache_copy; floor unchanged) # leak cycle -> F2 (jail fails AFTER cache_copy at kern_chroot # ENOTDIR; floor +~iters forever) # "pressure" = create+delete 8000 junk files to force the cache to # reclaim everything it *can*. set -e [ "$(id -u)" = 0 ] || { echo "must run as root"; exit 2; } D=/tmp/df2801 pressure() { mkdir -p /tmp/df2801press for i in $(jot 8000); do : > /tmp/df2801press/$i; done rm -rf /tmp/df2801press } settle() { pressure; sleep 5; } settle; F0=$(sysctl -n vfs.cache.numcache); echo "F0 baseline floor : $F0" echo "=== CONTROL cycle (EFAULT before kern_jail โ no cache_copy) ===" $D/jailleak 2000 control >/dev/null 2>&1 || true rm -f /tmp/df2801_* settle; F1=$(sysctl -n vfs.cache.numcache); echo "F1 after control cycle : $F1" echo "=== LEAK cycle (ENOTDIR after cache_copy โ ref leaked) ===" $D/jailleak 2000 leak rm -f /tmp/df2801_* settle; F2=$(sysctl -n vfs.cache.numcache); echo "F2 after leak cycle : $F2" echo "control growth: $((F1 - F0)) leak growth: $((F2 - F1))" if [ $((F2 - F1)) -gt 1000 ] && [ $((F1 - F0)) -lt 500 ]; then echo "REPRODUCED: ~$((F2 - F1)) namecache entries permanently pinned by 2000 failed jail(2) calls" fi |