diff options
author | netblue30 <netblue30@yahoo.com> | 2019-01-09 09:42:55 -0500 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2019-01-09 09:42:55 -0500 |
commit | 6fc51f43e88605682bd307515090df51b871b717 (patch) | |
tree | 39402990d193a19699d3770b0362042fc7264be2 /src/firejail/join.c | |
parent | mainline merge: fix netfilter-default functionality in /etc/firejail/firejail... (diff) | |
download | firejail-6fc51f43e88605682bd307515090df51b871b717.tar.gz firejail-6fc51f43e88605682bd307515090df51b871b717.tar.zst firejail-6fc51f43e88605682bd307515090df51b871b717.zip |
mainline merge: fix join/seccomp #2296
Diffstat (limited to 'src/firejail/join.c')
-rw-r--r-- | src/firejail/join.c | 65 |
1 files changed, 37 insertions, 28 deletions
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 @@ | |||
22 | #include <sys/wait.h> | 22 | #include <sys/wait.h> |
23 | #include <fcntl.h> | 23 | #include <fcntl.h> |
24 | #include <unistd.h> | 24 | #include <unistd.h> |
25 | #include <errno.h> | ||
26 | |||
25 | #include <sys/prctl.h> | 27 | #include <sys/prctl.h> |
26 | #include <errno.h> | 28 | #include <errno.h> |
27 | 29 | ||
@@ -71,8 +73,10 @@ static void extract_nogroups(pid_t pid) { | |||
71 | errExit("asprintf"); | 73 | errExit("asprintf"); |
72 | 74 | ||
73 | struct stat s; | 75 | struct stat s; |
74 | if (stat(fname, &s) == -1) | 76 | if (stat(fname, &s) == -1) { |
77 | free(fname); | ||
75 | return; | 78 | return; |
79 | } | ||
76 | 80 | ||
77 | arg_nogroups = 1; | 81 | arg_nogroups = 1; |
78 | free(fname); | 82 | free(fname); |
@@ -84,8 +88,10 @@ static void extract_cpu(pid_t pid) { | |||
84 | errExit("asprintf"); | 88 | errExit("asprintf"); |
85 | 89 | ||
86 | struct stat s; | 90 | struct stat s; |
87 | if (stat(fname, &s) == -1) | 91 | if (stat(fname, &s) == -1) { |
92 | free(fname); | ||
88 | return; | 93 | return; |
94 | } | ||
89 | 95 | ||
90 | // there is a CPU_CFG file, load it! | 96 | // there is a CPU_CFG file, load it! |
91 | load_cpu(fname); | 97 | load_cpu(fname); |
@@ -93,7 +99,7 @@ static void extract_cpu(pid_t pid) { | |||
93 | } | 99 | } |
94 | 100 | ||
95 | 101 | ||
96 | static void extract_caps_seccomp(pid_t pid) { | 102 | static void extract_caps(pid_t pid) { |
97 | // open stat file | 103 | // open stat file |
98 | char *file; | 104 | char *file; |
99 | if (asprintf(&file, "/proc/%u/status", pid) == -1) { | 105 | if (asprintf(&file, "/proc/%u/status", pid) == -1) { |
@@ -101,32 +107,35 @@ static void extract_caps_seccomp(pid_t pid) { | |||
101 | exit(1); | 107 | exit(1); |
102 | } | 108 | } |
103 | FILE *fp = fopen(file, "r"); | 109 | FILE *fp = fopen(file, "r"); |
104 | if (!fp) { | 110 | if (!fp) |
105 | free(file); | 111 | goto errexit; |
106 | fprintf(stderr, "Error: cannot open stat file for process %u\n", pid); | ||
107 | exit(1); | ||
108 | } | ||
109 | 112 | ||
110 | char buf[BUFLEN]; | 113 | char buf[BUFLEN]; |
111 | while (fgets(buf, BUFLEN - 1, fp)) { | 114 | while (fgets(buf, BUFLEN - 1, fp)) { |
112 | if (strncmp(buf, "Seccomp:", 8) == 0) { | 115 | if (strncmp(buf, "CapBnd:", 7) == 0) { |
113 | char *ptr = buf + 8; | ||
114 | int val; | ||
115 | sscanf(ptr, "%d", &val); | ||
116 | if (val == 2) | ||
117 | apply_seccomp = 1; | ||
118 | break; | ||
119 | } | ||
120 | else if (strncmp(buf, "CapBnd:", 7) == 0) { | ||
121 | char *ptr = buf + 7; | 116 | char *ptr = buf + 7; |
122 | unsigned long long val; | 117 | unsigned long long val; |
123 | sscanf(ptr, "%llx", &val); | 118 | if (sscanf(ptr, "%llx", &val) != 1) |
119 | goto errexit; | ||
124 | apply_caps = 1; | 120 | apply_caps = 1; |
125 | caps = val; | 121 | caps = val; |
126 | } | 122 | } |
123 | else if (strncmp(buf, "NoNewPrivs:", 11) == 0) { | ||
124 | char *ptr = buf + 11; | ||
125 | int val; | ||
126 | if (sscanf(ptr, "%d", &val) != 1) | ||
127 | goto errexit; | ||
128 | if (val) | ||
129 | arg_nonewprivs = 1; | ||
130 | } | ||
127 | } | 131 | } |
128 | fclose(fp); | 132 | fclose(fp); |
129 | free(file); | 133 | free(file); |
134 | return; | ||
135 | |||
136 | errexit: | ||
137 | fprintf(stderr, "Error: cannot read stat file for process %u\n", pid); | ||
138 | exit(1); | ||
130 | } | 139 | } |
131 | 140 | ||
132 | static void extract_user_namespace(pid_t pid) { | 141 | static void extract_user_namespace(pid_t pid) { |
@@ -187,7 +196,7 @@ pid_t switch_to_child(pid_t pid) { | |||
187 | char *comm = pid_proc_comm(pid); | 196 | char *comm = pid_proc_comm(pid); |
188 | if (!comm) { | 197 | if (!comm) { |
189 | if (errno == ENOENT) { | 198 | if (errno == ENOENT) { |
190 | fprintf(stderr, "Error: cannot find process with id %d\n", pid); | 199 | fprintf(stderr, "Error: cannot find process with pid %d\n", pid); |
191 | exit(1); | 200 | exit(1); |
192 | } | 201 | } |
193 | else { | 202 | else { |
@@ -240,7 +249,7 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
240 | EUID_ROOT(); | 249 | EUID_ROOT(); |
241 | // in user mode set caps seccomp, cpu, cgroup, etc | 250 | // in user mode set caps seccomp, cpu, cgroup, etc |
242 | if (getuid() != 0) { | 251 | if (getuid() != 0) { |
243 | extract_caps_seccomp(pid); | 252 | extract_caps(pid); |
244 | extract_cpu(pid); | 253 | extract_cpu(pid); |
245 | extract_nogroups(pid); | 254 | extract_nogroups(pid); |
246 | extract_user_namespace(pid); | 255 | extract_user_namespace(pid); |
@@ -309,15 +318,8 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
309 | if (apply_caps == 1) // not available for uid 0 | 318 | if (apply_caps == 1) // not available for uid 0 |
310 | caps_set(caps); | 319 | caps_set(caps); |
311 | #ifdef HAVE_SECCOMP | 320 | #ifdef HAVE_SECCOMP |
312 | // read cfg.protocol from file | ||
313 | if (getuid() != 0) | 321 | if (getuid() != 0) |
314 | protocol_filter_load(RUN_PROTOCOL_CFG); | 322 | seccomp_load_file_list(); |
315 | if (cfg.protocol) // not available for uid 0 | ||
316 | seccomp_load(RUN_SECCOMP_PROTOCOL); // install filter | ||
317 | |||
318 | // set seccomp filter | ||
319 | if (apply_seccomp == 1) // not available for uid 0 | ||
320 | seccomp_load(RUN_SECCOMP_CFG); | ||
321 | #endif | 323 | #endif |
322 | 324 | ||
323 | // mount user namespace or drop privileges | 325 | // mount user namespace or drop privileges |
@@ -333,6 +335,13 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
333 | caps_set(caps); | 335 | caps_set(caps); |
334 | } | 336 | } |
335 | 337 | ||
338 | // set nonewprivs | ||
339 | if (arg_nonewprivs == 1) { // not available for uid 0 | ||
340 | int rv = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); | ||
341 | if (arg_debug && rv == 0) | ||
342 | printf("NO_NEW_PRIVS set\n"); | ||
343 | } | ||
344 | |||
336 | EUID_USER(); | 345 | EUID_USER(); |
337 | // set nice | 346 | // set nice |
338 | if (arg_nice) { | 347 | if (arg_nice) { |