aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/firejail/sandbox.c68
1 files changed, 62 insertions, 6 deletions
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) {
295 printf("Child process initialized\n"); 295 printf("Child process initialized\n");
296} 296}
297 297
298void start_application(void) {
299//if (setsid() == -1)
300//errExit("setsid");
301 298
299// check execute permissions for the program
300// this is done typically by the shell
301// we are here because of --shell=none
302// we duplicate execvp functionality (man execvp):
303// [...] if the specified
304// filename does not contain a slash (/) character. The file is sought
305// in the colon-separated list of directory pathnames specified in the
306// PATH environment variable.
307static int ok_to_run(const char *program) {
308 if (strstr(program, "/")) {
309 if (access(program, X_OK) == 0) // it will also dereference symlinks
310 return 1;
311 }
312 else { // search $PATH
313 char *path1 = getenv("PATH");
314 if (path1) {
315 if (arg_debug)
316 printf("Searching $PATH for %s\n", program);
317 char *path2 = strdup(path1);
318 if (!path2)
319 errExit("strdup");
320
321 // use path2 to count the entries
322 char *ptr = strtok(path2, ":");
323 while (ptr) {
324 char *fname;
325
326 if (asprintf(&fname, "%s/%s", ptr, program) == -1)
327 errExit("asprintf");
328 if (arg_debug)
329 printf("trying #%s#\n", fname);
330
331 struct stat s;
332 int rv = stat(fname, &s);
333 if (rv == 0) {
334 if (access(fname, X_OK) == 0) {
335 free(path2);
336 free(fname);
337 return 1;
338 }
339 else
340 fprintf(stderr, "Error: execute permission denied for %s\n", fname);
341
342 free(fname);
343 break;
344 }
345
346 free(fname);
347 ptr = strtok(NULL, ":");
348 }
349 free(path2);
350 }
351 }
352 return 0;
353}
354
355void start_application(void) {
302 // set environment 356 // set environment
303 env_defaults(); 357 env_defaults();
304 env_apply(); 358 env_apply();
@@ -338,10 +392,14 @@ void start_application(void) {
338 if (!arg_command && !arg_quiet) 392 if (!arg_command && !arg_quiet)
339 print_time(); 393 print_time();
340 394
395 int rv = ok_to_run(cfg.original_argv[cfg.original_program_index]);
341#ifdef HAVE_GCOV 396#ifdef HAVE_GCOV
342 __gcov_dump(); 397 __gcov_dump();
343#endif 398#endif
344 execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]); 399 if (rv)
400 execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]);
401 else
402 fprintf(stderr, "Error: no suitable %s executable found\n", cfg.original_argv[cfg.original_program_index]);
345 exit(1); 403 exit(1);
346 } 404 }
347 //**************************************** 405 //****************************************
@@ -555,7 +613,6 @@ int sandbox(void* sandbox_arg) {
555 printf("Network namespace enabled\n"); 613 printf("Network namespace enabled\n");
556 } 614 }
557 615
558
559 // print network configuration 616 // print network configuration
560 if (!arg_quiet) { 617 if (!arg_quiet) {
561 if (any_bridge_configured() || any_interface_configured() || cfg.defaultgw || cfg.dns1) { 618 if (any_bridge_configured() || any_interface_configured() || cfg.defaultgw || cfg.dns1) {
@@ -767,7 +824,6 @@ int sandbox(void* sandbox_arg) {
767 } 824 }
768 } 825 }
769 826
770
771 //**************************** 827 //****************************
772 // hosts and hostname 828 // hosts and hostname
773 //**************************** 829 //****************************