aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@protonmail.com>2020-12-30 08:41:54 -0500
committerLibravatar GitHub <noreply@github.com>2020-12-30 08:41:54 -0500
commit98a87e6b535526a2efc7a2cb6ca3fe5d32f2b3d8 (patch)
treeab217878b74413d5fa11bd3f977c718f06baf6b2 /src
parentMerge pull request #3852 from rusty-snake/fix-3846 (diff)
parentjoin: add fexecve fallback for shells (diff)
downloadfirejail-98a87e6b535526a2efc7a2cb6ca3fe5d32f2b3d8.tar.gz
firejail-98a87e6b535526a2efc7a2cb6ca3fe5d32f2b3d8.tar.zst
firejail-98a87e6b535526a2efc7a2cb6ca3fe5d32f2b3d8.zip
Merge pull request #3850 from smitsohu/smitsohu-shell
join: add fexecve fallback for shells
Diffstat (limited to 'src')
-rw-r--r--src/firejail/firejail.h2
-rw-r--r--src/firejail/join.c32
-rw-r--r--src/firejail/main.c2
-rw-r--r--src/firejail/no_sandbox.c4
-rw-r--r--src/firejail/sandbox.c41
5 files changed, 54 insertions, 27 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 6c0ebcd43..80987e494 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -372,7 +372,7 @@ char *guess_shell(void);
372// sandbox.c 372// sandbox.c
373#define SANDBOX_DONE '1' 373#define SANDBOX_DONE '1'
374int sandbox(void* sandbox_arg); 374int sandbox(void* sandbox_arg);
375void start_application(int no_sandbox, char *set_sandbox_status) __attribute__((noreturn)); 375void start_application(int no_sandbox, int fd, char *set_sandbox_status) __attribute__((noreturn));
376void set_apparmor(void); 376void set_apparmor(void);
377 377
378// network_main.c 378// network_main.c
diff --git a/src/firejail/join.c b/src/firejail/join.c
index ca8b8c4bf..d2f802add 100644
--- a/src/firejail/join.c
+++ b/src/firejail/join.c
@@ -20,10 +20,14 @@
20#include "firejail.h" 20#include "firejail.h"
21#include <sys/stat.h> 21#include <sys/stat.h>
22#include <sys/wait.h> 22#include <sys/wait.h>
23#include <fcntl.h>
24#include <unistd.h> 23#include <unistd.h>
25#include <errno.h> 24#include <errno.h>
26 25
26#include <fcntl.h>
27#ifndef O_PATH
28#define O_PATH 010000000
29#endif
30
27#include <sys/prctl.h> 31#include <sys/prctl.h>
28#ifndef PR_SET_NO_NEW_PRIVS 32#ifndef PR_SET_NO_NEW_PRIVS
29#define PR_SET_NO_NEW_PRIVS 38 33#define PR_SET_NO_NEW_PRIVS 38
@@ -299,6 +303,21 @@ static void extract_umask(pid_t pid) {
299 fclose(fp); 303 fclose(fp);
300} 304}
301 305
306static int open_shell(void) {
307 EUID_ASSERT();
308 assert(cfg.shell);
309
310 if (arg_debug)
311 printf("Opening shell %s\n", cfg.shell);
312 // file descriptor will leak if not opened with O_CLOEXEC !!
313 int fd = open(cfg.shell, O_PATH|O_CLOEXEC);
314 if (fd == -1) {
315 fprintf(stderr, "Error: cannot open shell %s\n", cfg.shell);
316 exit(1);
317 }
318 return fd;
319}
320
302// return false if the sandbox identified by pid is not fully set up yet or if 321// return false if the sandbox identified by pid is not fully set up yet or if
303// it is no firejail sandbox at all, return true if the sandbox is complete 322// it is no firejail sandbox at all, return true if the sandbox is complete
304bool is_ready_for_join(const pid_t pid) { 323bool is_ready_for_join(const pid_t pid) {
@@ -391,6 +410,10 @@ void join(pid_t pid, int argc, char **argv, int index) {
391 410
392 extract_x11_display(parent); 411 extract_x11_display(parent);
393 412
413 int shfd = -1;
414 if (!arg_shell_none)
415 shfd = open_shell();
416
394 EUID_ROOT(); 417 EUID_ROOT();
395 // in user mode set caps seccomp, cpu, cgroup, etc 418 // in user mode set caps seccomp, cpu, cgroup, etc
396 if (getuid() != 0) { 419 if (getuid() != 0) {
@@ -522,10 +545,9 @@ void join(pid_t pid, int argc, char **argv, int index) {
522 extract_command(argc, argv, index); 545 extract_command(argc, argv, index);
523 if (cfg.command_line == NULL) { 546 if (cfg.command_line == NULL) {
524 assert(cfg.shell); 547 assert(cfg.shell);
525 cfg.command_line = cfg.shell;
526 cfg.window_title = cfg.shell; 548 cfg.window_title = cfg.shell;
527 } 549 }
528 if (arg_debug) 550 else if (arg_debug)
529 printf("Extracted command #%s#\n", cfg.command_line); 551 printf("Extracted command #%s#\n", cfg.command_line);
530 552
531 // set cpu affinity 553 // set cpu affinity
@@ -554,11 +576,13 @@ void join(pid_t pid, int argc, char **argv, int index) {
554 dbus_set_system_bus_env(); 576 dbus_set_system_bus_env();
555#endif 577#endif
556 578
557 start_application(0, NULL); 579 start_application(0, shfd, NULL);
558 580
559 __builtin_unreachable(); 581 __builtin_unreachable();
560 } 582 }
561 EUID_USER(); 583 EUID_USER();
584 if (shfd != -1)
585 close(shfd);
562 586
563 int status = 0; 587 int status = 0;
564 //***************************** 588 //*****************************
diff --git a/src/firejail/main.c b/src/firejail/main.c
index 544bfe83a..e5d8a4720 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -2787,7 +2787,7 @@ int main(int argc, char **argv, char **envp) {
2787 2787
2788 // build the sandbox command 2788 // build the sandbox command
2789 if (prog_index == -1 && cfg.shell) { 2789 if (prog_index == -1 && cfg.shell) {
2790 cfg.command_line = cfg.shell; 2790 assert(cfg.command_line == NULL); // runs cfg.shell
2791 cfg.window_title = cfg.shell; 2791 cfg.window_title = cfg.shell;
2792 cfg.command_name = cfg.shell; 2792 cfg.command_name = cfg.shell;
2793 } 2793 }
diff --git a/src/firejail/no_sandbox.c b/src/firejail/no_sandbox.c
index d7426f6ae..6c7803602 100644
--- a/src/firejail/no_sandbox.c
+++ b/src/firejail/no_sandbox.c
@@ -212,7 +212,7 @@ void run_no_sandbox(int argc, char **argv) {
212// } 212// }
213 213
214 if (prog_index == 0) { 214 if (prog_index == 0) {
215 cfg.command_line = cfg.shell; 215 assert(cfg.command_line == NULL); // runs cfg.shell
216 cfg.window_title = cfg.shell; 216 cfg.window_title = cfg.shell;
217 } else { 217 } else {
218 build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index); 218 build_cmdline(&cfg.command_line, &cfg.window_title, argc, argv, prog_index);
@@ -231,5 +231,5 @@ void run_no_sandbox(int argc, char **argv) {
231 231
232 arg_quiet = 1; 232 arg_quiet = 1;
233 233
234 start_application(1, NULL); 234 start_application(1, -1, NULL);
235} 235}
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 5115191ea..d811fe45a 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
464void start_application(int no_sandbox, char *set_sandbox_status) { 464void 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
589static void enforce_filters(void) { 592static 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);