Esempio n. 1
0
void main_loop()
{
	regenerate();
	if (do_specific_syscall == 1)
		regenerate_random_page();

	while (1) {
		fork_children();
		handle_children();

		/* Only check taint if it was zero on startup */
		if (do_check_tainted == 0) {
			if (check_tainted() != 0) {
				output("kernel became tainted!\n");
				exit(EXIT_FAILURE);
			}
		}

		if (syscallcount && (shm->execcount >= syscallcount))
			exit(EXIT_SUCCESS);

		if (shm->execcount % 1000 == 0)
			synclogs();
	}
}
Esempio n. 2
0
bool child_random_syscalls(void)
{
	struct syscallrecord *rec;
	unsigned int syscallnr;
	bool do32;
	unsigned int len;

retry:
	if (no_syscalls_enabled() == TRUE) {
		output(0, "[%d] No more syscalls enabled. Exiting\n", getpid());
		shm->exit_reason = EXIT_NO_SYSCALLS_ENABLED;
		return FAIL;
	}

	/* Ok, we're doing another syscall, let's pick one. */
	do32 = choose_syscall_table();
	syscallnr = rand() % max_nr_syscalls;

	/* If we got a syscallnr which is not active repeat the attempt,
	 * since another child has switched that syscall off already.*/
	if (active_syscalls[syscallnr] == 0)
		goto retry;

	syscallnr = active_syscalls[syscallnr] - 1;

	if (validate_specific_syscall_silent(syscalls, syscallnr) == FALSE) {
		deactivate_syscall(syscallnr, do32);
		goto retry;
	}

	rec = &this_child->syscall;
	/* critical section for shm updates. */
	lock(&rec->lock);
	rec->do32bit = do32;
	rec->nr = syscallnr;
	unlock(&rec->lock);

	if (syscalls_todo) {
		if (shm->stats.total_syscalls_done >= syscalls_todo)
			shm->exit_reason = EXIT_REACHED_COUNT;
	}

	/* Generate arguments, print them out */

	generate_syscall_args(rec);
	output_syscall_prefix(rec);

	/* Sanity check: Make sure the length of the buffer remains
	 * constant across the syscall.
	 */
	len = strlen(rec->prebuffer);

	/* If we're going to pause, might as well sync pre-syscall */
	if (dopause == TRUE)
		synclogs();

	do_syscall(rec);

	/* post syscall sanity checks. */
	if (len != strlen(rec->prebuffer)) {
		output(0, "Sanity check failed: prebuffer length changed from %d to %d.\n",
			len, strlen(rec->prebuffer));
	}

	/* Output the syscall result, and clean up */
	output_syscall_postfix(rec);

	if (dopause == TRUE)
		sleep(1);

	handle_syscall_ret(rec);

	return TRUE;
}
Esempio n. 3
0
static void watchdog(void)
{
	static const char watchdogname[17]="trinity-watchdog";
	static unsigned long lastcount = 0;
	bool watchdog_exit = FALSE;
	int ret = 0;

	while (shm->ready == FALSE) {
		sleep(1);
		if (shm->exit_reason != STILL_RUNNING)
			return;
	}

	output(0, "Watchdog is alive. (pid:%d)\n", watchdog_pid);

	prctl(PR_SET_NAME, (unsigned long) &watchdogname);
	(void)signal(SIGSEGV, SIG_DFL);

	while (watchdog_exit == FALSE) {

		if (check_shm_sanity() == SHM_CORRUPT)
			goto corrupt;

		if (check_main_alive() == FALSE)
			goto main_dead;

		if (shm->regenerating == FALSE) {
			unsigned int i;

			reap_dead_kids();

			check_children();

			if (syscalls_todo && (shm->total_syscalls_done >= syscalls_todo)) {
				output(0, "Reached limit %d. Telling children to exit.\n", syscalls_todo);
				shm->exit_reason = EXIT_REACHED_COUNT;
			}

			// Periodic log syncing. FIXME: This is kinda ugly, and mostly unnecessary.
			if (shm->total_syscalls_done % 1000 == 0)
				synclogs();

			for_each_pidslot(i) {
				if (shm->child_syscall_count[i] > hiscore)
					hiscore = shm->child_syscall_count[i];
			}

			if (shm->total_syscalls_done > 1) {
				if (shm->total_syscalls_done - lastcount > 10000) {
					output(0, "%ld iterations. [F:%ld S:%ld HI:%ld]\n",
						shm->total_syscalls_done,
						shm->failures, shm->successes,
						hiscore);
					lastcount = shm->total_syscalls_done;
				}
			}

		}

		/* Only check taint if it mask allows it */
		if (kernel_taint_mask != 0) {
			ret = check_tainted();
			if (((ret & kernel_taint_mask) & (~kernel_taint_initial)) != 0) {
				gettimeofday(&shm->taint_tv, NULL);

				output(0, "kernel became tainted! (%d/%d) Last seed was %u\n", ret, kernel_taint_initial, shm->seed);
				shm->exit_reason = EXIT_KERNEL_TAINTED;
			}
		}

main_dead:
		/* Are we done ? */
		if (shm->exit_reason != STILL_RUNNING) {
			/* Give children a chance to exit. */
			sleep(1);

			/* Are there still children running ? */
			if (pidmap_empty() == TRUE)
				watchdog_exit = TRUE;
			else {
				output(0, "exit_reason=%d, but %d children still running.\n",
					shm->exit_reason, shm->running_childs);
				kill_all_kids();
			}
		}

		sleep(1);
	}