DF-2799 / jailistreader.c
/* * DF-2799 — unprivileged side of the deadlock: hammer * `sysctl jail.list` (world-readable, no privileges required). * Each read takes its CPU's gd_sysctllock SHARED across the handler and * then blocks on jail_lock while the root churner holds it. * * Runs for <secs> seconds (or forever if 0). */ #include <sys/sysctl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <time.h> static time_t t0; int main(int argc, char **argv) { int secs = argc > 1 ? atoi(argv[1]) : 60; static char buf[1 << 19]; long n = 0, errs = 0; t0 = time(NULL); for (;;) { size_t len = sizeof(buf); if (sysctlbyname("jail.list", buf, &len, NULL, 0) < 0) errs++; n++; if ((n % 4096) == 0) { printf("reader: %ld reads, %ld errors, %lds\n", n, errs, (long)(time(NULL) - t0)); fflush(stdout); if (secs && time(NULL) - t0 > secs) break; } } printf("reader: finished %ld reads %ld errors\n", n, errs); return (0); } |