aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2018-12-15 17:00:49 +0100
committerLibravatar smitsohu <smitsohu@gmail.com>2018-12-15 17:37:22 +0100
commit89fa2a7562e84338d88ea83777861f00e545135d (patch)
tree78e9ab303fb28d9b94542ee96fbdb51ca6e8982c
parentjoin: check prctl return value (diff)
downloadfirejail-89fa2a7562e84338d88ea83777861f00e545135d.tar.gz
firejail-89fa2a7562e84338d88ea83777861f00e545135d.tar.zst
firejail-89fa2a7562e84338d88ea83777861f00e545135d.zip
enforce nonewprivs instead of seccomp for chroot sandboxes
currently users are able to specify a seccomp filter of their choosing, leaving the real defense to nonewprivs anyway.
-rw-r--r--src/firejail/main.c25
-rw-r--r--src/firejail/sandbox.c46
-rw-r--r--src/firejail/seccomp.c6
-rw-r--r--src/man/firejail.txt12
4 files changed, 43 insertions, 46 deletions
diff --git a/src/firejail/main.c b/src/firejail/main.c
index f35b2a925..9aff4e4e5 100644
--- a/src/firejail/main.c
+++ b/src/firejail/main.c
@@ -866,7 +866,6 @@ int main(int argc, char **argv) {
866 int lockfd_directory = -1; 866 int lockfd_directory = -1;
867 int option_cgroup = 0; 867 int option_cgroup = 0;
868 int custom_profile = 0; // custom profile loaded 868 int custom_profile = 0; // custom profile loaded
869 int arg_seccomp_cmdline = 0; // seccomp requested on command line (used to break out of --chroot)
870 int arg_caps_cmdline = 0; // caps requested on command line (used to break out of --chroot) 869 int arg_caps_cmdline = 0; // caps requested on command line (used to break out of --chroot)
871 870
872 // drop permissions by default and rise them when required 871 // drop permissions by default and rise them when required
@@ -1153,7 +1152,6 @@ int main(int argc, char **argv) {
1153 } 1152 }
1154 arg_seccomp = 1; 1153 arg_seccomp = 1;
1155 cfg.seccomp_list = seccomp_check_list(argv[i] + 10); 1154 cfg.seccomp_list = seccomp_check_list(argv[i] + 10);
1156 arg_seccomp_cmdline = 1;
1157 } 1155 }
1158 else 1156 else
1159 exit_err_feature("seccomp"); 1157 exit_err_feature("seccomp");
@@ -1166,7 +1164,6 @@ int main(int argc, char **argv) {
1166 } 1164 }
1167 arg_seccomp = 1; 1165 arg_seccomp = 1;
1168 cfg.seccomp_list_drop = seccomp_check_list(argv[i] + 15); 1166 cfg.seccomp_list_drop = seccomp_check_list(argv[i] + 15);
1169 arg_seccomp_cmdline = 1;
1170 } 1167 }
1171 else 1168 else
1172 exit_err_feature("seccomp"); 1169 exit_err_feature("seccomp");
@@ -1179,7 +1176,6 @@ int main(int argc, char **argv) {
1179 } 1176 }
1180 arg_seccomp = 1; 1177 arg_seccomp = 1;
1181 cfg.seccomp_list_keep = seccomp_check_list(argv[i] + 15); 1178 cfg.seccomp_list_keep = seccomp_check_list(argv[i] + 15);
1182 arg_seccomp_cmdline = 1;
1183 } 1179 }
1184 else 1180 else
1185 exit_err_feature("seccomp"); 1181 exit_err_feature("seccomp");
@@ -2278,12 +2274,21 @@ int main(int argc, char **argv) {
2278 } 2274 }
2279 EUID_ASSERT(); 2275 EUID_ASSERT();
2280 2276
2281 // exit for --chroot sandboxes when secomp or caps are explicitly specified on command line 2277 // exit chroot, overlay and appimage sandboxes when caps are explicitly specified on command line
2282 if (getuid() != 0 && cfg.chrootdir && (arg_seccomp_cmdline || arg_caps_cmdline)) { 2278 if (getuid() != 0 && arg_caps_cmdline) {
2283 fprintf(stderr, "Error: for chroot sandboxes, default seccomp and capabilities filters are\n" 2279 char *opt = NULL;
2284 "enabled by default. Please remove all --seccomp and --caps options from the\n" 2280 if (cfg.chrootdir)
2285 "command line.\n"); 2281 opt = "chroot";
2286 exit(1); 2282 else if (arg_overlay)
2283 opt = "overlay";
2284 else if (arg_appimage)
2285 opt = "appimage";
2286
2287 if (opt) {
2288 fprintf(stderr, "Error: all capabilities are dropped for %s by default.\n"
2289 "Please remove --caps options from the command line.\n", opt);
2290 exit(1);
2291 }
2287 } 2292 }
2288 2293
2289 // prog_index could still be -1 if no program was specified 2294 // prog_index could still be -1 if no program was specified
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 2113ef70f..6a9977455 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -39,6 +39,9 @@
39#ifndef PR_SET_NO_NEW_PRIVS 39#ifndef PR_SET_NO_NEW_PRIVS
40# define PR_SET_NO_NEW_PRIVS 38 40# define PR_SET_NO_NEW_PRIVS 38
41#endif 41#endif
42#ifndef PR_GET_NO_NEW_PRIVS
43# define PR_GET_NO_NEW_PRIVS 39
44#endif
42 45
43#ifdef HAVE_APPARMOR 46#ifdef HAVE_APPARMOR
44#include <sys/apparmor.h> 47#include <sys/apparmor.h>
@@ -46,10 +49,7 @@
46#include <syscall.h> 49#include <syscall.h>
47 50
48 51
49#ifdef HAVE_SECCOMP 52static int force_nonewprivs = 0;
50int enforce_seccomp = 0;
51#endif
52
53 53
54static int monitored_pid = 0; 54static int monitored_pid = 0;
55static void sandbox_handler(int sig){ 55static void sandbox_handler(int sig){
@@ -539,23 +539,17 @@ void start_application(int no_sandbox, FILE *fp) {
539} 539}
540 540
541static void enforce_filters(void) { 541static void enforce_filters(void) {
542 // force default seccomp inside the chroot, no keep or drop list 542 // enforce NO_NEW_PRIVS
543 // the list build on top of the default drop list is kept intact
544 arg_nonewprivs = 1; 543 arg_nonewprivs = 1;
545 arg_seccomp = 1; 544 force_nonewprivs = 1;
546#ifdef HAVE_SECCOMP
547 enforce_seccomp = 1;
548#endif
549 545
550 // disable all capabilities 546 // disable all capabilities
551 if (arg_caps_default_filter || arg_caps_list) 547 fmessage("\n** Warning: dropping all Linux capabilities **\n");
552 fwarning("all capabilities disabled for a regular user in chroot\n");
553 arg_caps_drop_all = 1; 548 arg_caps_drop_all = 1;
554 549
555 // drop all supplementary groups; /etc/group file inside chroot 550 // drop all supplementary groups; /etc/group file inside chroot
556 // is controlled by a regular usr 551 // is controlled by a regular usr
557 arg_nogroups = 1; 552 arg_nogroups = 1;
558 fmessage("\n** Warning: dropping all Linux capabilities **\n");
559} 553}
560 554
561int sandbox(void* sandbox_arg) { 555int sandbox(void* sandbox_arg) {
@@ -754,24 +748,17 @@ int sandbox(void* sandbox_arg) {
754 748
755 // need ld.so.preload if tracing or seccomp with any non-default lists 749 // need ld.so.preload if tracing or seccomp with any non-default lists
756 bool need_preload = arg_trace || arg_tracelog || arg_seccomp_postexec; 750 bool need_preload = arg_trace || arg_tracelog || arg_seccomp_postexec;
757 // for --appimage, --chroot and --overlay* we replace the seccomp filter with the default one 751 // for --appimage, --chroot and --overlay* we force NO_NEW_PRIVS
758 // we also drop all capabilities 752 // and drop all capabilities
759 if (getuid() != 0 && (arg_appimage || cfg.chrootdir || arg_overlay)) { 753 if (getuid() != 0 && (arg_appimage || cfg.chrootdir || arg_overlay)) {
760 enforce_filters(); 754 enforce_filters();
761 need_preload = arg_trace || arg_tracelog; 755 need_preload = arg_trace || arg_tracelog;
762 arg_seccomp = 1;
763 } 756 }
764 757
765 // trace pre-install 758 // trace pre-install
766 if (need_preload) 759 if (need_preload)
767 fs_trace_preload(); 760 fs_trace_preload();
768 761
769 // state of nonewprivs
770 save_nonewprivs();
771
772 // save original umask
773 save_umask();
774
775 // store hosts file 762 // store hosts file
776 if (cfg.hosts_file) 763 if (cfg.hosts_file)
777 fs_store_hosts_file(); 764 fs_store_hosts_file();
@@ -1043,9 +1030,15 @@ int sandbox(void* sandbox_arg) {
1043 if (arg_x11_xorg) 1030 if (arg_x11_xorg)
1044 x11_xorg(); 1031 x11_xorg();
1045 1032
1033 // save original umask
1034 save_umask();
1035
1046 //**************************** 1036 //****************************
1047 // set security filters 1037 // set security filters
1048 //**************************** 1038 //****************************
1039 // save state of nonewprivs
1040 save_nonewprivs();
1041
1049 // set capabilities 1042 // set capabilities
1050 set_caps(); 1043 set_caps();
1051 1044
@@ -1145,8 +1138,13 @@ int sandbox(void* sandbox_arg) {
1145 if (arg_nonewprivs) { 1138 if (arg_nonewprivs) {
1146 prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); 1139 prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1147 1140
1148 if (prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0) != 1) 1141 if (prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0) != 1) {
1149 fwarning("NO_NEW_PRIVS disabled, it requires a Linux kernel version 3.5 or newer.\n"); 1142 fwarning("cannot set NO_NEW_PRIVS, it requires a Linux kernel version 3.5 or newer.\n");
1143 if (force_nonewprivs) {
1144 fprintf(stderr, "Error: NO_NEW_PRIVS required for this sandbox, exiting ...\n");
1145 exit(1);
1146 }
1147 }
1150 else if (arg_debug) 1148 else if (arg_debug)
1151 printf("NO_NEW_PRIVS set\n"); 1149 printf("NO_NEW_PRIVS set\n");
1152 } 1150 }
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c
index 7be7b3950..974e36ba7 100644
--- a/src/firejail/seccomp.c
+++ b/src/firejail/seccomp.c
@@ -31,7 +31,6 @@ typedef struct filter_list {
31 31
32static FilterList *filter_list_head = NULL; 32static FilterList *filter_list_head = NULL;
33static int err_printed = 0; 33static int err_printed = 0;
34extern int enforce_seccomp;
35 34
36char *seccomp_check_list(const char *str) { 35char *seccomp_check_list(const char *str) {
37 assert(str); 36 assert(str);
@@ -74,11 +73,6 @@ int seccomp_install_filters(void) {
74 73
75 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &fl->prog)) { 74 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &fl->prog)) {
76 75
77 if (enforce_seccomp) {
78 fprintf(stderr, "Error: a seccomp-enabled Linux kernel is required, exiting...\n");
79 exit(1);
80 }
81
82 if (!err_printed) 76 if (!err_printed)
83 fwarning("seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n"); 77 fwarning("seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n");
84 err_printed = 1; 78 err_printed = 1;
diff --git a/src/man/firejail.txt b/src/man/firejail.txt
index 66663be35..9c1133756 100644
--- a/src/man/firejail.txt
+++ b/src/man/firejail.txt
@@ -100,8 +100,8 @@ $ firejail --allusers
100Enable AppArmor confinement. For more information, please see \fBAPPARMOR\fR section below. 100Enable AppArmor confinement. For more information, please see \fBAPPARMOR\fR section below.
101.TP 101.TP
102\fB\-\-appimage 102\fB\-\-appimage
103Sandbox an AppImage (https://appimage.org/) application. If the sandbox is started as a 103Sandbox an AppImage (https://appimage.org/) application. If the sandbox is started
104regular user, default seccomp and capabilities filters are enabled. 104as a regular user, nonewprivs and a default capabilities filter are enabled.
105.br 105.br
106 106
107.br 107.br
@@ -275,7 +275,7 @@ Example:
275\fB\-\-chroot=dirname 275\fB\-\-chroot=dirname
276Chroot the sandbox into a root filesystem. Unlike the regular filesystem container, 276Chroot the sandbox into a root filesystem. Unlike the regular filesystem container,
277the system directories are mounted read-write. If the sandbox is started as a 277the system directories are mounted read-write. If the sandbox is started as a
278regular user, default seccomp and capabilities filters are enabled. 278regular user, nonewprivs and a default capabilities filter are enabled.
279.br 279.br
280 280
281.br 281.br
@@ -1287,7 +1287,7 @@ Similar to \-\-output, but stderr is also stored.
1287Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container, 1287Mount a filesystem overlay on top of the current filesystem. Unlike the regular filesystem container,
1288the system directories are mounted read-write. All filesystem modifications go into the overlay. 1288the system directories are mounted read-write. All filesystem modifications go into the overlay.
1289Directories /run, /tmp and /dev are not covered by the overlay. The overlay is stored in $HOME/.firejail/<PID> directory. 1289Directories /run, /tmp and /dev are not covered by the overlay. The overlay is stored in $HOME/.firejail/<PID> directory.
1290If the sandbox is started as a regular user, default seccomp and capabilities filters are enabled. 1290If the sandbox is started as a regular user, nonewprivs and a default capabilities filter are enabled.
1291.br 1291.br
1292 1292
1293.br 1293.br
@@ -1307,7 +1307,7 @@ Mount a filesystem overlay on top of the current filesystem. Unlike the regular
1307the system directories are mounted read-write. All filesystem modifications go into the overlay. 1307the system directories are mounted read-write. All filesystem modifications go into the overlay.
1308Directories /run, /tmp and /dev are not covered by the overlay. The overlay is stored in $HOME/.firejail/<NAME> directory. 1308Directories /run, /tmp and /dev are not covered by the overlay. The overlay is stored in $HOME/.firejail/<NAME> directory.
1309The created overlay can be reused between multiple sessions. 1309The created overlay can be reused between multiple sessions.
1310If the sandbox is started as a regular user, default seccomp and capabilities filters are enabled. 1310If the sandbox is started as a regular user, nonewprivs and a default capabilities filter are enabled.
1311.br 1311.br
1312 1312
1313.br 1313.br
@@ -1325,7 +1325,7 @@ $ firejail \-\-overlay-named=jail1 firefox
1325\fB\-\-overlay-tmpfs 1325\fB\-\-overlay-tmpfs
1326Mount a filesystem overlay on top of the current filesystem. All filesystem modifications 1326Mount a filesystem overlay on top of the current filesystem. All filesystem modifications
1327are discarded when the sandbox is closed. Directories /run, /tmp and /dev are not covered by the overlay. 1327are discarded when the sandbox is closed. Directories /run, /tmp and /dev are not covered by the overlay.
1328If the sandbox is started as a regular user, default seccomp and capabilities filters are enabled. 1328If the sandbox is started as a regular user, nonewprivs and a default capabilities filter are enabled.
1329.br 1329.br
1330 1330
1331.br 1331.br