aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2018-12-17 23:16:13 +0100
committerLibravatar smitsohu <smitsohu@gmail.com>2018-12-17 23:16:13 +0100
commit9eca281abbb24f97fdb92c06018cd2bd0a5b215e (patch)
tree1bbefab1443c80bcc90cb4f3f69bc4b7649c6d09
parentMerge pull request #2297 from smitsohu/patch (diff)
downloadfirejail-9eca281abbb24f97fdb92c06018cd2bd0a5b215e.tar.gz
firejail-9eca281abbb24f97fdb92c06018cd2bd0a5b215e.tar.zst
firejail-9eca281abbb24f97fdb92c06018cd2bd0a5b215e.zip
join: also check proc file to detect nonewprivs bit
redundant check that adds defense in depth and maybe one day can replace the other, file based check
-rw-r--r--src/firejail/join.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/src/firejail/join.c b/src/firejail/join.c
index f52df7f04..3ee069305 100644
--- a/src/firejail/join.c
+++ b/src/firejail/join.c
@@ -22,9 +22,13 @@
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 <sys/prctl.h>
26#include <errno.h> 25#include <errno.h>
27 26
27#include <sys/prctl.h>
28#ifndef PR_SET_NO_NEW_PRIVS
29# define PR_SET_NO_NEW_PRIVS 38
30#endif
31
28static int apply_caps = 0; 32static int apply_caps = 0;
29static uint64_t caps = 0; 33static uint64_t caps = 0;
30static int apply_seccomp = 0; 34static int apply_seccomp = 0;
@@ -164,21 +168,16 @@ static void extract_caps_seccomp(pid_t pid) {
164 exit(1); 168 exit(1);
165 } 169 }
166 FILE *fp = fopen(file, "r"); 170 FILE *fp = fopen(file, "r");
167 if (!fp) { 171 if (!fp)
168 free(file); 172 goto errexit;
169 fprintf(stderr, "Error: cannot open stat file for process %u\n", pid);
170 exit(1);
171 }
172 173
173 char buf[BUFLEN]; 174 char buf[BUFLEN];
174 while (fgets(buf, BUFLEN - 1, fp)) { 175 while (fgets(buf, BUFLEN - 1, fp)) {
175 if (strncmp(buf, "Seccomp:", 8) == 0) { 176 if (strncmp(buf, "Seccomp:", 8) == 0) {
176 char *ptr = buf + 8; 177 char *ptr = buf + 8;
177 int val; 178 int val;
178 if (sscanf(ptr, "%d", &val) != 1) { 179 if (sscanf(ptr, "%d", &val) != 1)
179 fprintf(stderr, "Error: cannot read stat file for process %u\n", pid); 180 goto errexit;
180 exit(1);
181 }
182 if (val == 2) 181 if (val == 2)
183 apply_seccomp = 1; 182 apply_seccomp = 1;
184 break; 183 break;
@@ -186,16 +185,27 @@ static void extract_caps_seccomp(pid_t pid) {
186 else if (strncmp(buf, "CapBnd:", 7) == 0) { 185 else if (strncmp(buf, "CapBnd:", 7) == 0) {
187 char *ptr = buf + 7; 186 char *ptr = buf + 7;
188 unsigned long long val; 187 unsigned long long val;
189 if (sscanf(ptr, "%llx", &val) != 1) { 188 if (sscanf(ptr, "%llx", &val) != 1)
190 fprintf(stderr, "Error: cannot read stat file for process %u\n", pid); 189 goto errexit;
191 exit(1);
192 }
193 apply_caps = 1; 190 apply_caps = 1;
194 caps = val; 191 caps = val;
195 } 192 }
193 else if (strncmp(buf, "NoNewPrivs:", 11) == 0) {
194 char *ptr = buf + 11;
195 int val;
196 if (sscanf(ptr, "%d", &val) != 1)
197 goto errexit;
198 if (val)
199 arg_nonewprivs = 1;
200 }
196 } 201 }
197 fclose(fp); 202 fclose(fp);
198 free(file); 203 free(file);
204 return;
205
206errexit:
207 fprintf(stderr, "Error: cannot read stat file for process %u\n", pid);
208 exit(1);
199} 209}
200 210
201static void extract_user_namespace(pid_t pid) { 211static void extract_user_namespace(pid_t pid) {
@@ -312,7 +322,7 @@ void join(pid_t pid, int argc, char **argv, int index) {
312 EUID_ROOT(); 322 EUID_ROOT();
313 // in user mode set caps seccomp, cpu, cgroup, etc 323 // in user mode set caps seccomp, cpu, cgroup, etc
314 if (getuid() != 0) { 324 if (getuid() != 0) {
315 extract_nonewprivs(pid); 325 extract_nonewprivs(pid); // redundant on Linux >= 4.10; duplicated in function extract_caps_seccomp
316 extract_caps_seccomp(pid); 326 extract_caps_seccomp(pid);
317 extract_cpu(pid); 327 extract_cpu(pid);
318 extract_cgroup(pid); 328 extract_cgroup(pid);