int setup_syscall_group_biarch(unsigned int group) { unsigned int i; for_each_32bit_syscall(i) { if (syscalls_32bit[i].entry->group == group) toggle_syscall(syscalls_32bit[i].entry->name, TRUE); } if (shm->nr_active_32bit_syscalls == 0) outputstd("No 32-bit syscalls in group\n"); else outputstd("Found %d 32-bit syscalls in group\n", shm->nr_active_32bit_syscalls); /* now the 64 bit table*/ for_each_64bit_syscall(i) { if (syscalls_64bit[i].entry->group == group) toggle_syscall(syscalls_64bit[i].entry->name, TRUE); } if (shm->nr_active_64bit_syscalls == 0) { outputstd("No 64-bit syscalls in group\n"); return FALSE; } else { outputstd("Found %d 64-bit syscalls in group\n", shm->nr_active_64bit_syscalls); } return TRUE; }
void show_state(unsigned int state) { if (state) outputstd("Enabled"); else outputstd("Disabled"); }
void dump_syscall_tables_biarch(void) { struct syscallentry *entry; unsigned int i; outputstd("syscalls: %d [32-bit]\n", max_nr_32bit_syscalls); outputstd("syscalls: %d [64-bit]\n", max_nr_64bit_syscalls); for_each_32bit_syscall(i) { entry = syscalls_32bit[i].entry; outputstd("entrypoint %d %s : [32-bit] ", entry->number, entry->name); show_state(entry->flags & ACTIVE); if (entry->flags & AVOID_SYSCALL) outputstd(" AVOID"); outputstd("\n"); } for_each_64bit_syscall(i) { entry = syscalls_64bit[i].entry; outputstd("entrypoint %d %s : [64-bit] ", entry->number, entry->name); show_state(entry->flags & ACTIVE); if (entry->flags & AVOID_SYSCALL) outputstd(" AVOID"); outputstd("\n"); } }
void dump_syscall_tables_uniarch(void) { unsigned int i; outputstd("syscalls: %d\n", max_nr_syscalls); for_each_syscall(i) { outputstd("entrypoint %d %s : ", syscalls[i].entry->number, syscalls[i].entry->name); show_state(syscalls[i].entry->flags & ACTIVE); if (syscalls[i].entry->flags & AVOID_SYSCALL) outputstd(" AVOID"); outputstd("\n"); } }
const char * print_syscall_name(unsigned int callno, bool is32bit) { const struct syscalltable *table; unsigned int max; if (biarch == FALSE) { max = max_nr_syscalls; table = syscalls; } else { if (is32bit == FALSE) { max = max_nr_64bit_syscalls; table = syscalls_64bit; } else { max = max_nr_32bit_syscalls; table = syscalls_32bit; } } if (callno >= max) { outputstd("Bogus syscall number in %s (%u)\n", __func__, callno); return "invalid-syscall"; } return table[callno].entry->name; }
/* This is run *after* we've parsed params */ static int munge_tables(void) { unsigned int ret; /* By default, all syscall entries will be disabled. * If we didn't pass -c, -x or -r, mark all syscalls active. */ if ((do_specific_syscall == FALSE) && (do_exclude_syscall == FALSE) && (random_selection == FALSE) && (desired_group == GROUP_NONE)) mark_all_syscalls_active(); if (desired_group != GROUP_NONE) { ret = setup_syscall_group(desired_group); if (ret == FALSE) return FALSE; } if (random_selection == TRUE) enable_random_syscalls(); /* If we saw a '-x', set all syscalls to enabled, then selectively disable. * Unless we've started enabling them already (with -r) (or if we specified a group -g) */ if (do_exclude_syscall == TRUE) { if ((random_selection == FALSE) && (desired_group == GROUP_NONE)) mark_all_syscalls_active(); deactivate_disabled_syscalls(); } /* if we passed -n, make sure there's no VM/VFS syscalls enabled. */ if (no_files == TRUE) disable_non_net_syscalls(); sanity_check_tables(); count_syscalls_enabled(); if (verbose == TRUE) display_enabled_syscalls(); if (validate_syscall_tables() == FALSE) { outputstd("No syscalls were enabled!\n"); outputstd("Use 32bit:%d 64bit:%d\n", use_32bit, use_64bit); return FALSE; } return TRUE; }
int setup_syscall_group_uniarch(unsigned int group) { unsigned int i; for_each_syscall(i) { if (syscalls[i].entry->group == group) activate_syscall(i); } if (shm->nr_active_syscalls == 0) { outputstd("No syscalls found in group\n"); return FALSE; } else { outputstd("Found %d syscalls in group\n", shm->nr_active_syscalls); } return TRUE; }
void mark_all_syscalls_active(void) { outputstd("Marking all syscalls as enabled.\n"); if (biarch == TRUE) mark_all_syscalls_active_biarch(); else mark_all_syscalls_active_uniarch(); }
void dump_uids(void) { uid_t uid, euid, suid; gid_t gid, egid, sgid; getresuid(&uid, &euid, &suid); getresgid(&gid, &egid, &sgid); outputstd("initial uid:%u gid:%u euid:%u egid:%u suid:%u sgid:%u\n", uid, gid, euid, egid, suid, sgid); }
void do_uid0_check(void) { unsigned int i; /* if we're already unprivileged, then don't worry. */ if (orig_uid != 0) return; if (dangerous == TRUE) { outputstd("DANGER: RUNNING AS ROOT.\n"); outputstd("Unless you are running in a virtual machine, this could cause serious problems such as overwriting CMOS\n"); outputstd("or similar which could potentially make this machine unbootable without a firmware reset.\n"); outputstd("You might want to check out running with --dropprivs (currently experimental).\n\n"); } else { if (dropprivs == FALSE) { outputstd("Don't run as root (or pass --dangerous, or --dropprivs if you know what you are doing).\n"); exit(EXIT_FAILURE); } else { outputstd("--dropprivs is still in development, and really shouldn't be used unless you're helping development. Expect crashes.\n"); outputstd("Going to run as user nobody (uid:%d gid:%d)\n", nobody_uid, nobody_gid); } } if (clowntown == TRUE) { printf("THIS CLOWN GOES TO 11.\n"); return; } outputstd("ctrl-c now unless you really know what you are doing.\n"); for (i = 10; i > 0; i--) { outputstd("Continuing in %u seconds.\r", i); (void)fflush(stdout); sleep(1); } }
static void open_fds_from_path(const char *dirpath) { int before = files_in_index; /* old declaration int flags = FTW_DEPTH | FTW_ACTIONRETVAL | FTW_MOUNT; * android > 4.4 doesn't support FTW_ACTIONRETVAL anymore */ int flags = FTW_DEPTH | FTW_MOUNT; int ret; /* By default, don't follow symlinks so we only get each file once. * But, if we do something like -V /lib, then follow it * * I'm not sure about this, might remove later. */ if (victim_path == NULL) flags |= FTW_PHYS; if (victim_dev == NULL) { //run normally if no specific dev speficied ret = nftw(dirpath, file_tree_callback, 32, flags); if (ret != 0) { if (shm->exit_reason != EXIT_SIGINT) output(0, "Something went wrong during nftw(%s). (%d:%s)\n", dirpath, ret, strerror(errno)); return; } } else { //adding victim dev only! no recursion from file tree callback add_to_namelist(victim_dev); outputstd ("Adding only victim device: %s", victim_dev); files_in_index++; } output(0, "Added %d filenames from %s\n", files_in_index - before, dirpath); }
int main(int argc, char* argv[]) { int ret = EXIT_SUCCESS; int childstatus; pid_t pid; const char taskname[13]="trinity-main"; outputstd("Trinity " VERSION " Dave Jones <*****@*****.**>\n"); progname = argv[0]; initpid = getpid(); page_size = getpagesize(); num_online_cpus = sysconf(_SC_NPROCESSORS_ONLN); max_children = num_online_cpus; /* possibly overridden in params. */ if (init_random() == FALSE) exit(EXIT_FAILURE); set_seed(0); select_syscall_tables(); create_shm(); /* We do this before the parse_args because --fds will need to * operate on it when implemented. */ setup_fd_providers(); parse_args(argc, argv); init_uids(); change_tmp_dir(); init_logging(); init_shm(); kernel_taint_initial = check_tainted(); if (kernel_taint_initial != 0) output(0, "Kernel was tainted on startup. Will ignore flags that are already set.\n"); if (munge_tables() == FALSE) { ret = EXIT_FAILURE; goto out; } if (show_syscall_list == TRUE) { dump_syscall_tables(); goto out; } init_syscalls(); if (show_ioctl_list == TRUE) { dump_ioctls(); goto out; } do_uid0_check(); if (do_specific_domain == TRUE) find_specific_domain(specific_domain_optarg); setup_initial_mappings(); parse_devices(); pids_init(); setup_main_signals(); /* check if we ctrl'c or something went wrong during init. */ if (shm->exit_reason != STILL_RUNNING) goto cleanup_fds; init_watchdog(); /* do an extra fork so that the watchdog and the children don't share a common parent */ fflush(stdout); pid = fork(); if (pid == 0) { shm->mainpid = getpid(); setup_main_signals(); no_bind_to_cpu = RAND_BOOL(); output(0, "Main thread is alive.\n"); prctl(PR_SET_NAME, (unsigned long) &taskname); set_seed(0); 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_main_fail(); } if (dropprivs == TRUE) //FIXME: Push down into child processes later. drop_privs(); main_loop(); shm->mainpid = 0; _exit(EXIT_SUCCESS); } /* wait for main loop process to exit. */ (void)waitpid(pid, &childstatus, 0); /* wait for watchdog to exit. */ waitpid(watchdog_pid, &childstatus, 0); output(0, "Ran %ld syscalls. Successes: %ld Failures: %ld\n", shm->stats.total_syscalls_done - 1, shm->stats.successes, shm->stats.failures); cleanup_fds: close_sockets(); destroy_initial_mappings(); shutdown_logging(); ret = set_exit_code(shm->exit_reason); out: exit(ret); }
int main(int argc, char* argv[]) { int ret = EXIT_SUCCESS; int childstatus; unsigned int i; outputstd("Trinity v" __stringify(VERSION) " Dave Jones <*****@*****.**>\n"); progname = argv[0]; initpid = getpid(); page_size = getpagesize(); num_online_cpus = sysconf(_SC_NPROCESSORS_ONLN); select_syscall_tables(); if (create_shm()) exit(EXIT_FAILURE); parse_args(argc, argv); outputstd("Done parsing arguments.\n"); if (kernel_taint_mask != (int)0xFFFFFFFF) { outputstd("Custom kernel taint mask has been specified: 0x%08x (%d).\n", kernel_taint_mask, kernel_taint_mask); } if (user_specified_children != 0) max_children = user_specified_children; else max_children = sysconf(_SC_NPROCESSORS_ONLN); if (max_children > MAX_NR_CHILDREN) { outputerr("Increase MAX_NR_CHILDREN!\n"); exit(EXIT_FAILURE); } setup_shm_postargs(); if (logging == TRUE) open_logfiles(); if (munge_tables() == FALSE) { ret = EXIT_FAILURE; goto out; } if (show_syscall_list == TRUE) { dump_syscall_tables(); goto out; } init_syscalls(); if (show_ioctl_list == TRUE) { dump_ioctls(); goto out; } if (getuid() == 0) { if (dangerous == TRUE) { outputstd("DANGER: RUNNING AS ROOT.\n"); outputstd("Unless you are running in a virtual machine, this could cause serious problems such as overwriting CMOS\n"); outputstd("or similar which could potentially make this machine unbootable without a firmware reset.\n\n"); outputstd("ctrl-c now unless you really know what you are doing.\n"); for (i = 10; i > 0; i--) { outputstd("Continuing in %d seconds.\r", i); (void)fflush(stdout); sleep(1); } } else { outputstd("Don't run as root (or pass --dangerous if you know what you are doing).\n"); exit(EXIT_FAILURE); } } if (do_specific_proto == TRUE) find_specific_proto(specific_proto_optarg); init_buffers(); parse_devices(); pids_init(); setup_main_signals(); kernel_taint_initial = check_tainted(); if (kernel_taint_initial != 0) { output(0, "Kernel was tainted on startup. Will ignore flags that are already set.\n"); } change_tmp_dir(); /* check if we ctrl'c or something went wrong during init. */ if (shm->exit_reason != STILL_RUNNING) goto cleanup_fds; init_watchdog(); do_main_loop(); /* Shutting down. */ waitpid(watchdog_pid, &childstatus, 0); output(0, "\nRan %ld syscalls. Successes: %ld Failures: %ld\n", shm->total_syscalls_done - 1, shm->successes, shm->failures); ret = EXIT_SUCCESS; cleanup_fds: close_sockets(); destroy_global_mappings(); if (logging == TRUE) close_logfiles(); out: exit(ret); }
int main(int argc, char* argv[]) { int ret = EXIT_SUCCESS; const char taskname[13]="trinity-main"; outputstd("Trinity " VERSION " Dave Jones <*****@*****.**>\n"); progname = argv[0]; mainpid = getpid(); page_size = getpagesize(); num_online_cpus = sysconf(_SC_NPROCESSORS_ONLN); max_children = num_online_cpus; /* possibly overridden in params. */ if (init_random() == FALSE) exit(EXIT_FAILURE); select_syscall_tables(); create_shm(); /* We do this before the parse_args because --fds will need to * operate on the providers list when implemented. */ setup_fd_providers(); parse_args(argc, argv); init_uids(); change_tmp_dir(); init_logging(); init_shm(); kernel_taint_initial = check_tainted(); if (kernel_taint_initial != 0) output(0, "Kernel was tainted on startup. Will ignore flags that are already set.\n"); 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_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); } if (dropprivs == TRUE) //FIXME: Push down into child processes later. drop_privs(); main_loop(); destroy_global_objects(); output(0, "Ran %ld syscalls. Successes: %ld Failures: %ld\n", shm->stats.total_syscalls_done - 1, shm->stats.successes, shm->stats.failures); shutdown_logging(); ret = set_exit_code(shm->exit_reason); out: exit(ret); }
void parse_args(int argc, char *argv[]) { int opt; int opt_index = 0; while ((opt = getopt_long(argc, argv, paramstr, longopts, &opt_index)) != -1) { switch (opt) { default: if (opt == '?') exit(EXIT_FAILURE); else outputstd("opt:%c\n", opt); return; case 'b': init_bdev_list(); process_bdev_param(optarg); dump_bdev_list(); outputstd("--bdev doesn't do anything useful yet.\n"); exit(EXIT_SUCCESS); case 'c': /* syscalls are all disabled at this point. enable the syscall we care about. */ do_specific_syscall = TRUE; toggle_syscall(optarg, TRUE); break; case 'a': /* One of the architectures selected*/ do_32_arch = FALSE; do_64_arch = FALSE; if (strcmp(optarg, "64") == 0) { do_32_arch = FALSE; do_64_arch = TRUE; } else if (strcmp(optarg, "32") == 0) { do_32_arch = TRUE; do_64_arch = FALSE; } else { outputstd("can't parse %s\n", optarg); exit(EXIT_FAILURE); } break; case 'C': user_specified_children = strtoll(optarg, NULL, 10); max_children = user_specified_children; if (max_children == 0) { outputerr("zero children ? WAT?\n"); exit(EXIT_FAILURE); } break; case 'd': dangerous = TRUE; break; case 'D': set_debug = TRUE; break; case 'g': if (!strcmp(optarg, "vm")) desired_group = GROUP_VM; if (!strcmp(optarg, "vfs")) desired_group = GROUP_VFS; break; /* Show help */ case 'h': usage(); exit(EXIT_SUCCESS); case 'I': show_ioctl_list = TRUE; break; case 'l': if (!strcmp(optarg, "off")) logging = FALSE; break; case 'L': show_syscall_list = TRUE; break; case 'm': monochrome = TRUE; memset(&ANSI_RED, 0, 1); memset(&ANSI_GREEN, 0, 1); memset(&ANSI_YELLOW, 0, 1); memset(&ANSI_BLUE, 0, 1); memset(&ANSI_MAGENTA, 0, 1); memset(&ANSI_CYAN, 0, 1); memset(&ANSI_WHITE, 0, 1); memset(&ANSI_RESET, 0, 1); break; /* Set number of syscalls to do */ case 'N': syscalls_todo = strtoll(optarg, NULL, 10); break; /* Pause after each syscall */ case 'p': dopause = TRUE; break; case 'P': do_specific_domain = TRUE; specific_domain = strtol(optarg, NULL, 10); specific_domain_optarg = optarg; break; case 'E': parse_exclude_domains(optarg); break; case 'q': quiet_level++; break; case 'r': if (do_exclude_syscall == TRUE) { outputerr("-r needs to be before any -x options.\n"); exit(EXIT_FAILURE); } random_selection = TRUE; random_selection_num = strtol(optarg, NULL, 10); break; case 'R': if(fuzz_device_driver(optarg) == FALSE) { outputerr("Unable to open the device driver!\n"); exit(EXIT_FAILURE); } use_specific_dev_fd = TRUE; break; /* Set seed */ case 's': seed = strtol(optarg, NULL, 10); user_set_seed = TRUE; break; case 'S': do_syslog = TRUE; break; case 'T': //Load mask for kernel taint flags. process_taint_arg(optarg); if (kernel_taint_mask != 0xFFFFFFFF) outputstd("Custom kernel taint mask has been specified: 0x%08x (%d).\n", kernel_taint_mask, kernel_taint_mask); break; case 'v': verbose = TRUE; break; case 'V': if (victim_path == NULL) { victim_path = strdup(optarg); break; } else { outputstd("Sorry, only one victim path right now.\n"); exit(EXIT_FAILURE); } //FIXME: Later, allow for multiple victim files break; case 'x': do_exclude_syscall = TRUE; toggle_syscall(optarg, FALSE); break; case 'X': dropprivs = TRUE; break; case 0: /* * FIXME: It's really hard to find two reasonable short * names since S s P p all have been used. Use long * options before we fix this issue. */ if (strcmp("server_addr", longopts[opt_index].name) == 0) { unsigned int optarglen = strlen(optarg); unsigned int len = min((unsigned int)sizeof(server_addr), optarglen); strncpy(server_addr, optarg, len); } if (strcmp("server_port", longopts[opt_index].name) == 0) server_port = atoi(optarg); if (strcmp("disable-fds", longopts[opt_index].name) == 0) process_fds_param(optarg, FALSE); if (strcmp("enable-fds", longopts[opt_index].name) == 0) process_fds_param(optarg, TRUE); break; } } if (quiet_level > MAX_LOGLEVEL) quiet_level = MAX_LOGLEVEL; quiet_level = MAX_LOGLEVEL - quiet_level; output(1, "Done parsing arguments.\n"); }
void parse_args(int argc, char *argv[]) { int opt; while ((opt = getopt_long(argc, argv, paramstr, longopts, NULL)) != -1) { switch (opt) { default: if (opt == '?') exit(EXIT_FAILURE); else outputstd("opt:%c\n", opt); return; case '\0': return; case 'c': /* syscalls are all disabled at this point. enable the syscall we care about. */ do_specific_syscall = TRUE; toggle_syscall(optarg, TRUE); break; case 'a': /* One of the architectures selected*/ do_32_arch = FALSE; do_64_arch = FALSE; if (strcmp(optarg, "64") == 0) { do_32_arch = FALSE; do_64_arch = TRUE; } else if (strcmp(optarg, "32") == 0) { do_32_arch = TRUE; do_64_arch = FALSE; } else { outputstd("can't parse %s\n", optarg); exit(EXIT_FAILURE); } break; case 'C': user_specified_children = strtoll(optarg, NULL, 10); max_children = user_specified_children; if (max_children == 0) { outputerr("zero children ? WAT?\n"); exit(EXIT_FAILURE); } break; case 'd': dangerous = TRUE; break; case 'D': debug = TRUE; break; case 'g': if (!strcmp(optarg, "vm")) desired_group = GROUP_VM; if (!strcmp(optarg, "vfs")) desired_group = GROUP_VFS; break; /* Show help */ case 'h': usage(); exit(EXIT_SUCCESS); case 'I': show_ioctl_list = TRUE; break; case 'l': if (!strcmp(optarg, "off")) logging = FALSE; break; case 'L': show_syscall_list = TRUE; break; case 'm': monochrome = TRUE; memset(&ANSI_RED, 0, 1); memset(&ANSI_GREEN, 0, 1); memset(&ANSI_YELLOW, 0, 1); memset(&ANSI_BLUE, 0, 1); memset(&ANSI_MAGENTA, 0, 1); memset(&ANSI_CYAN, 0, 1); memset(&ANSI_WHITE, 0, 1); memset(&ANSI_RESET, 0, 1); break; case 'n': no_files = TRUE; break; /* Set number of syscalls to do */ case 'N': syscalls_todo = strtoll(optarg, NULL, 10); break; /* Pause after each syscall */ case 'p': dopause = TRUE; break; case 'P': do_specific_proto = TRUE; specific_proto = strtol(optarg, NULL, 10); specific_proto_optarg = optarg; break; case 'E': parse_exclude_protos(optarg); break; case 'q': quiet_level++; break; case 'r': if (do_exclude_syscall == TRUE) { outputerr("-r needs to be before any -x options.\n"); exit(EXIT_FAILURE); } random_selection = TRUE; random_selection_num = strtol(optarg, NULL, 10); break; /* Set seed */ case 's': seed = strtol(optarg, NULL, 10); user_set_seed = TRUE; break; case 'S': do_syslog = TRUE; break; case 'T': //Load mask for kernel taint flags. process_taint_arg(optarg); if (kernel_taint_mask != 0xFFFFFFFF) outputstd("Custom kernel taint mask has been specified: 0x%08x (%d).\n", kernel_taint_mask, kernel_taint_mask); break; case 'v': verbose = TRUE; break; case 'V': if (victim_path == NULL) { victim_path = strdup(optarg); break; } else { outputstd("Sorry, only one victim path right now.\n"); exit(EXIT_FAILURE); } //FIXME: Later, allow for multiple victim files break; case 'x': do_exclude_syscall = TRUE; toggle_syscall(optarg, FALSE); break; case 'X': dropprivs = TRUE; break; } } if (quiet_level > MAX_LOGLEVEL) quiet_level = MAX_LOGLEVEL; quiet_level = MAX_LOGLEVEL - quiet_level; output(1, "Done parsing arguments.\n"); }