Пример #1
0
void do_syscall(struct syscallrecord *rec)
{
	struct syscallentry *entry;
	struct msg_syscallprep scmsg;
	struct childdata *child = this_child();
	unsigned int call;

	init_msgchildhdr(&scmsg.hdr, SYSCALL_PREP, pids[child->num], child->num);
	scmsg.sequence_nr = child->op_nr;
	scmsg.nr = rec->nr;
	scmsg.is32bit = rec->do32bit;
	scmsg.a1 = rec->a1;
	scmsg.a2 = rec->a2;
	scmsg.a3 = rec->a3;
	scmsg.a4 = rec->a4;
	scmsg.a5 = rec->a5;
	scmsg.a6 = rec->a6;
	rec->tp = scmsg.hdr.tp;
	sendudp((char *) &scmsg, sizeof(scmsg));

	call = rec->nr;
	entry = syscalls[call].entry;

	if (entry->flags & EXTRA_FORK)
		do_extrafork(rec);
	else
		 /* common-case, do the syscall in this child process. */
		__do_syscall(rec, BEFORE);

	/* timestamp again for when we returned */
	clock_gettime(CLOCK_MONOTONIC, &rec->tp);
}
Пример #2
0
/*
 * Return a pointer a previous mmap() that we did, either during startup,
 * or from a fuzz result.
 */
struct map * get_map(void)
{
	struct object *obj = NULL;
	struct childdata *child = this_child();
	bool global;
	enum objecttype type = 0;

	/*
	 * Some of the fd providers need weird mappings on startup.
	 * (fd-perf for eg), these are called from the main process,
	 * and hence don't have a valid this_child, so we address the
	 * initial mappings list directly.
	 */
	if (child == NULL)
		global = OBJ_GLOBAL;
	else
		global = OBJ_LOCAL;

	while (obj == NULL) {
		switch (rnd() % 3) {
		case 0:	type = OBJ_MMAP_ANON;
			break;
		case 1:	type = OBJ_MMAP_FILE;
			break;
		case 2:	type = OBJ_MMAP_TESTFILE;
			break;
		}

		obj = get_random_object(type, global);
	}

	return &obj->map;
}
Пример #3
0
static void sigxcpu_handler(__unused__ int sig)
{
	struct childdata *child = this_child();

	child->xcpu_count++;

	siglongjmp(ret_jump, 1);
}
Пример #4
0
FILE *find_logfile_handle(void)
{
	struct childdata *child;
	pid_t pid;

	pid = getpid();
	if (pid == mainpid)
		return mainlogfile;

	child = this_child();
	if (child != NULL)
		return child->logfile;

	return NULL;
}
Пример #5
0
/* used in several sanitise_* functions. */
struct map * common_set_mmap_ptr_len(void)
{
	struct syscallrecord *rec;
	struct map *map;
	struct childdata *child = this_child();

	rec = &child->syscall;
	map = (struct map *) rec->a1;
	if (map == NULL) {
		rec->a1 = 0;
		rec->a2 = 0;
		return NULL;
	}

	rec->a1 = (unsigned long) map->ptr;
	rec->a2 = rnd() % map->size;
	rec->a2 &= PAGE_MASK;

	return map;
}
Пример #6
0
/*
 * Flush any pending log writes to disk.
 * Only to be called from child context.
 */
void synclogs(void)
{
	struct childdata *child;
	int fd;

	child = this_child();
	if (child->logdirty == FALSE)
		return;

	fflush(child->logfile);
	fd = fileno(child->logfile);
	if (fd != -1)
		(void) fsync(fd);

	child->logdirty = FALSE;

	/* If we're flushing the child log, may as well flush
	 * any other logs while we're writing to disk.
	 */
	(void)fflush(mainlogfile);
	fsync(fileno(mainlogfile));
}
Пример #7
0
/*
 * Return a pointer a previous mmap() that we did, either during startup,
 * or from a fuzz result.
 */
