diff options
Diffstat (limited to 'src/firejail/sandbox.c')
-rw-r--r-- | src/firejail/sandbox.c | 46 |
1 files changed, 22 insertions, 24 deletions
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 | 52 | static int force_nonewprivs = 0; |
50 | int enforce_seccomp = 0; | ||
51 | #endif | ||
52 | |||
53 | 53 | ||
54 | static int monitored_pid = 0; | 54 | static int monitored_pid = 0; |
55 | static void sandbox_handler(int sig){ | 55 | static void sandbox_handler(int sig){ |
@@ -539,23 +539,17 @@ void start_application(int no_sandbox, FILE *fp) { | |||
539 | } | 539 | } |
540 | 540 | ||
541 | static void enforce_filters(void) { | 541 | static 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 | ||
561 | int sandbox(void* sandbox_arg) { | 555 | int 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 | } |