From 680b84b4490e88a6ec40c7648e5712eff5385e82 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Sat, 29 Jul 2017 16:30:17 -0400 Subject: --shell=none fix --- src/firejail/sandbox.c | 68 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 47c6b7a06..55733d5d7 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c @@ -295,10 +295,64 @@ static void print_time(void) { printf("Child process initialized\n"); } -void start_application(void) { -//if (setsid() == -1) -//errExit("setsid"); +// check execute permissions for the program +// this is done typically by the shell +// we are here because of --shell=none +// we duplicate execvp functionality (man execvp): +// [...] if the specified +// filename does not contain a slash (/) character. The file is sought +// in the colon-separated list of directory pathnames specified in the +// PATH environment variable. +static int ok_to_run(const char *program) { + if (strstr(program, "/")) { + if (access(program, X_OK) == 0) // it will also dereference symlinks + return 1; + } + else { // search $PATH + char *path1 = getenv("PATH"); + if (path1) { + if (arg_debug) + printf("Searching $PATH for %s\n", program); + char *path2 = strdup(path1); + if (!path2) + errExit("strdup"); + + // use path2 to count the entries + char *ptr = strtok(path2, ":"); + while (ptr) { + char *fname; + + if (asprintf(&fname, "%s/%s", ptr, program) == -1) + errExit("asprintf"); + if (arg_debug) + printf("trying #%s#\n", fname); + + struct stat s; + int rv = stat(fname, &s); + if (rv == 0) { + if (access(fname, X_OK) == 0) { + free(path2); + free(fname); + return 1; + } + else + fprintf(stderr, "Error: execute permission denied for %s\n", fname); + + free(fname); + break; + } + + free(fname); + ptr = strtok(NULL, ":"); + } + free(path2); + } + } + return 0; +} + +void start_application(void) { // set environment env_defaults(); env_apply(); @@ -338,10 +392,14 @@ void start_application(void) { if (!arg_command && !arg_quiet) print_time(); + int rv = ok_to_run(cfg.original_argv[cfg.original_program_index]); #ifdef HAVE_GCOV __gcov_dump(); #endif - execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]); + if (rv) + execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]); + else + fprintf(stderr, "Error: no suitable %s executable found\n", cfg.original_argv[cfg.original_program_index]); exit(1); } //**************************************** @@ -555,7 +613,6 @@ int sandbox(void* sandbox_arg) { printf("Network namespace enabled\n"); } - // print network configuration if (!arg_quiet) { if (any_bridge_configured() || any_interface_configured() || cfg.defaultgw || cfg.dns1) { @@ -767,7 +824,6 @@ int sandbox(void* sandbox_arg) { } } - //**************************** // hosts and hostname //**************************** -- cgit v1.2.3-70-g09d2