diff options
-rw-r--r-- | RELNOTES | 3 | ||||
-rw-r--r-- | src/firejail/fs.c | 6 | ||||
-rw-r--r-- | src/firejail/main.c | 90 | ||||
-rw-r--r-- | src/firejail/usage.c | 1 | ||||
-rw-r--r-- | src/man/firejail.txt | 7 | ||||
-rwxr-xr-x | test/environment/firejail-in-firejail.exp | 20 |
6 files changed, 38 insertions, 89 deletions
@@ -1,6 +1,6 @@ | |||
1 | firejail (0.9.53) baseline; urgency=low | 1 | firejail (0.9.53) baseline; urgency=low |
2 | * work in progress | 2 | * work in progress |
3 | * add --noautopulse to disable automatic ~/.config/pulse (for complex setups) | 3 | * --force depercated |
4 | * modif: support for private-bin, private-lib and shell none has been | 4 | * modif: support for private-bin, private-lib and shell none has been |
5 | disabled while running AppImage archives in order to be able to use | 5 | disabled while running AppImage archives in order to be able to use |
6 | our regular profile files with AppImages. | 6 | our regular profile files with AppImages. |
@@ -10,6 +10,7 @@ firejail (0.9.53) baseline; urgency=low | |||
10 | All users of Firefox-based browsers who use addons and plugins | 10 | All users of Firefox-based browsers who use addons and plugins |
11 | that read/write from ${HOME} will need to uncomment the includes for | 11 | that read/write from ${HOME} will need to uncomment the includes for |
12 | firefox-common-addons.inc in firefox-common.profile. | 12 | firefox-common-addons.inc in firefox-common.profile. |
13 | * add --noautopulse to disable automatic ~/.config/pulse (for complex setups) | ||
13 | * Spectre mitigation patch for gcc and clang compiler | 14 | * Spectre mitigation patch for gcc and clang compiler |
14 | * D-Bus handling (--nodbus) | 15 | * D-Bus handling (--nodbus) |
15 | * AppArmor support for overlayfs and chroot sandboxes | 16 | * AppArmor support for overlayfs and chroot sandboxes |
diff --git a/src/firejail/fs.c b/src/firejail/fs.c index 25b52f5ce..29cca0761 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c | |||
@@ -707,8 +707,6 @@ void fs_basic_fs(void) { | |||
707 | restrict_users(); | 707 | restrict_users(); |
708 | 708 | ||
709 | // when starting as root, firejail config is not disabled; | 709 | // when starting as root, firejail config is not disabled; |
710 | // this mode could be used to install and test new software by chaining | ||
711 | // firejail sandboxes (firejail --force) | ||
712 | if (uid) | 710 | if (uid) |
713 | disable_config(); | 711 | disable_config(); |
714 | } | 712 | } |
@@ -1020,8 +1018,6 @@ void fs_overlayfs(void) { | |||
1020 | restrict_users(); | 1018 | restrict_users(); |
1021 | 1019 | ||
1022 | // when starting as root, firejail config is not disabled; | 1020 | // when starting as root, firejail config is not disabled; |
1023 | // this mode could be used to install and test new software by chaining | ||
1024 | // firejail sandboxes (firejail --force) | ||
1025 | if (getuid() != 0) | 1021 | if (getuid() != 0) |
1026 | disable_config(); | 1022 | disable_config(); |
1027 | 1023 | ||
@@ -1265,8 +1261,6 @@ void fs_chroot(const char *rootdir) { | |||
1265 | restrict_users(); | 1261 | restrict_users(); |
1266 | 1262 | ||
1267 | // when starting as root, firejail config is not disabled; | 1263 | // when starting as root, firejail config is not disabled; |
1268 | // this mode could be used to install and test new software by chaining | ||
1269 | // firejail sandboxes (firejail --force) | ||
1270 | if (getuid() != 0) | 1264 | if (getuid() != 0) |
1271 | disable_config(); | 1265 | disable_config(); |
1272 | } | 1266 | } |
diff --git a/src/firejail/main.c b/src/firejail/main.c index 52f6af667..0d53a24a8 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -829,18 +829,24 @@ int main(int argc, char **argv) { | |||
829 | int lockfd_network = -1; | 829 | int lockfd_network = -1; |
830 | int lockfd_directory = -1; | 830 | int lockfd_directory = -1; |
831 | int option_cgroup = 0; | 831 | int option_cgroup = 0; |
832 | int option_force = 0; | ||
833 | int custom_profile = 0; // custom profile loaded | 832 | int custom_profile = 0; // custom profile loaded |
834 | |||
835 | atexit(clear_atexit); | 833 | atexit(clear_atexit); |
836 | 834 | ||
837 | // get starting timestamp | 835 | // drop permissions by default and rise them when required |
838 | start_timestamp = getticks(); | 836 | EUID_INIT(); |
837 | EUID_USER(); | ||
838 | |||
839 | // check if the user is allowed to use firejail | ||
840 | init_cfg(argc, argv); | ||
839 | 841 | ||
842 | // get starting timestamp, process --quiet | ||
843 | start_timestamp = getticks(); | ||
840 | if (check_arg(argc, argv, "--quiet", 1)) | 844 | if (check_arg(argc, argv, "--quiet", 1)) |
841 | arg_quiet = 1; | 845 | arg_quiet = 1; |
842 | 846 | ||
847 | |||
843 | // build /run/firejail directory structure | 848 | // build /run/firejail directory structure |
849 | EUID_ROOT(); | ||
844 | preproc_build_firejail_dir(); | 850 | preproc_build_firejail_dir(); |
845 | char *container_name = getenv("container"); | 851 | char *container_name = getenv("container"); |
846 | if (!container_name || strcmp(container_name, "firejail")) { | 852 | if (!container_name || strcmp(container_name, "firejail")) { |
@@ -854,7 +860,10 @@ int main(int argc, char **argv) { | |||
854 | flock(lockfd_directory, LOCK_UN); | 860 | flock(lockfd_directory, LOCK_UN); |
855 | close(lockfd_directory); | 861 | close(lockfd_directory); |
856 | } | 862 | } |
863 | EUID_USER(); | ||
864 | |||
857 | 865 | ||
866 | // process allow-debuggers | ||
858 | if (check_arg(argc, argv, "--allow-debuggers", 1)) { | 867 | if (check_arg(argc, argv, "--allow-debuggers", 1)) { |
859 | // check kernel version | 868 | // check kernel version |
860 | struct utsname u; | 869 | struct utsname u; |
@@ -875,11 +884,12 @@ int main(int argc, char **argv) { | |||
875 | } | 884 | } |
876 | 885 | ||
877 | arg_allow_debuggers = 1; | 886 | arg_allow_debuggers = 1; |
887 | char *cmd = strdup("noblacklist ${PATH}/strace"); | ||
888 | if (!cmd) | ||
889 | errExit("strdup"); | ||
890 | profile_add(cmd); | ||
878 | } | 891 | } |
879 | 892 | ||
880 | // drop permissions by default and rise them when required | ||
881 | EUID_INIT(); | ||
882 | EUID_USER(); | ||
883 | 893 | ||
884 | #ifdef HAVE_GIT_INSTALL | 894 | #ifdef HAVE_GIT_INSTALL |
885 | // process git-install and git-uninstall | 895 | // process git-install and git-uninstall |
@@ -900,51 +910,29 @@ int main(int argc, char **argv) { | |||
900 | // check if we already have a sandbox running | 910 | // check if we already have a sandbox running |
901 | // If LXC is detected, start firejail sandbox | 911 | // If LXC is detected, start firejail sandbox |
902 | // otherwise try to detect a PID namespace by looking under /proc for specific kernel processes and: | 912 | // otherwise try to detect a PID namespace by looking under /proc for specific kernel processes and: |
903 | // - if --force flag is set, start firejail sandbox | 913 | // - start the application in a /bin/bash shell |
904 | // -- if --force flag is not set, start the application in a /bin/bash shell | ||
905 | if (check_namespace_virt() == 0) { | 914 | if (check_namespace_virt() == 0) { |
906 | EUID_ROOT(); | 915 | EUID_ROOT(); |
907 | int rv = check_kernel_procs(); | 916 | int rv = check_kernel_procs(); |
908 | EUID_USER(); | 917 | EUID_USER(); |
909 | if (rv == 0) { | 918 | if (rv == 0) { |
910 | // if --force option is passed to the program, disregard the existing sandbox | 919 | if (check_arg(argc, argv, "--version", 1)) { |
911 | if (check_arg(argc, argv, "--force", 1)) | 920 | printf("firejail version %s\n", VERSION); |
912 | option_force = 1; | 921 | exit(0); |
913 | else { | ||
914 | if (check_arg(argc, argv, "--version", 1)) { | ||
915 | printf("firejail version %s\n", VERSION); | ||
916 | exit(0); | ||
917 | } | ||
918 | |||
919 | // start the program directly without sandboxing | ||
920 | run_no_sandbox(argc, argv); | ||
921 | // it will never get here! | ||
922 | assert(0); | ||
923 | } | 922 | } |
924 | } | ||
925 | } | ||
926 | 923 | ||
927 | // check root/suid | 924 | // start the program directly without sandboxing |
928 | EUID_ROOT(); | 925 | run_no_sandbox(argc, argv); |
929 | if (geteuid()) { | 926 | // it will never get here! |
930 | // only --version is supported without SUID support | 927 | assert(0); |
931 | if (check_arg(argc, argv, "--version", 1)) { | ||
932 | printf("firejail version %s\n", VERSION); | ||
933 | exit(0); | ||
934 | } | 928 | } |
935 | |||
936 | fprintf(stderr, "Error: cannot rise privileges\n"); | ||
937 | exit(1); | ||
938 | } | 929 | } |
939 | EUID_USER(); | 930 | EUID_ASSERT(); |
940 | 931 | ||
941 | // initialize globals | ||
942 | init_cfg(argc, argv); | ||
943 | 932 | ||
944 | // check firejail directories | 933 | // check firejail directories |
945 | EUID_ROOT(); | 934 | EUID_ROOT(); |
946 | delete_run_files(sandbox_pid); | 935 | delete_run_files(sandbox_pid); |
947 | |||
948 | EUID_USER(); | 936 | EUID_USER(); |
949 | 937 | ||
950 | //check if the parent is sshd daemon | 938 | //check if the parent is sshd daemon |
@@ -998,6 +986,7 @@ int main(int argc, char **argv) { | |||
998 | free(comm); | 986 | free(comm); |
999 | } | 987 | } |
1000 | } | 988 | } |
989 | EUID_ASSERT(); | ||
1001 | 990 | ||
1002 | // is this a login shell, or a command passed by sshd, insert command line options from /etc/firejail/login.users | 991 | // is this a login shell, or a command passed by sshd, insert command line options from /etc/firejail/login.users |
1003 | if (*argv[0] == '-' || parent_sshd) { | 992 | if (*argv[0] == '-' || parent_sshd) { |
@@ -1047,30 +1036,19 @@ int main(int argc, char **argv) { | |||
1047 | // check --output option and execute it; | 1036 | // check --output option and execute it; |
1048 | check_output(argc, argv); // the function will not return if --output or --output-stderr option was found | 1037 | check_output(argc, argv); // the function will not return if --output or --output-stderr option was found |
1049 | } | 1038 | } |
1039 | EUID_ASSERT(); | ||
1050 | 1040 | ||
1051 | 1041 | ||
1052 | // check for force-nonewprivs in /etc/firejail/firejail.config file | 1042 | // check for force-nonewprivs in /etc/firejail/firejail.config file |
1053 | if (checkcfg(CFG_FORCE_NONEWPRIVS)) | 1043 | if (checkcfg(CFG_FORCE_NONEWPRIVS)) |
1054 | arg_nonewprivs = 1; | 1044 | arg_nonewprivs = 1; |
1055 | 1045 | ||
1056 | if (arg_allow_debuggers) { | ||
1057 | char *cmd = strdup("noblacklist ${PATH}/strace"); | ||
1058 | if (!cmd) | ||
1059 | errExit("strdup"); | ||
1060 | profile_add(cmd); | ||
1061 | } | ||
1062 | |||
1063 | // parse arguments | 1046 | // parse arguments |
1064 | for (i = 1; i < argc; i++) { | 1047 | for (i = 1; i < argc; i++) { |
1065 | run_cmd_and_exit(i, argc, argv); // will exit if the command is recognized | 1048 | run_cmd_and_exit(i, argc, argv); // will exit if the command is recognized |
1066 | 1049 | ||
1067 | if (strcmp(argv[i], "--debug") == 0) { | 1050 | if (strcmp(argv[i], "--debug") == 0 && !arg_quiet) |
1068 | if (!arg_quiet) { | 1051 | arg_debug = 1; |
1069 | arg_debug = 1; | ||
1070 | if (option_force) | ||
1071 | fmessage("Entering sandbox-in-sandbox mode\n"); | ||
1072 | } | ||
1073 | } | ||
1074 | else if (strcmp(argv[i], "--debug-check-filename") == 0) | 1052 | else if (strcmp(argv[i], "--debug-check-filename") == 0) |
1075 | arg_debug_check_filename = 1; | 1053 | arg_debug_check_filename = 1; |
1076 | else if (strcmp(argv[i], "--debug-blacklists") == 0) | 1054 | else if (strcmp(argv[i], "--debug-blacklists") == 0) |
@@ -1083,8 +1061,6 @@ int main(int argc, char **argv) { | |||
1083 | arg_quiet = 1; | 1061 | arg_quiet = 1; |
1084 | arg_debug = 0; | 1062 | arg_debug = 0; |
1085 | } | 1063 | } |
1086 | else if (strcmp(argv[i], "--force") == 0) | ||
1087 | ; | ||
1088 | else if (strcmp(argv[i], "--allow-debuggers") == 0) { | 1064 | else if (strcmp(argv[i], "--allow-debuggers") == 0) { |
1089 | // already handled | 1065 | // already handled |
1090 | } | 1066 | } |
@@ -2273,6 +2249,7 @@ int main(int argc, char **argv) { | |||
2273 | break; | 2249 | break; |
2274 | } | 2250 | } |
2275 | } | 2251 | } |
2252 | EUID_ASSERT(); | ||
2276 | 2253 | ||
2277 | // prog_index could still be -1 if no program was specified | 2254 | // prog_index could still be -1 if no program was specified |
2278 | if (prog_index == -1 && arg_shell_none) { | 2255 | if (prog_index == -1 && arg_shell_none) { |
@@ -2401,6 +2378,7 @@ int main(int argc, char **argv) { | |||
2401 | fmessage("\n** Note: you can use --noprofile to disable %s.profile **\n\n", profile_name); | 2378 | fmessage("\n** Note: you can use --noprofile to disable %s.profile **\n\n", profile_name); |
2402 | } | 2379 | } |
2403 | } | 2380 | } |
2381 | EUID_ASSERT(); | ||
2404 | 2382 | ||
2405 | // block X11 sockets | 2383 | // block X11 sockets |
2406 | if (arg_x11_block) | 2384 | if (arg_x11_block) |
@@ -2428,6 +2406,7 @@ int main(int argc, char **argv) { | |||
2428 | network_set_run_file(sandbox_pid); | 2406 | network_set_run_file(sandbox_pid); |
2429 | EUID_USER(); | 2407 | EUID_USER(); |
2430 | } | 2408 | } |
2409 | EUID_ASSERT(); | ||
2431 | 2410 | ||
2432 | // create the parent-child communication pipe | 2411 | // create the parent-child communication pipe |
2433 | if (pipe(parent_to_child_fds) < 0) | 2412 | if (pipe(parent_to_child_fds) < 0) |
@@ -2479,6 +2458,7 @@ int main(int argc, char **argv) { | |||
2479 | else if (arg_debug) | 2458 | else if (arg_debug) |
2480 | printf("Using the local network stack\n"); | 2459 | printf("Using the local network stack\n"); |
2481 | 2460 | ||
2461 | EUID_ASSERT(); | ||
2482 | EUID_ROOT(); | 2462 | EUID_ROOT(); |
2483 | child = clone(sandbox, | 2463 | child = clone(sandbox, |
2484 | child_stack + STACK_SIZE, | 2464 | child_stack + STACK_SIZE, |
@@ -2519,6 +2499,7 @@ int main(int argc, char **argv) { | |||
2519 | waitpid(net_child, NULL, 0); | 2499 | waitpid(net_child, NULL, 0); |
2520 | EUID_USER(); | 2500 | EUID_USER(); |
2521 | } | 2501 | } |
2502 | EUID_ASSERT(); | ||
2522 | 2503 | ||
2523 | // close each end of the unused pipes | 2504 | // close each end of the unused pipes |
2524 | close(parent_to_child_fds[0]); | 2505 | close(parent_to_child_fds[0]); |
@@ -2594,6 +2575,7 @@ int main(int argc, char **argv) { | |||
2594 | EUID_USER(); | 2575 | EUID_USER(); |
2595 | free(map_path); | 2576 | free(map_path); |
2596 | } | 2577 | } |
2578 | EUID_ASSERT(); | ||
2597 | 2579 | ||
2598 | // notify child that UID/GID mapping is complete | 2580 | // notify child that UID/GID mapping is complete |
2599 | notify_other(parent_to_child_fds[1]); | 2581 | notify_other(parent_to_child_fds[1]); |
diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 1c878c818..542747efc 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c | |||
@@ -76,7 +76,6 @@ static char *usage_str = | |||
76 | " --dns=address - set DNS server.\n" | 76 | " --dns=address - set DNS server.\n" |
77 | " --dns.print=name|pid - print DNS configuration.\n" | 77 | " --dns.print=name|pid - print DNS configuration.\n" |
78 | " --env=name=value - set environment variable.\n" | 78 | " --env=name=value - set environment variable.\n" |
79 | " --force - attempt to start a new sandbox inside the existing sandbox.\n" | ||
80 | " --fs.print=name|pid - print the filesystem log.\n" | 79 | " --fs.print=name|pid - print the filesystem log.\n" |
81 | " --get=name|pid filename - get a file from sandbox container.\n" | 80 | " --get=name|pid filename - get a file from sandbox container.\n" |
82 | #ifdef HAVE_GIT_INSTALL | 81 | #ifdef HAVE_GIT_INSTALL |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index f481f5c46..85550e576 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -468,13 +468,6 @@ Example: | |||
468 | $ firejail \-\-env=LD_LIBRARY_PATH=/opt/test/lib | 468 | $ firejail \-\-env=LD_LIBRARY_PATH=/opt/test/lib |
469 | 469 | ||
470 | .TP | 470 | .TP |
471 | \fB\-\-force | ||
472 | By default, if Firejail is started in an existing sandbox, it will run the program in a bash shell. | ||
473 | This option disables this behavior, and attempts to start Firejail in the existing sandbox. | ||
474 | There could be lots of reasons for it to fail, for example if the existing sandbox disables | ||
475 | admin capabilities, SUID binaries, or if it runs seccomp. | ||
476 | |||
477 | .TP | ||
478 | \fB\-\-fs.print=name|print | 471 | \fB\-\-fs.print=name|print |
479 | Print the filesystem log for the sandbox identified by name or by PID. | 472 | Print the filesystem log for the sandbox identified by name or by PID. |
480 | .br | 473 | .br |
diff --git a/test/environment/firejail-in-firejail.exp b/test/environment/firejail-in-firejail.exp index 6f8f4316f..29f82007b 100755 --- a/test/environment/firejail-in-firejail.exp +++ b/test/environment/firejail-in-firejail.exp | |||
@@ -24,26 +24,6 @@ after 100 | |||
24 | send -- "exit\r" | 24 | send -- "exit\r" |
25 | after 100 | 25 | after 100 |
26 | 26 | ||
27 | send -- "firejail --force\r" | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 3\n";exit} | ||
30 | "cannot rise privileges" | ||
31 | } | ||
32 | after 100 | ||
33 | |||
34 | send -- "firejail --version\r" | ||
35 | expect { | ||
36 | timeout {puts "TESTING ERROR 4\n";exit} | ||
37 | "firejail version" | ||
38 | } | ||
39 | after 100 | ||
40 | |||
41 | send -- "firejail --version --force\r" | ||
42 | expect { | ||
43 | timeout {puts "TESTING ERROR 5\n";exit} | ||
44 | "firejail version" | ||
45 | } | ||
46 | after 100 | ||
47 | 27 | ||
48 | 28 | ||
49 | puts "\nall done\n" | 29 | puts "\nall done\n" |