diff options
author | 2020-12-28 21:06:52 +0100 | |
---|---|---|
committer | 2020-12-29 23:47:05 +0100 | |
commit | 4df931507606a0a1ee2d0e916d027d01c801d926 (patch) | |
tree | 73f0e2b5eefdc2471ec2c446970edfc1dc299f6d /src/firejail/sandbox.c | |
parent | New profiles for alacarte,tootle,photoflare (#3816) (diff) | |
download | firejail-4df931507606a0a1ee2d0e916d027d01c801d926.tar.gz firejail-4df931507606a0a1ee2d0e916d027d01c801d926.tar.zst firejail-4df931507606a0a1ee2d0e916d027d01c801d926.zip |
join: add fexecve fallback for shells
Allows users to join a sandbox and get a shell even
if there is none in the sandbox mount namespace.
There are few limitations:
1. This will fail with scripted shells (see man 3 fexecve for an explanation)
2. Shell process names are not user friendly
Diffstat (limited to 'src/firejail/sandbox.c')
-rw-r--r-- | src/firejail/sandbox.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 5c7b5e556..991e5b2f2 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -461,7 +461,7 @@ static int ok_to_run(const char *program) { | |||
461 | return 0; | 461 | return 0; |
462 | } | 462 | } |
463 | 463 | ||
464 | void start_application(int no_sandbox, char *set_sandbox_status) { | 464 | void start_application(int no_sandbox, int fd, char *set_sandbox_status) { |
465 | // set environment | 465 | // set environment |
466 | if (no_sandbox == 0) { | 466 | if (no_sandbox == 0) { |
467 | env_defaults(); | 467 | env_defaults(); |
@@ -471,7 +471,7 @@ void start_application(int no_sandbox, char *set_sandbox_status) { | |||
471 | umask(orig_umask); | 471 | umask(orig_umask); |
472 | 472 | ||
473 | if (arg_debug) { | 473 | if (arg_debug) { |
474 | printf("starting application\n"); | 474 | printf("Starting application\n"); |
475 | printf("LD_PRELOAD=%s\n", getenv("LD_PRELOAD")); | 475 | printf("LD_PRELOAD=%s\n", getenv("LD_PRELOAD")); |
476 | } | 476 | } |
477 | 477 | ||
@@ -488,9 +488,6 @@ void start_application(int no_sandbox, char *set_sandbox_status) { | |||
488 | if (set_sandbox_status) | 488 | if (set_sandbox_status) |
489 | *set_sandbox_status = SANDBOX_DONE; | 489 | *set_sandbox_status = SANDBOX_DONE; |
490 | execl(arg_audit_prog, arg_audit_prog, NULL); | 490 | execl(arg_audit_prog, arg_audit_prog, NULL); |
491 | |||
492 | perror("execl"); | ||
493 | exit(1); | ||
494 | } | 491 | } |
495 | //**************************************** | 492 | //**************************************** |
496 | // start the program without using a shell | 493 | // start the program without using a shell |
@@ -532,35 +529,37 @@ void start_application(int no_sandbox, char *set_sandbox_status) { | |||
532 | //**************************************** | 529 | //**************************************** |
533 | else { | 530 | else { |
534 | assert(cfg.shell); | 531 | assert(cfg.shell); |
535 | assert(cfg.command_line); | ||
536 | 532 | ||
537 | char *arg[5]; | 533 | char *arg[5]; |
538 | int index = 0; | 534 | int index = 0; |
539 | arg[index++] = cfg.shell; | 535 | arg[index++] = cfg.shell; |
540 | if (login_shell) { | 536 | if (cfg.command_line) { |
541 | arg[index++] = "-l"; | ||
542 | if (arg_debug) | ||
543 | printf("Starting %s login shell\n", cfg.shell); | ||
544 | } else { | ||
545 | arg[index++] = "-c"; | ||
546 | if (arg_debug) | 537 | if (arg_debug) |
547 | printf("Running %s command through %s\n", cfg.command_line, cfg.shell); | 538 | printf("Running %s command through %s\n", cfg.command_line, cfg.shell); |
539 | arg[index++] = "-c"; | ||
548 | if (arg_doubledash) | 540 | if (arg_doubledash) |
549 | arg[index++] = "--"; | 541 | arg[index++] = "--"; |
550 | arg[index++] = cfg.command_line; | 542 | arg[index++] = cfg.command_line; |
551 | } | 543 | } |
552 | arg[index] = NULL; | 544 | else if (login_shell) { |
545 | if (arg_debug) | ||
546 | printf("Starting %s login shell\n", cfg.shell); | ||
547 | arg[index++] = "-l"; | ||
548 | } | ||
549 | else if (arg_debug) | ||
550 | printf("Starting %s shell\n", cfg.shell); | ||
551 | |||
553 | assert(index < 5); | 552 | assert(index < 5); |
553 | arg[index] = NULL; | ||
554 | 554 | ||
555 | if (arg_debug) { | 555 | if (arg_debug) { |
556 | char *msg; | 556 | char *msg; |
557 | if (asprintf(&msg, "sandbox %d, execvp into %s", sandbox_pid, cfg.command_line) == -1) | 557 | if (asprintf(&msg, "sandbox %d, execvp into %s", |
558 | sandbox_pid, cfg.command_line ? cfg.command_line : cfg.shell) == -1) | ||
558 | errExit("asprintf"); | 559 | errExit("asprintf"); |
559 | logmsg(msg); | 560 | logmsg(msg); |
560 | free(msg); | 561 | free(msg); |
561 | } | ||
562 | 562 | ||
563 | if (arg_debug) { | ||
564 | int i; | 563 | int i; |
565 | for (i = 0; i < 5; i++) { | 564 | for (i = 0; i < 5; i++) { |
566 | if (arg[i] == NULL) | 565 | if (arg[i] == NULL) |
@@ -580,10 +579,14 @@ void start_application(int no_sandbox, char *set_sandbox_status) { | |||
580 | if (set_sandbox_status) | 579 | if (set_sandbox_status) |
581 | *set_sandbox_status = SANDBOX_DONE; | 580 | *set_sandbox_status = SANDBOX_DONE; |
582 | execvp(arg[0], arg); | 581 | execvp(arg[0], arg); |
582 | |||
583 | // join sandbox without shell in the mount namespace | ||
584 | if (fd > -1) | ||
585 | fexecve(fd, arg, environ); | ||
583 | } | 586 | } |
584 | 587 | ||
585 | perror("execvp"); | 588 | perror("Cannot start application"); |
586 | exit(1); // it should never get here!!! | 589 | exit(1); |
587 | } | 590 | } |
588 | 591 | ||
589 | static void enforce_filters(void) { | 592 | static void enforce_filters(void) { |
@@ -1223,7 +1226,7 @@ int sandbox(void* sandbox_arg) { | |||
1223 | set_nice(cfg.nice); | 1226 | set_nice(cfg.nice); |
1224 | set_rlimits(); | 1227 | set_rlimits(); |
1225 | 1228 | ||
1226 | start_application(0, set_sandbox_status); | 1229 | start_application(0, -1, set_sandbox_status); |
1227 | } | 1230 | } |
1228 | 1231 | ||
1229 | munmap(set_sandbox_status, 1); | 1232 | munmap(set_sandbox_status, 1); |