From 6fc51f43e88605682bd307515090df51b871b717 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Wed, 9 Jan 2019 09:42:55 -0500 Subject: mainline merge: fix join/seccomp #2296 --- src/firejail/join.c | 65 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 28 deletions(-) (limited to 'src/firejail/join.c') diff --git a/src/firejail/join.c b/src/firejail/join.c index 731842275..28fd1b290 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c @@ -22,6 +22,8 @@ #include #include #include +#include + #include #include @@ -71,8 +73,10 @@ static void extract_nogroups(pid_t pid) { errExit("asprintf"); struct stat s; - if (stat(fname, &s) == -1) + if (stat(fname, &s) == -1) { + free(fname); return; + } arg_nogroups = 1; free(fname); @@ -84,8 +88,10 @@ static void extract_cpu(pid_t pid) { errExit("asprintf"); struct stat s; - if (stat(fname, &s) == -1) + if (stat(fname, &s) == -1) { + free(fname); return; + } // there is a CPU_CFG file, load it! load_cpu(fname); @@ -93,7 +99,7 @@ static void extract_cpu(pid_t pid) { } -static void extract_caps_seccomp(pid_t pid) { +static void extract_caps(pid_t pid) { // open stat file char *file; if (asprintf(&file, "/proc/%u/status", pid) == -1) { @@ -101,32 +107,35 @@ static void extract_caps_seccomp(pid_t pid) { exit(1); } FILE *fp = fopen(file, "r"); - if (!fp) { - free(file); - fprintf(stderr, "Error: cannot open stat file for process %u\n", pid); - exit(1); - } + if (!fp) + goto errexit; char buf[BUFLEN]; while (fgets(buf, BUFLEN - 1, fp)) { - if (strncmp(buf, "Seccomp:", 8) == 0) { - char *ptr = buf + 8; - int val; - sscanf(ptr, "%d", &val); - if (val == 2) - apply_seccomp = 1; - break; - } - else if (strncmp(buf, "CapBnd:", 7) == 0) { + if (strncmp(buf, "CapBnd:", 7) == 0) { char *ptr = buf + 7; unsigned long long val; - sscanf(ptr, "%llx", &val); + if (sscanf(ptr, "%llx", &val) != 1) + goto errexit; apply_caps = 1; caps = val; } + else if (strncmp(buf, "NoNewPrivs:", 11) == 0) { + char *ptr = buf + 11; + int val; + if (sscanf(ptr, "%d", &val) != 1) + goto errexit; + if (val) + arg_nonewprivs = 1; + } } fclose(fp); free(file); + return; + +errexit: + fprintf(stderr, "Error: cannot read stat file for process %u\n", pid); + exit(1); } static void extract_user_namespace(pid_t pid) { @@ -187,7 +196,7 @@ pid_t switch_to_child(pid_t pid) { char *comm = pid_proc_comm(pid); if (!comm) { if (errno == ENOENT) { - fprintf(stderr, "Error: cannot find process with id %d\n", pid); + fprintf(stderr, "Error: cannot find process with pid %d\n", pid); exit(1); } else { @@ -240,7 +249,7 @@ void join(pid_t pid, int argc, char **argv, int index) { EUID_ROOT(); // in user mode set caps seccomp, cpu, cgroup, etc if (getuid() != 0) { - extract_caps_seccomp(pid); + extract_caps(pid); extract_cpu(pid); extract_nogroups(pid); extract_user_namespace(pid); @@ -309,15 +318,8 @@ void join(pid_t pid, int argc, char **argv, int index) { if (apply_caps == 1) // not available for uid 0 caps_set(caps); #ifdef HAVE_SECCOMP - // read cfg.protocol from file if (getuid() != 0) - protocol_filter_load(RUN_PROTOCOL_CFG); - if (cfg.protocol) // not available for uid 0 - seccomp_load(RUN_SECCOMP_PROTOCOL); // install filter - - // set seccomp filter - if (apply_seccomp == 1) // not available for uid 0 - seccomp_load(RUN_SECCOMP_CFG); + seccomp_load_file_list(); #endif // mount user namespace or drop privileges @@ -333,6 +335,13 @@ void join(pid_t pid, int argc, char **argv, int index) { caps_set(caps); } + // set nonewprivs + if (arg_nonewprivs == 1) { // not available for uid 0 + int rv = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + if (arg_debug && rv == 0) + printf("NO_NEW_PRIVS set\n"); + } + EUID_USER(); // set nice if (arg_nice) { -- cgit v1.2.3-70-g09d2