task_t* create_process(char* name, uint32_t eip, bool wants_stack) { Deprecated(); task_t* parent = current_task; //clone address space page_directory_t* cloned = vmm_clone_active_pdir(); //create new process task_t* task = kmalloc(sizeof(task_t)); memset(task, 0, sizeof(task_t)); task->name = strdup(name); task->id = next_pid++; task->page_dir = cloned; task->child_tasks = array_m_create(32); //task->kernel_stack = kmalloc_a(KERNEL_STACK_SIZE); setup_fds(task); uint32_t current_eip = read_eip(); if (current_task == parent) { task->eip = current_eip; return task; } task->state = RUNNABLE; task->wake_timestamp = 0; task->vmem_slide = 0; task->windows = array_m_create(16); return task; }
/* ------------------------------------------------------------- ** ** Central select bit. Deals with data connection ** forwarding/listening, and quits on ctrl connection close. Once ** there is a complete line read from one of the control connctions ** specified in "which" (GET_SRVR, GET_CTRL, or GET_SRVR|GET_CTRL) we ** return. ** ** The line read into the control connection buffer on function return ** contains a newline (\n), and is NULL terminated at some point ** beyond that. No other checking has been done on it. ** ** Return value is one of GET_SRVR, GET_CTRL or GET_SRVR|GET_CTRL. ** ------------------------------------------------------------- */ int get_control_line(int which) { int ret = 0, i; fd_set reads, writes; do { i = setup_fds(&reads, &writes); alarm(config.timeout); if(select(i + 1, &reads, &writes, NULL, NULL) == -1) { if(errno == EINTR) continue; debug_perr("select"); die(0, NULL, 0, NULL, -1); } do_dataforward(&reads, &writes); if(FD_ISSET(info->client_control.fd, &reads)) { i = sstr_append_read(info->client_control.fd, info->client_control.buf, 0); if(i == 0) die(INFO, "Client closed connection", 0, NULL, 0); if(i < 0) die(ATTACK, "Client flooding control connection", 421, "You're sending rubbish. Goodbye", -1); if(sstr_hasline(info->client_control.buf)) ret |= GET_CLNT; } if(info->server_control.fd != -1 && FD_ISSET(info->server_control.fd, &reads)) { i = read_srvrctrl_data(); if(i == 0) { if(!cache_transferring()) die(ERROR, "Server closed the control connection", 0, NULL, 0); else { rclose(&info->server_control.fd); write_log(INFO, "Server closed connection. Keeping going until cache done"); } } if(i < 0) die(ATTACK, "Server flooding the control connection", 421, "Server is sending rubbish." "Closing connection", -1); if(sstr_hasline(info->server_control.buf)) ret |= GET_SRVR; } } while(!(ret & which)); return (ret); }
value ml_merlin_context_setup(value context) { CAMLparam1(context); setup_fds( Int_val(Field(context, 1)), Int_val(Field(context, 2)), Int_val(Field(context, 3)) ); CAMLreturn(Val_unit); }
value ml_merlin_context_close(value context, value return_code) { CAMLparam1(context); setup_fds(-1, -1, -1); char code = (char)(Int_val(return_code)); ssize_t wrote_ = -1; NO_EINTR(wrote_, write(Int_val(Field(context, 0)), &code, sizeof(char))); // Close stdin, stdout, stderr close(Int_val(Field(context, 1))); close(Int_val(Field(context, 2))); close(Int_val(Field(context, 3))); // Close client connection close(Int_val(Field(context, 0))); CAMLreturn(Val_unit); }
int main(int argc, char* argv[]) { int ret; unsigned int i; printf("Trinity v" __stringify(VERSION) " Dave Jones <*****@*****.**> 2012\n"); #ifdef __x86_64__ syscalls = syscalls_x86_64; max_nr_syscalls = NR_X86_64_SYSCALLS; #elif __i386__ syscalls = syscalls_i386; max_nr_syscalls = NR_I386_SYSCALLS; #elif __powerpc__ syscalls = syscalls_ppc; #elif __ia64__ syscalls = syscalls_ia64; #elif __sparc__ syscalls = syscalls_sparc; #else syscalls = syscalls_i386; #endif progname = argv[0]; parse_args(argc, argv); if (getuid() == 0) { if (dangerous == 1) { printf("DANGER: RUNNING AS ROOT.\n"); printf("Unless you are running in a virtual machine, this could cause serious problems such as overwriting CMOS\n"); printf("or similar which could potentially make this machine unbootable without a firmware reset.\n\n"); printf("ctrl-c now unless you really know what you are doing.\n"); for (i = 10; i > 0; i--) { printf("Continuing in %d seconds.\r", i); (void)fflush(stdout); sleep(1); } } else { printf("Don't run as root (or pass --dangerous if you know what you are doing).\n"); exit(EXIT_FAILURE); } } if (create_shm()) exit(EXIT_FAILURE); if (logging != 0) open_logfiles(); max_nr_syscalls = NR_SYSCALLS; for (i = 0; i < max_nr_syscalls; i++) syscalls[i].entry->number = i; if (desired_group == GROUP_VM) { struct syscalltable *newsyscalls; int count = 0, j = 0; for (i = 0; i < max_nr_syscalls; i++) { if (syscalls[i].entry->group == GROUP_VM) count++; } newsyscalls = malloc(count * sizeof(struct syscalltable)); if (newsyscalls == NULL) exit(EXIT_FAILURE); for (i = 0; i < max_nr_syscalls; i++) { if (syscalls[i].entry->group == GROUP_VM) newsyscalls[j++].entry = syscalls[i].entry; } max_nr_syscalls = count; syscalls = newsyscalls; } if (!do_specific_syscall) output("Fuzzing %d syscalls.\n", max_nr_syscalls); if (do_specific_syscall == 1) find_specific_syscall(); if (do_specific_proto == 1) find_specific_proto(); if (show_syscall_list == 1) { syscall_list(); exit(EXIT_SUCCESS); } page_size = getpagesize(); if (!seed) seed_from_tod(); else output("[%d] Random seed: %u (0x%x)\n", getpid(), seed, seed); init_buffers(); mask_signals(); setup_fds(); if (check_tainted() != 0) { output("Kernel was tainted on startup. Will keep running if trinity causes an oops.\n"); do_check_tainted = 1; } /* just in case we're not using the test.sh harness. */ chmod("tmp/", 0755); ret = chdir("tmp/"); if (!ret) { /* nothing right now */ } main_loop(); printf("\nRan %ld syscalls (%ld retries). Successes: %ld Failures: %ld\n", shm->execcount - 1, shm->retries, shm->successes, shm->failures); shmdt(shm); destroy_maps(); for (i = 0; i < socks; i++) close(socket_fds[i]); if (logging != 0) close_logfiles(); exit(EXIT_SUCCESS); }
void read_write( int fd ) { fd_set fds; char buf[BUFSIZE]; int cc, infd = 0, outfd = 1; M_INT64 total_bytes; time_t start_time, last_time, time_now; int total_1s; int total_5s; int each_sec[5]; int each_ind; FD_ZERO(&fds); if ( ISSET(OPT_FLOOD) ) { /* if you want to test a link that compresses data, like PPP with built-in libz support, send random data, since it doesn't compress well. */ for ( cc = 0; cc < BUFSIZE; cc++ ) buf[cc] = random() & 0xff; outfd = fd; } last_time = time_now = time( &start_time ); total_bytes = 0; total_1s = 0; total_5s = 0; each_sec[0] = 0; each_sec[1] = 0; each_sec[2] = 0; each_sec[3] = 0; each_sec[4] = 0; each_ind = 0; while (1) { if ( !ISSET(OPT_FLOOD) ) { #define setup_fds() do { \ FD_ZERO( &fds ); \ if ( !ISSET(OPT_NOSTDIN)) \ FD_SET( 0, &fds ); \ FD_SET( fd, &fds ); } while(0) setup_fds(); cc = select( fd+1, &fds, NULL, NULL, NULL ); if (FD_ISSET(0, &fds)) { infd = 0; outfd = fd; } else { infd = fd; outfd = 1; } if (infd == fd && ISSET(OPT_PINGACK)) { int in_size, temp_cc; cc = read(infd, &in_size, 4); if (cc == 4) { cc = 0; in_size = ntohl(in_size); while (cc < in_size) { temp_cc = read(infd, buf+cc, in_size-cc); cc += temp_cc; } write(fd,buf,1); } else { cc = 0; } } else { cc = read(infd, buf, BUFSIZE); } } else { cc = BUFSIZE; } if (ISSET(OPT_RAWQ) && (buf[0] == 3)) { printf( "\n" ); break; } total_bytes += cc; total_1s += cc; if (ISSET(OPT_VERBOSE) && time(&time_now) != last_time) { char rate[30]; total_5s -= each_sec[each_ind]; each_sec[each_ind] = total_1s; total_1s = 0; total_5s += each_sec[each_ind]; each_ind = (each_ind+1)%5; last_time = time_now; strcpy( rate, m_dump_number( total_bytes / (time_now-start_time), 10 )); if ( (time_now-start_time) < 5 ) fprintf( stderr, " %s bytes in %d seconds (%s bps) \r", m_dump_number( total_bytes, 10 ), time_now-start_time, rate ); else fprintf( stderr, " %s bytes in %d seconds (%s bps) " "(5s avg %d bps) \r", m_dump_number( total_bytes, 10 ), time_now-start_time, rate, total_5s / 5 ); } if (cc > 0) { if (ISSET(OPT_RAWQ) && (infd == 0)) { int x; for (x = 0; x < cc; x++) if (buf[x] == 10) buf[x] = 13; } if (outfd == fd && ISSET(OPT_PINGACK)) { int outsize; outsize = htonl(cc); write(fd, &outsize, 4); } if ( ISSET(OPT_DELNULS)) { int a,b; char outbuf[ BUFSIZE ]; for ( a = b = 0; a < cc; a++ ) if ( buf[a] != 0 && buf[a] != 13 ) outbuf[b++] = buf[a]; write( outfd, outbuf, b ); } else { write(outfd, buf, cc); } if (ISSET(OPT_ECHO)) dumphex(infd, buf, cc); if (outfd == fd && ISSET(OPT_PINGACK)) { read(fd, buf, 1); } } else { break; } } if (ISSET(OPT_VERBOSE)) fprintf( stderr, "\n" ); if (ISSET(OPT_VERBOSE) || ISSET(OPT_STAT)) { char rate[30]; /* avoid a divide-by-zero if the transfer takes less than a second. */ if (time(&time_now) == start_time) time_now++; strcpy( rate, m_dump_number( total_bytes / (time_now-start_time), 10 )); fprintf( stderr, " %s bytes in %d seconds (%s bps) \n", m_dump_number( total_bytes, 10 ), time_now-start_time, rate ); } close(fd); }
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. */ set_seed(0); select_syscall_tables(); create_shm(); parse_args(argc, argv); init_uids(); change_tmp_dir(); if (logging == TRUE) open_main_logfile(); 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_proto == TRUE) find_specific_proto(specific_proto_optarg); setup_shared_mappings(); init_page_rand(); 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(); output(0, "Main thread is alive.\n"); prctl(PR_SET_NAME, (unsigned long) &taskname); set_seed(0); if (setup_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_shared_mappings(); if (logging == TRUE) close_logfile(&mainlogfile); out: exit(ret); }
static ct_process_t __local_enter_cb(ct_handler_t h, ct_process_desc_t ph, int (*cb)(void *), void *arg, bool is_exec) { struct container *ct = cth2ct(h); struct process_desc *p = prh2pr(ph); struct process *pr; int aux = -1, pid; int wait_pipe[2]; if (ct->state != CT_RUNNING) return ERR_PTR(-LCTERR_BADCTSTATE); if (ct->nsmask & CLONE_NEWPID) { if (switch_ns(ct->p.pid, &pid_ns, &aux)) return ERR_PTR(-LCTERR_INVARG); } pr = xmalloc(sizeof(struct process)); if (pr == NULL) return ERR_PTR(-1); local_process_init(pr); if (pipe(wait_pipe)) { xfree(pr); return ERR_PTR(-1); } pid = fork(); if (pid == 0) { struct ns_desc *ns; close(wait_pipe[0]); if (p->fds) { p->fds[p->fdn] = wait_pipe[1]; if (setup_fds(p->fds, p->fdn + 1)) exit(-1); wait_pipe[1] = p->fdn; } for (aux = 0; namespaces[aux]; aux++) { ns = namespaces[aux]; if (ns->cflag == CLONE_NEWPID) continue; if (!(ns->cflag & ct->nsmask)) continue; if (switch_ns(ct->p.pid, ns, NULL)) exit(-1); } if (cgroups_attach(ct)) exit(-1); if (ct->root_path && !(ct->nsmask & CLONE_NEWNS)) { char nroot[128]; /* * Otherwise switched by setns() */ snprintf(nroot, sizeof(nroot), "/proc/%d/root", ct->p.pid); if (set_current_root(nroot)) exit(-1); } if (apply_creds(p)) exit(-1); if (is_exec) spawn_wake_and_cloexec(wait_pipe, 0); else spawn_wake_and_close(wait_pipe, 0); aux = cb(arg); if (is_exec) spawn_wake_and_close(wait_pipe, -1); exit(aux); } close(wait_pipe[1]); if (aux >= 0) restore_ns(aux, &pid_ns); if (spawn_wait(wait_pipe)) goto err; if (spawn_wait_and_close(wait_pipe) != INT_MIN) goto err; pr->pid = pid; return &pr->h; err: xfree(pr); close(wait_pipe[0]); waitpid(pid, NULL, 0); return ERR_PTR(-1); }
static int ct_clone(void *arg) { int ret = -1; struct ct_clone_arg *ca = arg; struct container *ct = ca->ct; struct process_desc *p = ca->p; close(ca->child_wait_pipe[1]); close(ca->parent_wait_pipe[0]); ret = spawn_wait_and_close(ca->child_wait_pipe); if (ret) goto err_um; if (ct->nsmask & CLONE_NEWUSER) { if (setuid(0) || setgid(0) || setgroups(0, NULL)) goto err; } if (prctl(PR_SET_PDEATHSIG, p->pdeathsig)) goto err; if (!(ct->flags & CT_NOSETSID) && setsid() == -1) goto err; if (ct->tty_fd >= 0 && ioctl(ct->tty_fd, TIOCSCTTY, 0) == -1) goto err; if (p->fds) { p->fds[p->fdn] = ca->parent_wait_pipe[1]; if (setup_fds(p->fds, p->fdn + 1)) goto err; ca->parent_wait_pipe[1] = p->fdn; } if (ct->nsmask & CLONE_NEWNS) { /* * Remount / as slave, so that it doesn't * propagate its changes to our container. */ ret = -LCTERR_CANTMOUNT; if (mount("none", "/", "none", MS_SLAVE|MS_REC, NULL)) goto err; } if (try_mount_cg(ct)) goto err; ret = cgroups_attach(ct); if (ret < 0) goto err_um; if (ct->root_path) { /* * Mount external in child, since it may live * in sub mount namespace. If it doesn't do * it here anyway, just umount by hands in the * fs_umount(). */ ret = fs_mount_ext(ct); if (ret < 0) goto err; ret = set_ct_root(ct); if (ret < 0) goto err_um; ret = fs_create_devnodes(ct); if (ret < 0) goto err; } ret = uname_set(ct); if (ret < 0) goto err_um; ret = try_mount_proc(ct); if (ret < 0) goto err_um; ret = apply_creds(p); if (ret < 0) goto err_um; if (p->lsm_label) ret = lsm_process_label_set(p->lsm_label, false, p->lsm_on_exec); p->lsm_on_exec = 0; if (ret < 0) goto err; if (ca->is_exec) spawn_wake_and_cloexec(ca->parent_wait_pipe, 0); else spawn_wake_and_close(ca->parent_wait_pipe, 0); ret = ca->cb(ca->arg); if (ca->is_exec) goto err; return ret; err_um: if (ct->root_path) fs_umount_ext(ct); err: spawn_wake_and_close(ca->parent_wait_pipe, ret); exit(ret); }