void arch_reapChild(honggfuzz_t * hfuzz, fuzzer_t * fuzzer) { pid_t ptracePid = (hfuzz->pid > 0) ? hfuzz->pid : fuzzer->pid; pid_t childPid = fuzzer->pid; timer_t timerid; if (arch_setTimer(&timerid) == false) { LOGMSG(l_FATAL, "Couldn't set timer"); } int perfFd[3]; int status; pid_t pid = wait4(childPid, &status, __WNOTHREAD | __WALL | WUNTRACED, NULL); if (pid != childPid) { LOGMSG(l_FATAL, "wait4() =! pid (%d)", childPid); } if (!WIFSTOPPED(status)) { LOGMSG(l_FATAL, "PID '%d' is not in a stopped state", pid); } if (arch_ptraceAttach(ptracePid) == false) { LOGMSG(l_FATAL, "Couldn't attach to pid %d", ptracePid); } if (arch_perfEnable(ptracePid, hfuzz, perfFd) == false) { LOGMSG(l_FATAL, "Couldn't enable perf counters for pid %d", ptracePid); } kill(childPid, SIGCONT); for (;;) { int status; pid_t pid = wait3(&status, __WNOTHREAD | __WALL, NULL); LOGMSG_P(l_DEBUG, "PID '%d' returned with status '%d'", pid, status); if (pid == -1 && errno == EINTR) { arch_checkTimeLimit(hfuzz, fuzzer); continue; } if (pid == -1 && errno == ECHILD) { arch_perfAnalyze(hfuzz, fuzzer, perfFd); LOGMSG(l_DEBUG, "No more processes to track"); break; } if (pid == -1) { LOGMSG_P(l_FATAL, "wait3() failed"); } uint64_t tmp; if ((tmp = arch_ptraceGetCustomPerf(hfuzz, ptracePid)) != 0ULL) { fuzzer->branchCnt[3] = tmp; } if (ptracePid == childPid) { arch_ptraceAnalyze(hfuzz, status, pid, fuzzer); continue; } if (pid == childPid && (WIFEXITED(status) || WIFSIGNALED(status))) { arch_perfAnalyze(hfuzz, fuzzer, perfFd); break; } if (pid == childPid) { continue; } arch_ptraceAnalyze(hfuzz, status, pid, fuzzer); } arch_removeTimer(&timerid); return; }
int main(int argc, char **argv) { pid_t npid, cpid; int s, ns, cs, fc, cc, scn, scr, i; if(argc < 3){ return 1; } _max = atoi(argv[1]); if(_max < 0){ return 1; } setsid(); for(i = 0; i < sizeof(_sig) / sizeof(int); ++i){ signal(_sig[i], handler); } //limit(RLIMIT_NPROC, 64); if(_max == 0){ limit(RLIMIT_AS, 32 * 1024 * 1024); } limit(RLIMIT_CPU, 1); _pid = fork(); if(_pid < 0){ return 1; } if(_pid == 0){ if(_max <= 1){ ptrace(PTRACE_TRACEME, 0, NULL, NULL); } execv(argv[2], argv + 2); } cc = 1; fc = 0; while(cc > 0){ cpid = wait3(&cs, 0, NULL); if(WIFEXITED(cs)){ --cc; if(cpid == _pid){ s = cs; } continue; } if(WIFSIGNALED(cs)){ kill(0, WTERMSIG(cs)); } if(_max <= 1){ scn = ptrace(PTRACE_PEEKUSER, cpid, SCN, NULL); if(_bad[scn] == FORK){ scr = ptrace(PTRACE_PEEKUSER, cpid, SCR, NULL); if(scr > 0){ ++cc; if(!_max){ ptrace(PTRACE_ATTACH, scr, NULL, NULL); } ptrace(PTRACE_SYSCALL, cpid, NULL, NULL); }else if(fc < _max){ ++fc; ptrace(PTRACE_SYSCALL, cpid, NULL, NULL); }else{ kill(0, SIGKILL); } }else if(_bad[scn]){ kill(0, SIGKILL); }else{ ptrace(PTRACE_SYSCALL, cpid, NULL, NULL); } } } return WEXITSTATUS(s); }
void execute(xmlDocPtr doc, xmlNodePtr cur) { xmlChar *directory; xmlChar *command; xmlChar *returnoutput; char cwd[2048]; FILE *ptr; char buf[1024]; int returnoutputflag = 0, status, retval = 0; /* Get the current directory, in case we chdir() */ getcwd(cwd, sizeof(cwd)); if(cwd == NULL) { llog(LOG_ERR, "execute: Could not get current directory."); } directory = xmlGetProp(cur, (xmlChar *) "directory"); if(directory != NULL) { llog(LOG_DEBUG, "execute: I am changing directories"); retval = chdir((char *)directory); if(retval < 0) { llog(LOG_ERR, "Could not chdir to '%s': %s", directory, strerror(errno)); } } returnoutput = xmlGetProp(cur, (xmlChar *) "returnoutput"); if(!(xmlStrcmp((xmlChar *) "yes", (xmlChar *) returnoutput))) { llog(LOG_DEBUG, "execute: I am returning output"); returnoutputflag = 1; } command = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); llog(LOG_DEBUG, "execute: I am executing '%s'", command); if(returnoutputflag > 0) { ptr = popen((char *) command, "r"); wait3(&status, 0, NULL); if(status != 0) { llog(LOG_ERR, "execute: popen() failed, bad exit status."); } else { if(ptr == NULL) { llog(LOG_ERR, "execute: popen() failed"); } else { while(fgets(buf, 1024, ptr) != NULL) { add_output(buf); } } } pclose(ptr); } else { retval = system((char *) command); if(retval < 0) { llog(LOG_ERR, "Command failed to execute."); } } if(directory != NULL) { /* chdir() back to the original directory */ if(cwd != NULL) { retval = chdir(cwd); if(retval < 0) { llog(LOG_ERR, "Could not chdir back to '%s': %s", directory, strerror(errno)); } } } xmlFree(directory); xmlFree(command); xmlFree(returnoutput); }
void waitchild(int n) { while (wait3(NULL, WNOHANG, NULL) > 0); }
int main(int argc, char *argv[]) { int rc; struct itimerval t; struct rusage ru; int arg_offs = 1; FP = stderr; /* default */ if (argc < 2) { return usage(argv[0]); } while (argv[arg_offs][0] == '-') { if (strcmp(argv[arg_offs], "-s") == 0) { if (argc <= arg_offs+1) return usage(argv[0]); limit = atoi(argv[arg_offs+1]); arg_offs += 2; } else if (strcmp(argv[arg_offs], "-m") == 0) { if (argc <= arg_offs+1) return usage(argv[0]); limit = atoi(argv[arg_offs+1])*60; arg_offs += 2; } else if (strcmp(argv[arg_offs], "-h") == 0) { if (argc <= arg_offs+1) return usage(argv[0]); limit = atoi(argv[arg_offs+1])*3600; arg_offs += 2; } else if (strcmp(argv[arg_offs], "-v") == 0) { /* just ignore -v, only here for compatibility with texec */ arg_offs += 1; } else if (strcmp(argv[arg_offs], "-silent") == 0) { silent = 1; arg_offs += 1; } else if (strcmp(argv[arg_offs], "-killpg") == 0) { kill_group = 1; arg_offs += 1; } else if (strcmp(argv[arg_offs], "-f") == 0) { char fname[32]; int len = snprintf(fname, sizeof(fname)/sizeof(fname[0]), "runstats-%d", getpid()); if (len <= 0) return 1; FP = fopen(fname, "w"); arg_offs += 1; } else if (strcmp(argv[arg_offs], "-env") == 0) { if (argc <= arg_offs+2) return usage(argv[0]); #if VERBOSE fprintf(FP, "setting env var \"%s\" to \"%s\"\n", argv[arg_offs+1], argv[arg_offs+2]); #endif rc = setenv(argv[arg_offs+1], argv[arg_offs+2], 1/*overwrite*/); if (rc != 0 || strcmp(getenv(argv[arg_offs+1]), argv[arg_offs+2]) != 0) { fprintf(FP, "error in setenv of \"%s\" to \"%s\"\n", argv[arg_offs+1], argv[arg_offs+2]); fprintf(FP, "setenv returned %d\n", rc); fprintf(FP, "env var \"%s\" is now \"%s\"\n", argv[arg_offs+1], getenv(argv[arg_offs+1])); exit(-1); } arg_offs += 3; } else { return usage(argv[0]); } if (limit < 0) { return usage(argv[0]); } if (argc - arg_offs < 1) return usage(argv[0]); } gettimeofday(&start, (struct timezone *) 0); child = fork(); if (child < 0) { perror("ERROR on fork"); return 1; } else if (child > 0) { pid_t result; int status; get_mem_stats(child); intercept_signal(SIGALRM, (handler_t) signal_handler); intercept_signal(SIGCHLD, (handler_t) signal_handler); t.it_interval.tv_sec = 0; t.it_interval.tv_usec = 500000; t.it_value.tv_sec = 0; t.it_value.tv_usec = 500000; /* must use real timer so timer decrements while process suspended */ rc = setitimer(ITIMER_REAL, &t, NULL); assert(rc == 0); #if VERBOSE fprintf(FP, "parent waiting for child\n"); #endif /* need loop since SIGALRM will interrupt us */ do { result = wait3(&status, 0, &ru); } while (result != child); gettimeofday(&end, (struct timezone *) 0); #if VERBOSE fprintf(FP, "child has exited\n"); #endif /* turn off timer */ t.it_interval.tv_usec = 0; t.it_value.tv_usec = 0; rc = setitimer(ITIMER_REAL, &t, NULL); assert(rc == 0); if (!silent) print_stats(&start, &end, &ru, status); return (status == 0 ? 0 : 1); } else { int result; if (kill_group) { /* Change the process group so we can relibably kill all children. * This assumes that no child will change the process group or * invoke sub-commands via bash. */ result = setpgid(0 /* my pid */, 0 /* set pgid to my pid */); if (result < 0) { perror("ERROR in setpgid"); fprintf(FP, " trying to run %s\n", argv[arg_offs]); return 1; } } result = execvp(argv[arg_offs], argv+arg_offs); if (result < 0) { perror("ERROR in execvp"); fprintf(FP, " trying to run %s\n", argv[arg_offs]); return 1; } } return 0; }
int main( int argc, char ** argv ) { if ( sem_init(&sema,0,1) ) { perror("init"); } // Print usage if not enough arguments if ( argc < 3 ) { fprintf( stderr, "%s", usage ); exit( -1 ); } // Get the port from the arguments int port = 0; port = atoi( argv[2] ); if (port == 0) { fprintf( stderr, "%s", usage ); exit( -1 ); } if (port < 1024 || port > 65536) { port = 1337; } char concurrency = argv[1][1]; // Set the IP address and port for this server struct sockaddr_in serverIPAddress; memset( &serverIPAddress, 0, sizeof(serverIPAddress) ); serverIPAddress.sin_family = AF_INET; serverIPAddress.sin_addr.s_addr = INADDR_ANY; serverIPAddress.sin_port = htons((u_short) port); // Allocate a socket int masterSocket = socket(PF_INET, SOCK_STREAM, 0); if ( masterSocket < 0) { perror("socket"); exit( -1 ); } // Set socket options to reuse port. Otherwise we will // have to wait about 2 minutes before reusing the same port number int optval = 1; int err = setsockopt(masterSocket, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, sizeof( int ) ); // Bind the socket to the IP address and port int error = bind( masterSocket, (struct sockaddr *)&serverIPAddress, sizeof(serverIPAddress) ); if ( error ) { perror("bind"); exit( -1 ); } // Put socket in listening mode and set the // size of the queue of unprocessed connections error = listen( masterSocket, QueueLength); if ( error ) { perror("listen"); exit( -1 ); } // Accept incoming connections alen = sizeof( clientIPAddress ); switch(concurrency) { case 'f': while ( 1 ) { struct sockaddr_in clientIPAddress; int ret = 0; int slaveSocket = accept( masterSocket, (struct sockaddr *)&clientIPAddress, (socklen_t*)&alen); if ( slaveSocket >= 0 ) { ret = fork(); if (ret == 0) { // Process request. processRequest( slaveSocket ); exit(0); } // Close socket close( slaveSocket ); } wait3(0,0,NULL); while(waitpid(-1,NULL,WNOHANG) > 0){} } break; case 't': while( 1 ) { struct sockaddr_in clientIPAddress; int ret = 0; int slaveSocket = accept( masterSocket, (struct sockaddr *)&clientIPAddress, (socklen_t*)&alen); pthread_t thread; if (slaveSocket >= 0) { if (pthread_create(&thread, NULL, &threadRequest, (void*)slaveSocket)) { perror("Thread creation"); exit(0); } } else { perror("ARGH THE PORTS"); exit(0); } } break; case 'p': pthread_t thread[5]; for (int x = 0; x < 4; x+=1) { pthread_create(&thread[x], NULL, threadPool, (void *)masterSocket); } threadPool((void *)masterSocket); break; case 'i': while( 1 ) { struct sockaddr_in clientIPAddress; int slaveSocket = accept( masterSocket, (struct sockaddr *)&clientIPAddress, (socklen_t*)&alen); if ( slaveSocket < 0 ) { perror( "accept" ); exit( -1 ); } // Process request. processRequest( slaveSocket ); // Close socket close( slaveSocket ); } break; } }
static void sighandler_wait_child(int signum) { int status; wait3(&status, WNOHANG, NULL); wmlog_msg(2, "Child exited with status %d", status); }
ATF_TC_BODY(wait3, tc) { ATF_REQUIRE_ERRNO(ECHILD, wait3(NULL, TWAIT_OPTION, NULL) == -1); }
/* Here is the code that cleans up any remaining child processes */ static inline void clean_children(void) { while (wait3(NULL, WNOHANG, NULL) > 0); }
int main(int argc, char *argv[]) { pid_t pid; int ch, status; struct timeval before, after; struct rusage ru; int exitonsig = 0; while ((ch = getopt(argc, argv, "lp")) != -1) { switch(ch) { case 'l': lflag = 1; break; case 'p': portableflag = 1; break; default: usage(); /* NOTREACHED */ } } argc -= optind; argv += optind; if (argc < 1) usage(); gettimeofday(&before, (struct timezone *)NULL); switch(pid = vfork()) { case -1: /* error */ perror("time"); exit(1); /* NOTREACHED */ case 0: /* child */ execvp(*argv, argv); perror(*argv); _exit((errno == ENOENT) ? 127 : 126); /* NOTREACHED */ } /* parent */ (void)signal(SIGINT, SIG_IGN); (void)signal(SIGQUIT, SIG_IGN); while (wait3(&status, 0, &ru) != pid) ; gettimeofday(&after, (struct timezone *)NULL); if (WIFSIGNALED(status)) exitonsig = WTERMSIG(status); if (!WIFEXITED(status)) fprintf(stderr, "Command terminated abnormally.\n"); timersub(&after, &before, &after); if (portableflag) { fprintf(stderr, "real %9ld.%02ld\n", after.tv_sec, after.tv_usec/10000); fprintf(stderr, "user %9ld.%02ld\n", ru.ru_utime.tv_sec, ru.ru_utime.tv_usec/10000); fprintf(stderr, "sys %9ld.%02ld\n", ru.ru_stime.tv_sec, ru.ru_stime.tv_usec/10000); } else { fprintf(stderr, "%9ld.%02ld real ", after.tv_sec, after.tv_usec/10000); fprintf(stderr, "%9ld.%02ld user ", ru.ru_utime.tv_sec, ru.ru_utime.tv_usec/10000); fprintf(stderr, "%9ld.%02ld sys\n", ru.ru_stime.tv_sec, ru.ru_stime.tv_usec/10000); } if (lflag) { int hz; long ticks; int mib[2]; struct clockinfo clkinfo; size_t size; mib[0] = CTL_KERN; mib[1] = KERN_CLOCKRATE; size = sizeof(clkinfo); if (sysctl(mib, 2, &clkinfo, &size, NULL, 0) < 0) err(1, "sysctl"); hz = clkinfo.hz; ticks = hz * (ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) + hz * (ru.ru_utime.tv_usec + ru.ru_stime.tv_usec) / 1000000; fprintf(stderr, "%10ld %s\n", ru.ru_maxrss, "maximum resident set size"); fprintf(stderr, "%10ld %s\n", ticks ? ru.ru_ixrss / ticks : 0, "average shared memory size"); fprintf(stderr, "%10ld %s\n", ticks ? ru.ru_idrss / ticks : 0, "average unshared data size"); fprintf(stderr, "%10ld %s\n", ticks ? ru.ru_isrss / ticks : 0, "average unshared stack size"); fprintf(stderr, "%10ld %s\n", ru.ru_minflt, "minor page faults"); fprintf(stderr, "%10ld %s\n", ru.ru_majflt, "major page faults"); fprintf(stderr, "%10ld %s\n", ru.ru_nswap, "swaps"); fprintf(stderr, "%10ld %s\n", ru.ru_inblock, "block input operations"); fprintf(stderr, "%10ld %s\n", ru.ru_oublock, "block output operations"); fprintf(stderr, "%10ld %s\n", ru.ru_msgsnd, "messages sent"); fprintf(stderr, "%10ld %s\n", ru.ru_msgrcv, "messages received"); fprintf(stderr, "%10ld %s\n", ru.ru_nsignals, "signals received"); fprintf(stderr, "%10ld %s\n", ru.ru_nvcsw, "voluntary context switches"); fprintf(stderr, "%10ld %s\n", ru.ru_nivcsw, "involuntary context switches"); } if (exitonsig) { if (signal(exitonsig, SIG_DFL) == SIG_ERR) perror("signal"); else kill(getpid(), exitonsig); } exit(WIFEXITED(status) ? WEXITSTATUS(status) : EXIT_FAILURE); }