关于工具trinity:syscall测试

git地址:
https://github.com/kernelslacker/trinity

linux下对syscall的模糊测试。

main函数位于trinity.c中。

int main(int argc, char* argv[])
{
	int ret = EXIT_SUCCESS;
	const char taskname[16]="test-main";

	outputstd("Trinity " VERSION "  Dave Jones <davej@codemonkey.org.uk>\n");

	progname = argv[0];

	mainpid = getpid();

	getrlimit(RLIMIT_NOFILE, &max_files_rlimit); //获取或设定资源使用限制
	// eg.RLIMIT_NOFILE进程能打开的最大文件数

	page_size = getpagesize();
	num_online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
	max_children = num_online_cpus * 4;	/* possibly overridden in params. -C可配置*/

	select_syscall_tables(); //根据系统架构选择系统调用表eg.syscalls-x86_64.h

	create_shm();//创建共享内存

	parse_args(argc, argv);//对传入的参数解析

	init_uids();//当前进程的uid,gid以及nobody用户的信息

	change_tmp_dir();

	init_shm();//用于查看每个子进程的syscall records

	init_taint_checking();//'/proc/sys/kernel/tainted'内核是否被污染
	if (munge_tables() == FALSE) {
		ret = EXIT_FAILURE;
		goto out;
	}

	if (show_syscall_list == TRUE) {
		dump_syscall_tables();
		goto out;
	}

	if (show_ioctl_list == TRUE) {
		dump_ioctls();
		goto out;
	}

	if (show_unannotated == TRUE) {
		show_unannotated_args();
		goto out;
	}

	init_syscalls();

	do_uid0_check();

	if (do_specific_domain == TRUE)
		find_specific_domain(specific_domain_optarg);

	pids_init();

	init_logging();

	init_object_lists(OBJ_GLOBAL);

	setup_initial_mappings();

	parse_devices();

	/* FIXME: Some better object construction method needed. */
	create_futexes();
	create_sysv_shms();


	setup_main_signals();

	no_bind_to_cpu = RAND_BOOL();

	prctl(PR_SET_NAME, (unsigned long) &taskname);

	if (open_fds() == FALSE) {
		if (shm->exit_reason != STILL_RUNNING)
			panic(EXIT_FD_INIT_FAILURE);	// FIXME: Later, push this down to multiple EXIT's.

		_exit(EXIT_FAILURE);
	}

	setup_ftrace();

	main_loop();

	destroy_global_objects();

	if (is_tainted() == TRUE)
		stop_ftrace();

	output(0, "Ran %ld syscalls. Successes: %ld  Failures: %ld\n",
		shm->stats.op_count, shm->stats.successes, shm->stats.failures);
	if (show_stats == TRUE)
		dump_stats();

	shutdown_logging();

	ret = set_exit_code(shm->exit_reason);
out:

	exit(ret);
}

trinity通过spawn_child产生子进程去执行系统调用。子进程内调用child_process,其中random_syscall即随机匹配系统调用去执行。

	// spawn_child中代码段
	
	pid = fork();

	if (pid == 0) {
		child_process(child, childno);
		_exit(EXIT_SUCCESS);
	} else {
		if (pid == -1) {
			debugf("Couldn't fork a new child in pidslot %d. errno:%s\n",
					childno, strerror(errno));
			return FALSE;
		}
	}

random_syscall函数中,set_syscall_nr随机系统调用号

syscallnr = rnd() % max_nr_syscalls;
bool random_syscall(struct childdata *child)
{
	struct syscallrecord *rec;
	int ret = FALSE;

	rec = &child->syscall;

	if (set_syscall_nr(rec) == FAIL)
		return FAIL;

	memset(rec->postbuffer, 0, POSTBUFFER_LEN);

	/* Generate arguments, print them out */
	generate_syscall_args(rec);

	output_syscall_prefix(rec);

	do_syscall(rec);

	output_syscall_postfix(rec);

	handle_syscall_ret(rec);

	ret = TRUE;

	return ret;
}

系统调用的参数随机生成

syscalltrinity/include/syscalls-x86_64.h该文件中存在struct syscalltable结构体数组,每一个元素都是一个系统调用。

struct syscalltable {
	struct syscallentry *entry;
};

syscalltrinity/syscalls/文件夹下,对于每个系统调用,实现了对应的结构体。

eg. syscall_poll

struct syscallentry syscall_poll = {
	.name = "poll",
	.num_args = 3,
	.arg1name = "ufds",
	.arg2name = "nfds",
	.arg3name = "timeout_msecs",
	.arg3type = ARG_RANGE,
	.low3range = 0,
	.hi3range = 1,
	.flags = NEED_ALARM,
	.sanitise = sanitise_poll,
	.post = post_poll,
};
//函数sanitise_poll即为poll对应的参数调整函数
static void sanitise_poll(struct syscallrecord *rec)
{
	struct pollfd *pollfd;
	unsigned int i;
	unsigned int num_fds = rnd() % 10;

	pollfd = zmalloc(num_fds * sizeof(struct pollfd));

	for (i = 0; i < num_fds; i++) {
		pollfd[i].fd = get_random_fd();
		pollfd[i].events = set_rand_bitmask(ARRAY_SIZE(poll_events), poll_events);
	}

	rec->a1 = (unsigned long) pollfd;
	rec->a2 = num_fds;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值