struct map * get_map(void)
{
	struct object *obj;
	struct map *map;
	struct childdata *child = this_child();
	bool global;

	/*
	 * Some of the fd providers need weird mappings on startup.
	 * (fd-perf for eg), these are called from the main process,
	 * and hence don't have a valid this_child, so we address the
	 * initial mappings list directly.
	 */
	if (child == NULL)
		global = OBJ_GLOBAL;
	else
		global = OBJ_LOCAL;

	obj = get_random_object(OBJ_MMAP, global);
	map = &obj->map;

	return map;
}
Пример #8
0
/*
 * Set up a childs local mapping list.
 * A child inherits the initial mappings, and will add to them
 * when it successfully completes mmap() calls.
 */
void init_child_mappings(void)
{
	struct list_head *globallist, *node;
	struct objhead *head;
	struct childdata *child = this_child();

	init_object_lists(OBJ_LOCAL);

	head = &child->objects[OBJ_MMAP];
	head->destroy = &map_destructor;

	globallist = shm->global_objects[OBJ_MMAP].list;

	/* Copy the initial mapping list to the child.
	 * Note we're only copying pointers here, the actual mmaps
	 * will be faulted into the child when they get accessed.
	 */
	list_for_each(node, globallist) {
		struct map *m;
		struct object *globalobj, *newobj;

		globalobj = (struct object *) node;
		m = &globalobj->map;

		newobj = zmalloc(sizeof(struct object));
		newobj->map.ptr = m->ptr;
		newobj->map.name = strdup(m->name);
		newobj->map.size = m->size;
		newobj->map.prot = m->prot;
		/* We leave type as 'INITIAL' until we change the mapping
		 * by mprotect/mremap/munmap etc..
		 */
		newobj->map.type = TRINITY_MAP_INITIAL;
		add_object(newobj, OBJ_LOCAL, OBJ_MMAP);
	}
}
Пример #9
0
void handle_syscall_ret(struct syscallrecord *rec)
{
	struct syscallentry *entry;
	struct msg_syscallresult scmsg;
	struct childdata *child = this_child();
	unsigned int call;

	init_msgchildhdr(&scmsg.hdr, SYSCALL_RESULT, pids[child->num], child->num);
	scmsg.hdr.tp = rec->tp;
	scmsg.sequence_nr = child->op_nr;
	scmsg.retval = rec->retval;
	scmsg.errno_post = rec->errno_post;
	sendudp((char *) &scmsg, sizeof(scmsg));

	call = rec->nr;
	entry = syscalls[call].entry;

	if (rec->retval == -1UL) {
		int err = rec->errno_post;

		/* only check syscalls that completed. */
		//FIXME: how else would we get here?
		if (rec->state == AFTER) {
			if (err == ENOSYS)
				deactivate_enosys(rec, entry, call);

			entry->failures++;
			if (err < NR_ERRNOS) {
				entry->errnos[err]++;
			} else {
				// "These should never be seen by user programs."
				// But trinity isn't a 'normal' user program, we're doing
				// stuff that libc hides from apps.
				if (err < 512 || err > 530)
					printf("errno out of range after doing %s: %d:%s\n",
						entry->name,
						err, strerror(err));
			}
			shm->stats.failures++;
		}
	} else {
		handle_success(rec);	// Believe me folks, you'll never get bored with winning
		entry->successes++;
		shm->stats.successes++;
	}
	entry->attempted++;

	generic_post(entry->arg1type, rec->a1);
	generic_post(entry->arg2type, rec->a2);
	generic_post(entry->arg3type, rec->a3);
	generic_post(entry->arg4type, rec->a4);
	generic_post(entry->arg5type, rec->a5);
	generic_post(entry->arg6type, rec->a6);

	if (entry->post)
	    entry->post(rec);

	check_uid();

	generic_free_arg(rec);
}