Exemplo n.º 1
0
static void choose_syscall_table(int childno)
{
    if (biarch == FALSE) {
        active_syscalls = shm->active_syscalls;
        nr_active_syscalls = shm->nr_active_syscalls;
    } else {

        /* First, check that we have syscalls enabled in either table. */
        if (validate_syscall_table_64() == FALSE) {
            use_64bit = FALSE;
            /* If no 64bit syscalls enabled, force 32bit. */
            shm->do32bit[childno] = TRUE;
        }

        if (validate_syscall_table_32() == FALSE)
            use_32bit = FALSE;

        /* If both tables enabled, pick randomly. */
        if ((use_64bit == TRUE) && (use_32bit == TRUE)) {
            /*
             * 10% possibility of a 32bit syscall
             */
            shm->do32bit[childno] = FALSE;

            if (rand() % 100 < 10)
                shm->do32bit[childno] = TRUE;
        }

        if (shm->do32bit[childno] == FALSE) {
            syscalls = syscalls_64bit;
            nr_active_syscalls = shm->nr_active_64bit_syscalls;
            active_syscalls = shm->active_syscalls64;
            max_nr_syscalls = max_nr_64bit_syscalls;
        } else {
            syscalls = syscalls_32bit;
            nr_active_syscalls = shm->nr_active_32bit_syscalls;
            active_syscalls = shm->active_syscalls32;
            max_nr_syscalls = max_nr_32bit_syscalls;
        }
    }

    if (no_syscalls_enabled() == TRUE) {
        output(0, "[%d] No more syscalls enabled. Exiting\n", getpid());
        shm->exit_reason = EXIT_NO_SYSCALLS_ENABLED;
    }
}
Exemplo 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;
}