diff options
-rw-r--r-- | src/firejail/caps.c | 17 | ||||
-rw-r--r-- | src/firejail/cpu.c | 4 | ||||
-rw-r--r-- | src/firejail/firejail.h | 3 | ||||
-rw-r--r-- | src/firejail/join.c | 78 | ||||
-rw-r--r-- | src/firejail/ls.c | 17 | ||||
-rw-r--r-- | src/firejail/network_main.c | 17 | ||||
-rw-r--r-- | src/firejail/protocol.c | 17 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 2 | ||||
-rw-r--r-- | src/firejail/seccomp.c | 17 | ||||
-rw-r--r-- | src/firejail/util.c | 17 |
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 |
428 | void join(pid_t pid, int argc, char **argv, int index); | 428 | void join(pid_t pid, int argc, char **argv, int index); |
429 | int invalid_sandbox(const pid_t pid); | 429 | int is_ready_for_join(const pid_t pid); |
430 | void check_join_permission(pid_t pid); | ||
430 | pid_t switch_to_child(pid_t pid); | 431 | pid_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 |
260 | int invalid_sandbox(const pid_t pid) { | 260 | int 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 | |||
321 | void 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 | ||
320 | pid_t switch_to_child(pid_t pid) { | 342 | pid_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; |