aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2019-12-23 02:07:33 +0100
committerLibravatar smitsohu <smitsohu@gmail.com>2019-12-23 02:07:33 +0100
commit34b39fd486af4e2f586d20fcea275940a5df41e9 (patch)
tree50f7281cfc1320c26dfd28b03f57fcadf8f463a9 /src
parentmove invalid_sandbox function to join module (diff)
downloadfirejail-34b39fd486af4e2f586d20fcea275940a5df41e9.tar.gz
firejail-34b39fd486af4e2f586d20fcea275940a5df41e9.tar.zst
firejail-34b39fd486af4e2f586d20fcea275940a5df41e9.zip
let join wait if target sandbox is not ready yet
fixes #2139
Diffstat (limited to 'src')
-rw-r--r--src/firejail/caps.c17
-rw-r--r--src/firejail/cpu.c4
-rw-r--r--src/firejail/firejail.h3
-rw-r--r--src/firejail/join.c78
-rw-r--r--src/firejail/ls.c17
-rw-r--r--src/firejail/network_main.c17
-rw-r--r--src/firejail/protocol.c17
-rw-r--r--src/firejail/sandbox.c2
-rw-r--r--src/firejail/seccomp.c17
-rw-r--r--src/firejail/util.c17
10 files changed, 58 insertions, 131 deletions
diff --git a/src/firejail/caps.c b/src/firejail/caps.c
index 71dd9430b..738675766 100644
--- a/src/firejail/caps.c
+++ b/src/firejail/caps.c
@@ -404,21 +404,8 @@ void caps_print_filter(pid_t pid) {
404 // in case the pid is that of a firejail process, use the pid of the first child process 404 // in case the pid is that of a firejail process, use the pid of the first child process
405 pid = switch_to_child(pid); 405 pid = switch_to_child(pid);
406 406
407 // now check if the pid belongs to a firejail sandbox 407 // exit if no permission to join the sandbox
408 if (invalid_sandbox(pid)) { 408 check_join_permission(pid);
409 fprintf(stderr, "Error: no valid sandbox\n");
410 exit(1);
411 }
412
413 // check privileges for non-root users
414 uid_t uid = getuid();
415 if (uid != 0) {
416 uid_t sandbox_uid = pid_get_uid(pid);
417 if (uid != sandbox_uid) {
418 fprintf(stderr, "Error: permission denied.\n");
419 exit(1);
420 }
421 }
422 409
423 uint64_t caps = extract_caps(pid); 410 uint64_t caps = extract_caps(pid);
424 int i; 411 int i;
diff --git a/src/firejail/cpu.c b/src/firejail/cpu.c
index 7a0807257..f3392d1e0 100644
--- a/src/firejail/cpu.c
+++ b/src/firejail/cpu.c
@@ -170,13 +170,11 @@ void cpu_print_filter(pid_t pid) {
170 pid = switch_to_child(pid); 170 pid = switch_to_child(pid);
171 171
172 // now check if the pid belongs to a firejail sandbox 172 // now check if the pid belongs to a firejail sandbox
173 if (invalid_sandbox(pid)) { 173 if (is_ready_for_join(pid) == 0) {
174 fprintf(stderr, "Error: no valid sandbox\n"); 174 fprintf(stderr, "Error: no valid sandbox\n");
175 exit(1); 175 exit(1);
176 } 176 }
177 177
178
179
180 print_cpu(pid); 178 print_cpu(pid);
181 exit(0); 179 exit(0);
182} 180}
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 464e8c07c..a8c580aa1 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -426,7 +426,8 @@ void usage(void);
426 426
427// join.c 427// join.c
428void join(pid_t pid, int argc, char **argv, int index); 428void join(pid_t pid, int argc, char **argv, int index);
429int invalid_sandbox(const pid_t pid); 429int is_ready_for_join(const pid_t pid);
430void check_join_permission(pid_t pid);
430pid_t switch_to_child(pid_t pid); 431pid_t switch_to_child(pid_t pid);
431 432
432// shutdown.c 433// shutdown.c
diff --git a/src/firejail/join.c b/src/firejail/join.c
index a8dc56b3a..864d4069d 100644
--- a/src/firejail/join.c
+++ b/src/firejail/join.c
@@ -255,9 +255,10 @@ static void extract_umask(pid_t pid) {
255 fclose(fp); 255 fclose(fp);
256} 256}
257 257
258// return 1 if the sandbox identified by pid is not fully set up yet or if 258// return 0 if the sandbox identified by pid is not fully set up yet or if
259// it is no firejail sandbox at all, return 0 if the sandbox is complete 259// it is no firejail sandbox at all, return 1 if the sandbox is complete
260int invalid_sandbox(const pid_t pid) { 260int is_ready_for_join(const pid_t pid) {
261 EUID_ASSERT();
261 // check if a file "ready-for-join" exists 262 // check if a file "ready-for-join" exists
262 char *fname; 263 char *fname;
263 if (asprintf(&fname, "/proc/%d/root%s", pid, RUN_READY_FOR_JOIN) == -1) 264 if (asprintf(&fname, "/proc/%d/root%s", pid, RUN_READY_FOR_JOIN) == -1)
@@ -267,7 +268,7 @@ int invalid_sandbox(const pid_t pid) {
267 EUID_USER(); 268 EUID_USER();
268 free(fname); 269 free(fname);
269 if (!fp) 270 if (!fp)
270 return 1; 271 return 0;
271 // regular file owned by root 272 // regular file owned by root
272 int fd = fileno(fp); 273 int fd = fileno(fp);
273 if (fd == -1) 274 if (fd == -1)
@@ -277,18 +278,18 @@ int invalid_sandbox(const pid_t pid) {
277 errExit("fstat"); 278 errExit("fstat");
278 if (!S_ISREG(s.st_mode) || s.st_uid != 0) { 279 if (!S_ISREG(s.st_mode) || s.st_uid != 0) {
279 fclose(fp); 280 fclose(fp);
280 return 1; 281 return 0;
281 } 282 }
282 // check if it is non-empty 283 // check if it is non-empty
283 char buf[BUFLEN]; 284 char buf[BUFLEN];
284 if (fgets(buf, BUFLEN, fp) == NULL) { 285 if (fgets(buf, BUFLEN, fp) == NULL) {
285 fclose(fp); 286 fclose(fp);
286 return 1; 287 return 0;
287 } 288 }
288 fclose(fp); 289 fclose(fp);
289 // confirm "ready" string was written 290 // confirm "ready" string was written
290 if (strncmp(buf, "ready\n", 6) != 0) 291 if (strcmp(buf, "ready\n") != 0)
291 return 1; 292 return 0;
292 293
293 // walk down the process tree a few nodes, there should be no firejail leaf 294 // walk down the process tree a few nodes, there should be no firejail leaf
294#define MAXNODES 5 295#define MAXNODES 5
@@ -306,7 +307,7 @@ int invalid_sandbox(const pid_t pid) {
306 } 307 }
307 if (strcmp(comm, "firejail") == 0) { 308 if (strcmp(comm, "firejail") == 0) {
308 free(comm); 309 free(comm);
309 return 1; 310 return 0;
310 } 311 }
311 free(comm); 312 free(comm);
312 break; 313 break;
@@ -314,35 +315,53 @@ int invalid_sandbox(const pid_t pid) {
314 current = next; 315 current = next;
315 } 316 }
316 317
317 return 0; 318 return 1;
319}
320
321void check_join_permission(pid_t pid) {
322 // check if pid belongs to a fully set up firejail sandbox
323 unsigned i;
324 for (i = 0; is_ready_for_join(pid) == 0; i++) { // give sandbox some time to start up
325 if (i >= 50) {
326 fprintf(stderr, "Error: no valid sandbox\n");
327 exit(1);
328 }
329 usleep(100000); // 0.1 sec
330 }
331 // check privileges for non-root users
332 uid_t uid = getuid();
333 if (uid != 0) {
334 uid_t sandbox_uid = pid_get_uid(pid);
335 if (uid != sandbox_uid) {
336 fprintf(stderr, "Error: permission is denied to join a sandbox created by a different user.\n");
337 exit(1);
338 }
339 }
318} 340}
319 341
320pid_t switch_to_child(pid_t pid) { 342pid_t switch_to_child(pid_t pid) {
343 EUID_ASSERT();
321 EUID_ROOT(); 344 EUID_ROOT();
345 pid_t rv = pid;
322 errno = 0; 346 errno = 0;
323 char *comm = pid_proc_comm(pid); 347 char *comm = pid_proc_comm(pid);
324 if (!comm) { 348 if (!comm) {
325 if (errno == ENOENT) { 349 if (errno == ENOENT)
326 fprintf(stderr, "Error: cannot find process with pid %d\n", pid); 350 fprintf(stderr, "Error: cannot find process with pid %d\n", pid);
327 exit(1); 351 else
328 }
329 else {
330 fprintf(stderr, "Error: cannot read /proc file\n"); 352 fprintf(stderr, "Error: cannot read /proc file\n");
331 exit(1); 353 exit(1);
332 }
333 } 354 }
334 EUID_USER(); 355 EUID_USER();
335 if (strcmp(comm, "firejail") == 0) { 356 if (strcmp(comm, "firejail") == 0) {
336 pid_t child; 357 if (find_child(pid, &rv) == 1) {
337 if (find_child(pid, &child) == 1) {
338 fprintf(stderr, "Error: no valid sandbox\n"); 358 fprintf(stderr, "Error: no valid sandbox\n");
339 exit(1); 359 exit(1);
340 } 360 }
341 fmessage("Switching to pid %u, the first child process inside the sandbox\n", (unsigned) child); 361 fmessage("Switching to pid %u, the first child process inside the sandbox\n", (unsigned) rv);
342 pid = child;
343 } 362 }
344 free(comm); 363 free(comm);
345 return pid; 364 return rv;
346} 365}
347 366
348 367
@@ -354,21 +373,8 @@ void join(pid_t pid, int argc, char **argv, int index) {
354 // in case the pid is that of a firejail process, use the pid of the first child process 373 // in case the pid is that of a firejail process, use the pid of the first child process
355 pid = switch_to_child(pid); 374 pid = switch_to_child(pid);
356 375
357 // now check if the pid belongs to a firejail sandbox 376 // exit if no permission to join the sandbox
358 if (invalid_sandbox(pid)) { 377 check_join_permission(pid);
359 fprintf(stderr, "Error: no valid sandbox\n");
360 exit(1);
361 }
362
363 // check privileges for non-root users
364 uid_t uid = getuid();
365 if (uid != 0) {
366 uid_t sandbox_uid = pid_get_uid(pid);
367 if (uid != sandbox_uid) {
368 fprintf(stderr, "Error: permission is denied to join a sandbox created by a different user.\n");
369 exit(1);
370 }
371 }
372 378
373 extract_x11_display(parent); 379 extract_x11_display(parent);
374 380
diff --git a/src/firejail/ls.c b/src/firejail/ls.c
index 08cf5f16a..75333fdc2 100644
--- a/src/firejail/ls.c
+++ b/src/firejail/ls.c
@@ -215,21 +215,8 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
215 // in case the pid is that of a firejail process, use the pid of the first child process 215 // in case the pid is that of a firejail process, use the pid of the first child process
216 pid = switch_to_child(pid); 216 pid = switch_to_child(pid);
217 217
218 // now check if the pid belongs to a firejail sandbox 218 // exit if no permission to join the sandbox
219 if (invalid_sandbox(pid)) { 219 check_join_permission(pid);
220 fprintf(stderr, "Error: no valid sandbox\n");
221 exit(1);
222 }
223
224 // check privileges for non-root users
225 uid_t uid = getuid();
226 if (uid != 0) {
227 uid_t sandbox_uid = pid_get_uid(pid);
228 if (uid != sandbox_uid) {
229 fprintf(stderr, "Error: permission denied.\n");
230 exit(1);
231 }
232 }
233 220
234 // expand paths 221 // expand paths
235 char *fname1 = expand_path(path1);; 222 char *fname1 = expand_path(path1);;
diff --git a/src/firejail/network_main.c b/src/firejail/network_main.c
index 6a199469a..6800bde8d 100644
--- a/src/firejail/network_main.c
+++ b/src/firejail/network_main.c
@@ -272,21 +272,8 @@ void net_dns_print(pid_t pid) {
272 // in case the pid is that of a firejail process, use the pid of the first child process 272 // in case the pid is that of a firejail process, use the pid of the first child process
273 pid = switch_to_child(pid); 273 pid = switch_to_child(pid);
274 274
275 // now check if the pid belongs to a firejail sandbox 275 // exit if no permission to join the sandbox
276 if (invalid_sandbox(pid)) { 276 check_join_permission(pid);
277 fprintf(stderr, "Error: no valid sandbox\n");
278 exit(1);
279 }
280
281 // check privileges for non-root users
282 uid_t uid = getuid();
283 if (uid != 0) {
284 uid_t sandbox_uid = pid_get_uid(pid);
285 if (uid != sandbox_uid) {
286 fprintf(stderr, "Error: permission denied.\n");
287 exit(1);
288 }
289 }
290 277
291 EUID_ROOT(); 278 EUID_ROOT();
292 if (join_namespace(pid, "mnt")) 279 if (join_namespace(pid, "mnt"))
diff --git a/src/firejail/protocol.c b/src/firejail/protocol.c
index 72d29c671..d3a9e0153 100644
--- a/src/firejail/protocol.c
+++ b/src/firejail/protocol.c
@@ -67,21 +67,8 @@ void protocol_print_filter(pid_t pid) {
67 // in case the pid is that of a firejail process, use the pid of the first child process 67 // in case the pid is that of a firejail process, use the pid of the first child process
68 pid = switch_to_child(pid); 68 pid = switch_to_child(pid);
69 69
70 // now check if the pid belongs to a firejail sandbox 70 // exit if no permission to join the sandbox
71 if (invalid_sandbox(pid)) { 71 check_join_permission(pid);
72 fprintf(stderr, "Error: no valid sandbox\n");
73 exit(1);
74 }
75
76 // check privileges for non-root users
77 uid_t uid = getuid();
78 if (uid != 0) {
79 uid_t sandbox_uid = pid_get_uid(pid);
80 if (uid != sandbox_uid) {
81 fprintf(stderr, "Error: permission denied.\n");
82 exit(1);
83 }
84 }
85 72
86 // find the seccomp filter 73 // find the seccomp filter
87 EUID_ROOT(); 74 EUID_ROOT();
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 995e98f9f..6356f89a6 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -444,7 +444,7 @@ void start_application(int no_sandbox, FILE *fp) {
444 } 444 }
445 // restore original umask 445 // restore original umask
446 umask(orig_umask); 446 umask(orig_umask);
447 447 //sleep(10);
448 if (arg_debug) { 448 if (arg_debug) {
449 printf("starting application\n"); 449 printf("starting application\n");
450 printf("LD_PRELOAD=%s\n", getenv("LD_PRELOAD")); 450 printf("LD_PRELOAD=%s\n", getenv("LD_PRELOAD"));
diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c
index 609ebb7be..648ce1612 100644
--- a/src/firejail/seccomp.c
+++ b/src/firejail/seccomp.c
@@ -332,21 +332,8 @@ void seccomp_print_filter(pid_t pid) {
332 // in case the pid is that of a firejail process, use the pid of the first child process 332 // in case the pid is that of a firejail process, use the pid of the first child process
333 pid = switch_to_child(pid); 333 pid = switch_to_child(pid);
334 334
335 // now check if the pid belongs to a firejail sandbox 335 // exit if no permission to join the sandbox
336 if (invalid_sandbox(pid)) { 336 check_join_permission(pid);
337 fprintf(stderr, "Error: no valid sandbox\n");
338 exit(1);
339 }
340
341 // check privileges for non-root users
342 uid_t uid = getuid();
343 if (uid != 0) {
344 uid_t sandbox_uid = pid_get_uid(pid);
345 if (uid != sandbox_uid) {
346 fprintf(stderr, "Error: permission denied.\n");
347 exit(1);
348 }
349 }
350 337
351 // find the seccomp list file 338 // find the seccomp list file
352 EUID_ROOT(); 339 EUID_ROOT();
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 032b9a003..2a4353d8d 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -1234,21 +1234,8 @@ void enter_network_namespace(pid_t pid) {
1234 // in case the pid is that of a firejail process, use the pid of the first child process 1234 // in case the pid is that of a firejail process, use the pid of the first child process
1235 pid_t child = switch_to_child(pid); 1235 pid_t child = switch_to_child(pid);
1236 1236
1237 // now check if the pid belongs to a firejail sandbox 1237 // exit if no permission to join the sandbox
1238 if (invalid_sandbox(child)) { 1238 check_join_permission(child);
1239 fprintf(stderr, "Error: no valid sandbox\n");
1240 exit(1);
1241 }
1242
1243 // check privileges for non-root users
1244 uid_t uid = getuid();
1245 if (uid != 0) {
1246 uid_t sandbox_uid = pid_get_uid(pid);
1247 if (uid != sandbox_uid) {
1248 fprintf(stderr, "Error: permission is denied to join a sandbox created by a different user.\n");
1249 exit(1);
1250 }
1251 }
1252 1239
1253 // check network namespace 1240 // check network namespace
1254 char *name; 1241 char *name;