/* * Like execve(2) but falls back to running through /bin/sh * ala execvp(3) if we get ENOEXEC. */ int sudo_execve(int fd, const char *path, char *const argv[], char *envp[], bool noexec) { /* Modify the environment as needed to disable further execve(). */ if (noexec) envp = disable_execute(envp); #ifdef HAVE_FEXECVE if (fd != -1) fexecve(fd, argv, envp); else #endif execve(path, argv, envp); if (fd == -1 && errno == ENOEXEC) { int argc; char **nargv; for (argc = 0; argv[argc] != NULL; argc++) continue; nargv = reallocarray(NULL, argc + 2, sizeof(char *)); if (nargv != NULL) { nargv[0] = "sh"; nargv[1] = (char *)path; memcpy(nargv + 2, argv + 1, argc * sizeof(char *)); execve(_PATH_SUDO_BSHELL, nargv, envp); free(nargv); } } return -1; }
static int test_fexecve(char * const *envp) { int fd = open("/usr/bin/printf", O_EXEC); if (fd < 0) { perror("open"); return 1; } pid_t pid = fork(); if (pid == -1) { perror("fork"); return 1; } else if (pid > 0) { /* parent */ } else { char *argv[] = {"printf", "PASSED\n", NULL}; if (fexecve(fd, argv, envp) < 0) { perror("fexecve"); _exit(1); } } wait(NULL); return 0; }
/** A process to test the ipc's messaging */ void misc_daemon_2( ){ ipc_msg_t msg, reply; int ret; while ( 1 ){ ret = get_msg( MSG_NO_BLOCK, &msg ); if ( ret == 0 ){ printf( "pid %d: got message 0x%x (%s) from pid %d\n", getpid(), msg.msg_type, msg_lookup( msg.msg_type ), msg.sender ); if ( msg.msg_type == MSG_STATUS ){ reply.msg_type = MSG_ACK; reply.sender = getpid(); send_msg( msg.sender, &reply ); } if ( msg.msg_type == 123 ) exit_thread(); if ( msg.msg_type == 234 ){ int fd = open( "/init/blarg", 0 ); if ( fd > -1 ){ printf( "Testing...(%d)\n", fd ); fexecve( fd, 0, 0 ); } close( fd ); printf( "Complete\n" ); } } else { //sleep_thread( 1 ); } } exit_thread(); }
static int containers_reexec(void) { char **argv, *exename; int fd, mmfd, n_read, n_written; struct stat st; char buf[2048]; argv = parse_proc_stringlist("/proc/self/cmdline"); if (argv == NULL) { return -1; } fd = open("/proc/self/exe", O_RDONLY | O_CLOEXEC); if (fd == -1) { fprintf(stderr, "open(\"/proc/self/exe\"): %m\n"); return -1; } if (fstat(fd, &st) == -1) { fprintf(stderr, "fstat(\"/proc/self/exe\"): %m\n"); return -1; } exename = basename(argv[0]); mmfd = syscall(SYS_memfd_create, exename, (long) MFD_ALLOW_SEALING | MFD_CLOEXEC); if (mmfd == -1) { fprintf(stderr, "memfd_create(): %m\n"); return -1; } for (;;) { n_read = read(fd, buf, sizeof(buf)); if (n_read < 0) { fprintf(stderr, "read(\"/proc/self/exe\"): %m\n"); return -1; } if (n_read == 0) { break; } n_written = write(mmfd, buf, n_read); if (n_written < 0) { fprintf(stderr, "write(anonfd): %m\n"); return -1; } if (n_written != n_read) { fprintf(stderr, "write(anonfd): short write (%d != %d)\n", n_written, n_read); return -1; } } close(fd); if (fcntl(mmfd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL) == -1) { close(mmfd); fprintf(stderr, "Error sealing memfd copy: %m\n"); return -1; } if (fexecve(mmfd, argv, environ) == -1) { close(mmfd); fprintf(stderr, "Error during reexec(...): %m\n"); return -1; } return 0; }
int load_module( char *path, int flags ){ int fd, ret; fd = open( path, 0 ); if ( !fd ){ printf( "Could not find path\n" ); return -1; } ret = fexecve( fd, 0, 0 ); printf( "Could not exec file\n" ); return ret; }
int ensure_cloned_binary(void) { int execfd; char **argv = NULL; /* Check that we're not self-cloned, and if we are then bail. */ int cloned = is_self_cloned(); if (cloned > 0 || cloned == -ENOTRECOVERABLE) return cloned; if (fetchve(&argv) < 0) return -EINVAL; execfd = clone_binary(); if (execfd < 0) return -EIO; fexecve(execfd, argv, environ); return -ENOEXEC; }
int main(int argc, char *argv[]) { char *fullPath; fullPath = getenv("PATH"); int i= 0, fd; if(argc < 2){ printf("no argument passed \n"); return 1; } //*Passing argument to parameters of function find_executable and returning the value of the executable file as to file discriptor*// fd = find_executable(fullPath, argv[1]); if (fd < 0) err(-1, "failed to find %s in %s", argv[1], fullPath); printf("Executing FD: %d\n", fd); cap_enter();//*Enabling Capsicum capability mode*// fexecve(fd, argv + 1, environ); err(-1, "fexecve() failed"); }
int main(void) { printf ("ExecHelper tests - pid %d\n\n", getpid()); extern char **environ; int ret; printf("\n\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); printf("Attempting to execute /usr/bin/ristretto via a file descriptor... \n"); int execfd = open("/usr/bin/ristretto", O_RDONLY); char *fargv[] = {"/home/steve/Downloads", "~/Documents/Administratif/CNI", NULL}; ret = fexecve(execfd, fargv, environ); if (ret) printf("Failed: %s\n", strerror(errno)); else printf("Success!\n"); printf("\n\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); printf("Attempting to execute /usr/bin/vlc with forbidden parameters... \n"); char *argv[] = {"/usr/bin/vlc", "/tmp/test.mp3", "/tmp/test-managed.mp3", "~/Documents/Administratif/Lol", "../../../../tmp/test-managed.mp3", NULL}; ret = execvpe("vlc", argv, environ); if (ret) printf("Failed: %s\n", strerror(errno)); else printf("Success!\n"); printf("\n\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); printf("Attempting to execute /usr/bin/vlc with only allowed parameters... \n"); char *argv2[] = {"/usr/bin/vlc", "/tmp/test.mp3", "../../foo.mp3", "~/Documents/AuthorisedFiles/Test.mp3", NULL}; ret = execvpe("totem", argv2, environ); if (ret) printf("Failed: %s\n", strerror(errno)); else printf("Success!\n"); return 0; }
ATF_TC_BODY(fexecve, tc) { int status; pid_t pid; const char *const argv[] = { "touch", "test", NULL }; const char *const envp[] = { NULL }; ATF_REQUIRE((pid = fork()) != -1); if (pid == 0) { int fd; if ((fd = open("/usr/bin/touch", O_RDONLY, 0)) == -1) err(EXIT_FAILURE, "open /usr/bin/touch"); if (fexecve(fd, __UNCONST(argv), __UNCONST(envp)) == -1) { int error; if (errno == ENOSYS) error = 76; else error = EXIT_FAILURE; #ifdef __FreeBSD__ (void)close(fd); #endif err(error, "fexecve"); } } ATF_REQUIRE(waitpid(pid, &status, 0) != -1); if (!WIFEXITED(status)) atf_tc_fail("child process did not exit cleanly"); if (WEXITSTATUS(status) == 76) atf_tc_expect_fail("fexecve not implemented"); else ATF_REQUIRE(WEXITSTATUS(status) == EXIT_SUCCESS); ATF_REQUIRE(access("test", F_OK) == 0); }