⬢ DragonFlyBSD Kernel Audit
DF-5773 / storm_demo_fixed.c
← back to finding ↓ download raw
/* storm_demo with the DF-5773 fix (init.c handle_term guard) applied */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/wait.h>

#define EX_VKERNEL_REBOOT 32

static pid_t childpid;

static void handle_term(int sig)
{
	/* FIXED: only the monitor (childpid > 0) may forward */
	if (childpid > 0)
		kill(childpid, sig);
}

static void pause_ms(int sec)
{
	struct timespec ts = { sec, 0 };
	nanosleep(&ts, NULL);
}

int
main(int ac, char **av)
{
	struct sigaction sa;
	int window = ac > 1 ? atoi(av[1]) : 5;
	int status;

	while ((childpid = fork()) != 0) {
		memset(&sa, 0, sizeof(sa));
		sigemptyset(&sa.sa_mask);
		sa.sa_handler = SIG_IGN;
		sigaction(SIGINT, &sa, NULL);
		sigaction(SIGQUIT, &sa, NULL);
		sigaction(SIGHUP, &sa, NULL);

		sa.sa_handler = handle_term;
		sigaction(SIGTERM, &sa, NULL);

		while (waitpid(childpid, &status, 0) != childpid) {
		}
		if (WEXITSTATUS(status) != EX_VKERNEL_REBOOT)
			return 0;
	}

	pause_ms(window);
	_exit(EX_VKERNEL_REBOOT);
	return 0;
}