From 178f649ac21f1511db89c1bfcb617678b7bf2e2a Mon Sep 17 00:00:00 2001 From: The Fox in the Shell Date: Thu, 7 Apr 2016 18:22:24 +0200 Subject: sandbox: Add NO_NEW_PRIVS inconditionally This is just a first try --- src/firejail/sandbox.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 5cfee44d8..109395b60 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c @@ -747,6 +747,16 @@ int sandbox(void* sandbox_arg) { set_caps(); } + //**************************************** + // Set NO_NEW_PRIVS if desired + //**************************************** + int no_new_privs = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + if(no_new_privs != 0) { + errExit("NO_NEW_PRIVS"); + } else + printf("No new privileges from this point on\n"); + + //**************************************** // fork the application and monitor it //**************************************** -- cgit v1.2.3-54-g00ecf From 0688847fa8287752e2bdd209bde37029dff48dc5 Mon Sep 17 00:00:00 2001 From: The Fox in the Shell Date: Wed, 25 May 2016 02:19:02 +0200 Subject: Make NO_NEW_PRIVS configurable --- src/firejail/firejail.h | 1 + src/firejail/main.c | 4 ++++ src/firejail/profile.c | 4 ++++ src/firejail/sandbox.c | 13 ++++++++----- src/firejail/usage.c | 3 +++ 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index f4a176caf..c9c090a97 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -237,6 +237,7 @@ extern int arg_rlimit_nproc; // rlimit nproc extern int arg_rlimit_fsize; // rlimit fsize extern int arg_rlimit_sigpending;// rlimit sigpending extern int arg_nogroups; // disable supplementary groups +extern int arg_nonewprivs; // set the NO_NEW_PRIVS prctl extern int arg_noroot; // create a new user namespace and disable root user extern int arg_netfilter; // enable netfilter extern int arg_netfilter6; // enable netfilter6 diff --git a/src/firejail/main.c b/src/firejail/main.c index a540d468b..2f4a78d4b 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -77,6 +77,7 @@ int arg_rlimit_nproc = 0; // rlimit nproc int arg_rlimit_fsize = 0; // rlimit fsize int arg_rlimit_sigpending = 0; // rlimit fsize int arg_nogroups = 0; // disable supplementary groups +int arg_nonewprivs = 0; // set the NO_NEW_PRIVS prctl int arg_noroot = 0; // create a new user namespace and disable root user int arg_netfilter; // enable netfilter int arg_netfilter6; // enable netfilter6 @@ -1367,6 +1368,9 @@ int main(int argc, char **argv) { } } #endif + else if (strcmp(argv[i], "--nonewprivs") == 0) { + arg_nonewprivs = 1; + } else if (strncmp(argv[i], "--env=", 6) == 0) env_store(argv[i] + 6); else if (strncmp(argv[i], "--nosound", 9) == 0) { diff --git a/src/firejail/profile.c b/src/firejail/profile.c index 3bf294e00..192f36974 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c @@ -131,6 +131,10 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { return 0; } + else if (strcmp(ptr, "nonewprivs") == 0) { + arg_nonewprivs = 1; + return 0; + } else if (strcmp(ptr, "seccomp") == 0) { #ifdef HAVE_SECCOMP if (checkcfg(CFG_SECCOMP)) diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 109395b60..843c1efe5 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c @@ -750,11 +750,14 @@ int sandbox(void* sandbox_arg) { //**************************************** // Set NO_NEW_PRIVS if desired //**************************************** - int no_new_privs = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); - if(no_new_privs != 0) { - errExit("NO_NEW_PRIVS"); - } else - printf("No new privileges from this point on\n"); + if (arg_nonewprivs) { + int no_new_privs = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + + if(no_new_privs != 0) + errExit("NO_NEW_PRIVS"); + else if (arg_debug) + printf("NO_NEW_PRIVS set\n"); + } //**************************************** diff --git a/src/firejail/usage.c b/src/firejail/usage.c index ef02c0d72..45bf2e3b1 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c @@ -157,6 +157,9 @@ void usage(void) { printf("\tuser. root user does not exist in the new namespace. This option\n"); printf("\tis not supported for --chroot and --overlay configurations.\n\n"); #endif + printf(" --nonewprivs - sets the NO_NEW_PRIVS prctl - the child processes\n"); + printf("\tcannot gain privileges using execve(2); in particular, this prevents\n"); + printf("\tgaining privileges by calling a suid binary\n\n"); printf(" --nosound - disable sound system.\n\n"); printf(" --output=logfile - stdout logging and log rotation. Copy stdout and stderr\n"); -- cgit v1.2.3-54-g00ecf From 2cecda837db48f92d5f6089ba680ae5292382e6c Mon Sep 17 00:00:00 2001 From: The Fox in the Shell Date: Wed, 25 May 2016 02:26:31 +0200 Subject: Document nonewprivs --- src/man/firejail-profile.txt | 6 ++++++ src/man/firejail.txt | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt index 4d1de76f5..1f7c8beac 100644 --- a/src/man/firejail-profile.txt +++ b/src/man/firejail-profile.txt @@ -239,6 +239,12 @@ Enable seccomp filter and blacklist the system calls in the list. \fBseccomp.keep syscall,syscall,syscall Enable seccomp filter and whitelist the system calls in the list. .TP +\fBnonewprivs +Sets the NO_NEW_PRIVS prctl. This ensures that child processes +cannot acquire new privileges using execve(2); in particular, +this means that calling a suid binary (or one with file capabilities) +does not results in an increase of privilege. +.TP \fBnoroot Use this command to enable an user namespace. The namespace has only one user, the current user. There is no root account (uid 0) defined in the namespace. diff --git a/src/man/firejail.txt b/src/man/firejail.txt index 2ea15ff2b..7b22a5bf2 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt @@ -903,6 +903,13 @@ ping: icmp open socket: Operation not permitted .br $ +.TP +\fB\-\-nonewprivs +Sets the NO_NEW_PRIVS prctl. This ensures that child processes +cannot acquire new privileges using execve(2); in particular, +this means that calling a suid binary (or one with file capabilities) +does not results in an increase of privilege. + .TP \fB\-\-nosound Disable sound system. -- cgit v1.2.3-54-g00ecf From 1c0428dba28299b66380c8c05770d6619383d758 Mon Sep 17 00:00:00 2001 From: The Fox in the Shell Date: Wed, 25 May 2016 14:59:30 +0200 Subject: Add force-nonewprivs setting --- README.md | 7 +++++++ etc/firejail.config | 6 ++++++ src/firejail/checkcfg.c | 11 +++++++++++ src/firejail/firejail.h | 3 ++- src/firejail/sandbox.c | 2 +- src/man/firejail-config.txt | 8 ++++++++ 6 files changed, 35 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4fa79d9f2..6f05a010f 100644 --- a/README.md +++ b/README.md @@ -207,6 +207,13 @@ The following features can be enabled or disabled: x11 Enable or disable X11 sandboxing support, default enabled. + force-nonewprivs + Force use of theh NO_NEW_PRIVS prctl(2) flag. + This mitigates the possibility of a user abusing firejail's + features to trick a privileged (suid or file capabilities) + process into loading code or configuration that is partially + under their control. Default disabled + xephyr-screen Screen size for --x11=xephyr, default 800x600. Run /usr/bin/xrandr for a full list of resolutions available on your diff --git a/etc/firejail.config b/etc/firejail.config index 41cd08e68..caaeb6792 100644 --- a/etc/firejail.config +++ b/etc/firejail.config @@ -30,6 +30,12 @@ # Enable or disable X11 sandboxing support, default enabled. # x11 yes +# Force use of nonewprivs. This mitigates the possibility of +# a user abusing firejail's features to trick a privileged (suid +# or file capabilities) process into loading code or configuration +# that is partially under their control. Default disabled +# force-nonewprivs no + # Screen size for --x11=xephyr, default 800x600. Run /usr/bin/xrandr for # a full list of resolutions available on your specific setup. # xephyr-screen 640x480 diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c index 430b0c5a6..4fdbe1897 100644 --- a/src/firejail/checkcfg.c +++ b/src/firejail/checkcfg.c @@ -36,7 +36,9 @@ int checkcfg(int val) { int i; for (i = 0; i < CFG_MAX; i++) cfg_val[i] = 1; // most of them are enabled by default + cfg_val[CFG_RESTRICTED_NETWORK] = 0; // disabled by default + cfg_val[CFG_FORCE_NONEWPRIVS ] = 0; // disabled by default // open configuration file char *fname; @@ -106,6 +108,15 @@ int checkcfg(int val) { else goto errout; } + // nonewprivs + else if (strncmp(ptr, "force-nonewprivs ", 17) == 0) { + if (strcmp(ptr + 17, "yes") == 0) + cfg_val[CFG_SECCOMP] = 1; + else if (strcmp(ptr + 17, "no") == 0) + cfg_val[CFG_SECCOMP] = 0; + else + goto errout; + } // seccomp else if (strncmp(ptr, "seccomp ", 8) == 0) { if (strcmp(ptr + 8, "yes") == 0) diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index c9c090a97..661073730 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -566,7 +566,8 @@ void sandboxfs(int op, pid_t pid, const char *patqh); #define CFG_SECCOMP 5 #define CFG_NETWORK 6 #define CFG_RESTRICTED_NETWORK 7 -#define CFG_MAX 8 // this should always be the last entry +#define CFG_FORCE_NONEWPRIVS 8 +#define CFG_MAX 9 // this should always be the last entry int checkcfg(int val); // fs_rdwr.c diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 843c1efe5..6133a610d 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c @@ -750,7 +750,7 @@ int sandbox(void* sandbox_arg) { //**************************************** // Set NO_NEW_PRIVS if desired //**************************************** - if (arg_nonewprivs) { + if (arg_nonewprivs || checkcfg(CFG_FORCE_NONEWPRIVS)) { int no_new_privs = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); if(no_new_privs != 0) diff --git a/src/man/firejail-config.txt b/src/man/firejail-config.txt index fcf4109ee..dcede2ec6 100644 --- a/src/man/firejail-config.txt +++ b/src/man/firejail-config.txt @@ -48,6 +48,14 @@ Enable or disable user namespace support, default enabled. \fBx11 Enable or disable X11 sandboxing support, default enabled. +.TP +\fBforce-nonewprivs +Force use of nonewprivs. This mitigates the possibility of +a user abusing firejail's features to trick a privileged (suid +or file capabilities) process into loading code or configuration +that is partially under their control. Default disabled. + + .TP \fBxephyr-screen Screen size for --x11=xephyr, default 800x600. Run /usr/bin/xrandr for -- cgit v1.2.3-54-g00ecf