Merge tag 'upstream/0.9.44.2'
Upstream version 0.9.44.2
# gpg: Signature made Sun 04 Dec 2016 09:27:48 PM CET
# gpg: using RSA key D8F6FA7DEA24D90D6EAC733BCCF04928DB0EEAA7
# gpg: issuer "reiner@reiner-h.de"
# gpg: Good signature from "Reiner Herrmann <reiner@reiner-h.de>" [ultimate]
# Primary key fingerprint: 2F5D AF3F C1F7 93D9 4F3D 900C A721 DA05 5374 AA4F
# Subkey fingerprint: D8F6 FA7D EA24 D90D 6EAC 733B CCF0 4928 DB0E EAA7
Reiner Herrmann
7 years ago
0 | firejail (0.9.44.2) baseline; urgency=low | |
1 | * security: overwrite /etc/resolv.conf found by Martin Carpenter | |
2 | * secuirty: TOCTOU exploit for --get and --put found by Daniel Hodson | |
3 | * security: invalid environment exploit found by Martin Carpenter | |
4 | * security: several security enhancements | |
5 | * bugfix: crashing VLC by pressing Ctrl-O | |
6 | * bugfix: use user configured icons in KDE | |
7 | * bugfix: mkdir and mkfile are not applied to private directories | |
8 | * bugfix: cannot open files on Deluge running under KDE | |
9 | * bugfix: --private=dir where dir is the user home directory | |
10 | * bugfix: cannot start Vivaldi browser | |
11 | * bugfix: cannot start mupdf | |
12 | * bugfix: ssh profile problems | |
13 | * bugfix: --quiet | |
14 | * bugfix: quiet in git profile | |
15 | * bugfix: memory corruption | |
16 | -- netblue30 <netblue30@yahoo.com> Fri, 2 Dec 2016 08:00:00 -0500 | |
17 | ||
0 | 18 | firejail (0.9.44) baseline; urgency=low |
1 | 19 | * CVE-2016-7545 submitted by Aleksey Manevich |
2 | 20 | * modifs: removed man firejail-config |
0 | 0 | #! /bin/sh |
1 | 1 | # Guess values for system-dependent variables and create Makefiles. |
2 | # Generated by GNU Autoconf 2.69 for firejail 0.9.44. | |
2 | # Generated by GNU Autoconf 2.69 for firejail 0.9.44.2. | |
3 | 3 | # |
4 | 4 | # Report bugs to <netblue30@yahoo.com>. |
5 | 5 | # |
579 | 579 | # Identity of this package. |
580 | 580 | PACKAGE_NAME='firejail' |
581 | 581 | PACKAGE_TARNAME='firejail' |
582 | PACKAGE_VERSION='0.9.44' | |
583 | PACKAGE_STRING='firejail 0.9.44' | |
582 | PACKAGE_VERSION='0.9.44.2' | |
583 | PACKAGE_STRING='firejail 0.9.44.2' | |
584 | 584 | PACKAGE_BUGREPORT='netblue30@yahoo.com' |
585 | 585 | PACKAGE_URL='http://firejail.wordpress.com' |
586 | 586 | |
1258 | 1258 | # Omit some internal or obsolete options to make the list less imposing. |
1259 | 1259 | # This message is too long to be a string in the A/UX 3.1 sh. |
1260 | 1260 | cat <<_ACEOF |
1261 | \`configure' configures firejail 0.9.44 to adapt to many kinds of systems. | |
1261 | \`configure' configures firejail 0.9.44.2 to adapt to many kinds of systems. | |
1262 | 1262 | |
1263 | 1263 | Usage: $0 [OPTION]... [VAR=VALUE]... |
1264 | 1264 | |
1319 | 1319 | |
1320 | 1320 | if test -n "$ac_init_help"; then |
1321 | 1321 | case $ac_init_help in |
1322 | short | recursive ) echo "Configuration of firejail 0.9.44:";; | |
1322 | short | recursive ) echo "Configuration of firejail 0.9.44.2:";; | |
1323 | 1323 | esac |
1324 | 1324 | cat <<\_ACEOF |
1325 | 1325 | |
1423 | 1423 | test -n "$ac_init_help" && exit $ac_status |
1424 | 1424 | if $ac_init_version; then |
1425 | 1425 | cat <<\_ACEOF |
1426 | firejail configure 0.9.44 | |
1426 | firejail configure 0.9.44.2 | |
1427 | 1427 | generated by GNU Autoconf 2.69 |
1428 | 1428 | |
1429 | 1429 | Copyright (C) 2012 Free Software Foundation, Inc. |
1725 | 1725 | This file contains any messages produced by compilers while |
1726 | 1726 | running configure, to aid debugging if configure makes a mistake. |
1727 | 1727 | |
1728 | It was created by firejail $as_me 0.9.44, which was | |
1728 | It was created by firejail $as_me 0.9.44.2, which was | |
1729 | 1729 | generated by GNU Autoconf 2.69. Invocation command line was |
1730 | 1730 | |
1731 | 1731 | $ $0 $@ |
4302 | 4302 | # report actual input values of CONFIG_FILES etc. instead of their |
4303 | 4303 | # values after options handling. |
4304 | 4304 | ac_log=" |
4305 | This file was extended by firejail $as_me 0.9.44, which was | |
4305 | This file was extended by firejail $as_me 0.9.44.2, which was | |
4306 | 4306 | generated by GNU Autoconf 2.69. Invocation command line was |
4307 | 4307 | |
4308 | 4308 | CONFIG_FILES = $CONFIG_FILES |
4356 | 4356 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 |
4357 | 4357 | ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" |
4358 | 4358 | ac_cs_version="\\ |
4359 | firejail config.status 0.9.44 | |
4359 | firejail config.status 0.9.44.2 | |
4360 | 4360 | configured by $0, generated by GNU Autoconf 2.69, |
4361 | 4361 | with options \\"\$ac_cs_config\\" |
4362 | 4362 |
0 | 0 | AC_PREREQ([2.68]) |
1 | AC_INIT(firejail, 0.9.44, netblue30@yahoo.com, , http://firejail.wordpress.com) | |
1 | AC_INIT(firejail, 0.9.44.2, netblue30@yahoo.com, , http://firejail.wordpress.com) | |
2 | 2 | AC_CONFIG_SRCDIR([src/firejail/main.c]) |
3 | 3 | #AC_CONFIG_HEADERS([config.h]) |
4 | 4 |
13 | 13 | seccomp |
14 | 14 | |
15 | 15 | shell none |
16 | private-bin deluge,sh,python,uname | |
17 | whitelist /tmp/.X11-unix | |
16 | #private-bin deluge,sh,python,uname | |
18 | 17 | private-dev |
19 | nosound | |
18 | private-tmp | |
20 | 19 |
0 | 0 | # git profile |
1 | ||
1 | quiet | |
2 | 2 | noblacklist ~/.gitconfig |
3 | 3 | noblacklist ~/.ssh |
4 | 4 | noblacklist ~/.gnupg |
11 | 11 | include /etc/firejail/disable-programs.inc |
12 | 12 | include /etc/firejail/disable-passwdmgr.inc |
13 | 13 | |
14 | quiet | |
15 | 14 | |
16 | 15 | caps.drop all |
17 | 16 | netfilter |
14 | 14 | shell none |
15 | 15 | tracelog |
16 | 16 | |
17 | private-bin mupdf | |
18 | 17 | private-tmp |
19 | 18 | private-dev |
19 | private-etc fonts | |
20 | 20 | |
21 | 21 | # mupdf will never write anything |
22 | 22 | read-only ${HOME} |
23 | 23 | |
24 | # | |
25 | # Experimental: | |
26 | # | |
27 | #seccomp.keep access,arch_prctl,brk,clone,close,connect,execve,exit_group,fchmod,fchown,fcntl,fstat,futex,getcwd,getpeername,getrlimit,getsockname,getsockopt,lseek,lstat,mlock,mmap,mprotect,mremap,munmap,nanosleep,open,poll,prctl,read,recvfrom,recvmsg,restart_syscall,rt_sigaction,rt_sigprocmask,select,sendmsg,set_robust_list,set_tid_address,setresgid,setresuid,shmat,shmctl,shmget,shutdown,socket,stat,sysinfo,uname,unshare,wait4,write,writev | |
28 | # private-bin mupdf,sh,tempfile,rm |
1 | 1 | quiet |
2 | 2 | noblacklist ~/.ssh |
3 | 3 | noblacklist /tmp/ssh-* |
4 | noblacklist /etc/ssh | |
4 | 5 | |
5 | 6 | include /etc/firejail/disable-common.inc |
6 | 7 | include /etc/firejail/disable-programs.inc |
5 | 5 | include /etc/firejail/disable-devel.inc |
6 | 6 | |
7 | 7 | netfilter |
8 | nonewprivs | |
9 | 8 | |
10 | 9 | whitelist ${DOWNLOADS} |
11 | 10 | mkdir ~/.config/vivaldi |
10 | 10 | nogroups |
11 | 11 | nonewprivs |
12 | 12 | noroot |
13 | protocol unix,inet,inet6 | |
13 | protocol unix,inet,inet6,netlink | |
14 | 14 | seccomp |
15 | 15 | shell none |
16 | 16 |
29 | 29 | mkdir ~/.config/dconf |
30 | 30 | whitelist ~/.config/dconf |
31 | 31 | |
32 | # qt | |
32 | # qt/kde | |
33 | 33 | whitelist ~/.config/kdeglobals |
34 | whitelist ~/.kde/share/config/oxygenrc | |
35 | whitelist ~/.kde/share/config/kdeglobals | |
36 | whitelist ~/.kde/share/icons |
0 | 0 | #!/bin/bash |
1 | VERSION="0.9.44" | |
1 | VERSION="0.9.44.2" | |
2 | 2 | rm -fr ~/rpmbuild |
3 | 3 | rm -f firejail-$VERSION-1.x86_64.rpm |
4 | 4 | |
457 | 457 | chmod u+s /usr/bin/firejail |
458 | 458 | |
459 | 459 | %changelog |
460 | * Sat Dec 3 2016 netblue30 <netblue30@yahoo.com> 0.9.44.2-1 | |
461 | - bugfix release | |
462 | ||
460 | 463 | * Fri Oct 21 2016 netblue30 <netblue30@yahoo.com> 0.9.44-1 |
461 | 464 | - CVE-2016-7545 submitted by Aleksey Manevich |
462 | 465 | - modifs: removed man firejail-config |
461 | 461 | arg[1] = "-c"; |
462 | 462 | arg[2] = cmd; |
463 | 463 | arg[3] = NULL; |
464 | clearenv(); | |
464 | 465 | execvp(arg[0], arg); |
465 | 466 | |
466 | 467 | // it will never get here |
496 | 496 | ptr = entry->data + 6; |
497 | 497 | op = MOUNT_TMPFS; |
498 | 498 | } |
499 | else if (strncmp(entry->data, "mkdir ", 6) == 0) { | |
500 | EUID_USER(); | |
501 | fs_mkdir(entry->data + 6); | |
502 | EUID_ROOT(); | |
503 | entry = entry->next; | |
504 | continue; | |
505 | } | |
506 | else if (strncmp(entry->data, "mkfile ", 7) == 0) { | |
507 | EUID_USER(); | |
508 | fs_mkfile(entry->data + 7); | |
509 | EUID_ROOT(); | |
510 | entry = entry->next; | |
511 | continue; | |
512 | } | |
499 | 513 | else { |
500 | 514 | fprintf(stderr, "Error: invalid profile line %s\n", entry->data); |
501 | 515 | entry = entry->next; |
190 | 190 | char *f; |
191 | 191 | if (asprintf(&f, "%s/%s", RUN_BIN_DIR, fname) == -1) |
192 | 192 | errExit("asprintf"); |
193 | clearenv(); | |
193 | 194 | execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", actual_path, f, NULL); |
194 | 195 | perror("execlp"); |
195 | 196 | _exit(1); |
104 | 104 | char *f; |
105 | 105 | if (asprintf(&f, "/etc/%s", fname) == -1) |
106 | 106 | errExit("asprintf"); |
107 | clearenv(); | |
107 | 108 | execlp(RUN_CP_COMMAND, RUN_CP_COMMAND, "-a", "--parents", f, RUN_MNT_DIR, NULL); |
108 | 109 | perror("execlp"); |
109 | 110 | _exit(1); |
323 | 323 | |
324 | 324 | // get file from sandbox and store it in the current directory |
325 | 325 | else if (op == SANDBOX_FS_GET) { |
326 | // check source file (sandbox) | |
327 | char *src_fname; | |
328 | if (asprintf(&src_fname, "%s%s", rootdir, fname1) == -1) | |
329 | errExit("asprintf"); | |
326 | char *src_fname =fname1; | |
327 | char *dest_fname = strrchr(fname1, '/'); | |
328 | if (!dest_fname || *(++dest_fname) == '\0') { | |
329 | fprintf(stderr, "Error: invalid file name %s\n", fname1); | |
330 | exit(1); | |
331 | } | |
332 | ||
330 | 333 | EUID_ROOT(); |
331 | struct stat s; | |
332 | if (stat(src_fname, &s) == -1) { | |
333 | fprintf(stderr, "Error: Cannot access %s\n", fname1); | |
334 | exit(1); | |
335 | } | |
336 | if (is_dir(src_fname)) { | |
337 | fprintf(stderr, "Error: source file name is a directory\n"); | |
338 | exit(1); | |
339 | } | |
340 | ||
341 | // try to open the source file - we need to chroot | |
334 | if (arg_debug) | |
335 | printf("copy %s to %s\n", src_fname, dest_fname); | |
336 | ||
337 | // create a user-owned temporary file in /run/firejail directory | |
338 | char tmp_fname[] = "/run/firejail/tmpget-XXXXXX"; | |
339 | int fd = mkstemp(tmp_fname); | |
340 | SET_PERMS_FD(fd, getuid(), getgid(), 0600); | |
341 | close(fd); | |
342 | ||
343 | // copy the source file into the temporary file - we need to chroot | |
342 | 344 | pid_t child = fork(); |
343 | 345 | if (child < 0) |
344 | 346 | errExit("fork"); |
352 | 354 | // drop privileges |
353 | 355 | drop_privs(0); |
354 | 356 | |
355 | // try to read the file | |
356 | if (access(fname1, R_OK) == -1) { | |
357 | fprintf(stderr, "Error: Cannot read %s\n", fname1); | |
358 | exit(1); | |
359 | } | |
357 | // copy the file | |
358 | if (copy_file(src_fname, tmp_fname, getuid(), getgid(), 0600)) | |
359 | _exit(1); | |
360 | 360 | _exit(0); |
361 | 361 | } |
362 | 362 | |
364 | 364 | int status = 0; |
365 | 365 | waitpid(child, &status, 0); |
366 | 366 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0); |
367 | else | |
368 | exit(1); | |
367 | else { | |
368 | unlink(tmp_fname); | |
369 | exit(1); | |
370 | } | |
371 | ||
372 | // copy the temporary file into the destionation file | |
373 | child = fork(); | |
374 | if (child < 0) | |
375 | errExit("fork"); | |
376 | if (child == 0) { | |
377 | // drop privileges | |
378 | drop_privs(0); | |
379 | ||
380 | // copy the file | |
381 | if (copy_file(tmp_fname, dest_fname, getuid(), getgid(), 0600)) | |
382 | _exit(1); | |
383 | _exit(0); | |
384 | } | |
385 | ||
386 | // wait for the child to finish | |
387 | status = 0; | |
388 | waitpid(child, &status, 0); | |
389 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0); | |
390 | else { | |
391 | unlink(tmp_fname); | |
392 | exit(1); | |
393 | } | |
394 | ||
395 | // remove the temporary file | |
396 | unlink(tmp_fname); | |
369 | 397 | EUID_USER(); |
370 | ||
371 | // check destination file (host) | |
372 | char *dest_fname = strrchr(fname1, '/'); | |
373 | if (!dest_fname || *(++dest_fname) == '\0') { | |
374 | fprintf(stderr, "Error: invalid file name %s\n", fname1); | |
375 | exit(1); | |
376 | } | |
377 | ||
378 | if (access(dest_fname, F_OK) == -1) { | |
379 | // try to create the file as a regular user | |
380 | pid_t child = fork(); | |
381 | if (child < 0) | |
382 | errExit("fork"); | |
383 | if (child == 0) { | |
384 | // drop privileges | |
385 | drop_privs(0); | |
386 | ||
387 | FILE *fp = fopen(dest_fname, "w"); | |
388 | if (!fp) { | |
389 | fprintf(stderr, "Error: cannot create %s\n", dest_fname); | |
390 | exit(1); | |
391 | } | |
392 | fclose(fp); | |
393 | _exit(0); | |
394 | } | |
395 | ||
396 | // wait for the child to finish | |
397 | int status = 0; | |
398 | waitpid(child, &status, 0); | |
399 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0); | |
400 | else | |
401 | exit(1); | |
402 | } | |
403 | else { | |
404 | if (access(dest_fname, W_OK) == -1) { | |
405 | fprintf(stderr, "Error: cannot write %s\n", dest_fname); | |
406 | exit(1); | |
407 | } | |
408 | } | |
409 | ||
410 | // copy file | |
398 | } | |
399 | ||
400 | // get file from host and store it in the sandbox | |
401 | else if (op == SANDBOX_FS_PUT && path2) { | |
402 | char *src_fname =fname1; | |
403 | char *dest_fname = fname2; | |
404 | ||
405 | EUID_ROOT(); | |
411 | 406 | if (arg_debug) |
412 | 407 | printf("copy %s to %s\n", src_fname, dest_fname); |
413 | EUID_ROOT(); | |
414 | if (copy_file(src_fname, dest_fname, getuid(), getgid(), 0644)) | |
415 | fprintf(stderr, "Error: transfer failed\n"); | |
416 | else | |
417 | printf("Transfer complete\n"); | |
418 | EUID_USER(); | |
419 | } | |
420 | // get file from host and store it in the sandbox | |
421 | else if (op == SANDBOX_FS_PUT && path2) { | |
422 | // verify the source file | |
423 | const char *src_fname = path1; | |
424 | struct stat s; | |
425 | if (stat(src_fname, &s) == -1) { | |
426 | fprintf(stderr, "Error: Cannot access %s\n", fname1); | |
427 | exit(1); | |
428 | } | |
429 | if (is_dir(src_fname)) { | |
430 | fprintf(stderr, "Error: source file name is a directory\n"); | |
431 | exit(1); | |
432 | } | |
433 | ||
434 | // try to open the source file | |
408 | ||
409 | // create a user-owned temporary file in /run/firejail directory | |
410 | char tmp_fname[] = "/run/firejail/tmpget-XXXXXX"; | |
411 | int fd = mkstemp(tmp_fname); | |
412 | SET_PERMS_FD(fd, getuid(), getgid(), 0600); | |
413 | close(fd); | |
414 | ||
415 | // copy the source file into the temporary file - we need to chroot | |
435 | 416 | pid_t child = fork(); |
436 | 417 | if (child < 0) |
437 | 418 | errExit("fork"); |
439 | 420 | // drop privileges |
440 | 421 | drop_privs(0); |
441 | 422 | |
442 | // try to read the file | |
443 | if (access(src_fname, R_OK) == -1) { | |
444 | fprintf(stderr, "Error: Cannot read %s\n", src_fname); | |
445 | exit(1); | |
446 | } | |
423 | // copy the file | |
424 | if (copy_file(src_fname, tmp_fname, getuid(), getgid(), 0600)) | |
425 | _exit(1); | |
447 | 426 | _exit(0); |
448 | 427 | } |
449 | 428 | |
451 | 430 | int status = 0; |
452 | 431 | waitpid(child, &status, 0); |
453 | 432 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0); |
454 | else | |
455 | exit(1); | |
456 | ||
457 | // check destination file (sandbox) | |
458 | char *dest_fname; | |
459 | if (asprintf(&dest_fname, "%s%s", rootdir, fname2) == -1) | |
460 | errExit("asprintf"); | |
461 | EUID_ROOT(); | |
462 | if (is_dir(dest_fname)) { | |
463 | fprintf(stderr, "Error: destination file name is a directory inside the sandbox\n"); | |
464 | exit(1); | |
465 | } | |
466 | ||
467 | // check write access on destination | |
433 | else { | |
434 | unlink(tmp_fname); | |
435 | exit(1); | |
436 | } | |
437 | ||
438 | // copy the temporary file into the destionation file | |
468 | 439 | child = fork(); |
469 | 440 | if (child < 0) |
470 | 441 | errExit("fork"); |
474 | 445 | errExit("chroot"); |
475 | 446 | if (chdir("/") < 0) |
476 | 447 | errExit("chdir"); |
477 | ||
448 | ||
478 | 449 | // drop privileges |
479 | 450 | drop_privs(0); |
480 | ||
481 | if (access(path2, F_OK) == -1) { | |
482 | FILE *fp = fopen(path2, "w"); | |
483 | if (!fp) { | |
484 | fprintf(stderr, "Error: cannot create %s\n", path2); | |
485 | exit(1); | |
486 | } | |
487 | fclose(fp); | |
488 | } | |
489 | else { | |
490 | if (access(path2, W_OK) == -1) { | |
491 | fprintf(stderr, "Error: cannot write %s\n", path2); | |
492 | exit(1); | |
493 | } | |
494 | } | |
495 | ||
451 | ||
452 | // copy the file | |
453 | if (copy_file(tmp_fname, dest_fname, getuid(), getgid(), 0600)) | |
454 | _exit(1); | |
496 | 455 | _exit(0); |
497 | 456 | } |
498 | 457 | |
500 | 459 | status = 0; |
501 | 460 | waitpid(child, &status, 0); |
502 | 461 | if (WIFEXITED(status) && WEXITSTATUS(status) == 0); |
503 | else | |
504 | exit(1); | |
505 | ||
506 | // copy file | |
507 | if (arg_debug) | |
508 | printf("copy %s to %s\n", src_fname, dest_fname); | |
509 | EUID_ROOT(); | |
510 | if (copy_file(src_fname, dest_fname, getuid(), getgid(), 0644)) | |
511 | fprintf(stderr, "Error: transfer failed\n"); | |
512 | else | |
513 | printf("Transfer complete\n"); | |
462 | else { | |
463 | unlink(tmp_fname); | |
464 | exit(1); | |
465 | } | |
466 | ||
467 | // remove the temporary file | |
468 | unlink(tmp_fname); | |
514 | 469 | EUID_USER(); |
515 | 470 | } |
516 | 471 |
1604 | 1604 | return 1; |
1605 | 1605 | } |
1606 | 1606 | |
1607 | // don't allow "--chroot=/" | |
1608 | char *rpath = realpath(cfg.chrootdir, NULL); | |
1609 | if (rpath == NULL || strcmp(rpath, "/") == 0) { | |
1610 | fprintf(stderr, "Error: invalid chroot directory\n"); | |
1611 | exit(1); | |
1612 | } | |
1613 | free(rpath); | |
1614 | ||
1607 | 1615 | // check chroot directory structure |
1608 | 1616 | if (fs_check_chroot_dir(cfg.chrootdir)) { |
1609 | 1617 | fprintf(stderr, "Error: invalid chroot\n"); |
1642 | 1650 | exit(1); |
1643 | 1651 | } |
1644 | 1652 | fs_check_private_dir(); |
1653 | ||
1654 | // downgrade to --private if the directory is the user home directory | |
1655 | if (strcmp(cfg.home_private, cfg.homedir) == 0) { | |
1656 | free(cfg.home_private); | |
1657 | cfg.home_private = NULL; | |
1658 | } | |
1645 | 1659 | arg_private = 1; |
1646 | 1660 | } |
1647 | 1661 | #ifdef HAVE_PRIVATE_HOME |
143 | 143 | |
144 | 144 | // wipe out environment variables |
145 | 145 | environ = NULL; |
146 | clearenv(); | |
146 | 147 | execl(iptables_restore, iptables_restore, NULL); |
147 | 148 | perror("execl"); |
148 | 149 | _exit(1); |
256 | 257 | |
257 | 258 | // wipe out environment variables |
258 | 259 | environ = NULL; |
260 | clearenv(); | |
259 | 261 | execl(ip6tables_restore, ip6tables_restore, NULL); |
260 | 262 | perror("execl"); |
261 | 263 | _exit(1); |
270 | 272 | errExit("fork"); |
271 | 273 | if (child == 0) { |
272 | 274 | environ = NULL; |
275 | clearenv(); | |
273 | 276 | execl(ip6tables, ip6tables, "-vL", NULL); |
274 | 277 | perror("execl"); |
275 | 278 | _exit(1); |
104 | 104 | // mkdir |
105 | 105 | if (strncmp(ptr, "mkdir ", 6) == 0) { |
106 | 106 | fs_mkdir(ptr + 6); |
107 | return 0; | |
107 | return 1; | |
108 | 108 | } |
109 | 109 | // mkfile |
110 | 110 | if (strncmp(ptr, "mkfile ", 7) == 0) { |
111 | 111 | fs_mkfile(ptr + 7); |
112 | return 0; | |
112 | return 1; | |
113 | 113 | } |
114 | 114 | // sandbox name |
115 | 115 | else if (strncmp(ptr, "name ", 5) == 0) { |
129 | 129 | #if HAVE_USERNS |
130 | 130 | if (checkcfg(CFG_USERNS)) |
131 | 131 | check_user_namespace(); |
132 | else | |
132 | else if (!arg_quiet) | |
133 | 133 | fprintf(stderr, "Warning: user namespace feature is disabled in Firejail configuration file\n"); |
134 | 134 | #endif |
135 | 135 | |
143 | 143 | #ifdef HAVE_SECCOMP |
144 | 144 | if (checkcfg(CFG_SECCOMP)) |
145 | 145 | arg_seccomp = 1; |
146 | else | |
146 | else if (!arg_quiet) | |
147 | 147 | fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); |
148 | 148 | #endif |
149 | 149 | return 0; |
175 | 175 | fs_check_home_list(); |
176 | 176 | arg_private = 1; |
177 | 177 | } |
178 | else | |
178 | else if (!arg_quiet) | |
179 | 179 | fprintf(stderr, "Warning: private-home is disabled in Firejail configuration file\n"); |
180 | 180 | #endif |
181 | 181 | return 0; |
208 | 208 | #ifdef HAVE_NETWORK |
209 | 209 | if (checkcfg(CFG_NETWORK)) |
210 | 210 | arg_netfilter = 1; |
211 | else | |
211 | else if (!arg_quiet) | |
212 | 212 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); |
213 | 213 | #endif |
214 | 214 | return 0; |
222 | 222 | errExit("strdup"); |
223 | 223 | check_netfilter_file(arg_netfilter_file); |
224 | 224 | } |
225 | else | |
225 | else if (!arg_quiet) | |
226 | 226 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); |
227 | 227 | #endif |
228 | 228 | return 0; |
236 | 236 | errExit("strdup"); |
237 | 237 | check_netfilter_file(arg_netfilter6_file); |
238 | 238 | } |
239 | else | |
239 | else if (!arg_quiet) | |
240 | 240 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); |
241 | 241 | #endif |
242 | 242 | return 0; |
254 | 254 | cfg.interface2.configured = 0; |
255 | 255 | cfg.interface3.configured = 0; |
256 | 256 | } |
257 | else | |
257 | else if (!arg_quiet) | |
258 | 258 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); |
259 | 259 | #endif |
260 | 260 | return 0; |
295 | 295 | } |
296 | 296 | net_configure_bridge(br, ptr + 4); |
297 | 297 | } |
298 | else | |
298 | else if (!arg_quiet) | |
299 | 299 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); |
300 | 300 | #endif |
301 | 301 | return 0; |
318 | 318 | exit(1); |
319 | 319 | } |
320 | 320 | } |
321 | else | |
321 | else if (!arg_quiet) | |
322 | 322 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); |
323 | 323 | #endif |
324 | 324 | return 0; |
363 | 363 | exit(1); |
364 | 364 | } |
365 | 365 | } |
366 | else | |
366 | else if (!arg_quiet) | |
367 | 367 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); |
368 | 368 | #endif |
369 | 369 | return 0; |
390 | 390 | exit(1); |
391 | 391 | } |
392 | 392 | } |
393 | else | |
393 | else if (!arg_quiet) | |
394 | 394 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); |
395 | 395 | #endif |
396 | 396 | return 0; |
410 | 410 | exit(1); |
411 | 411 | } |
412 | 412 | } |
413 | else | |
413 | else if (!arg_quiet) | |
414 | 414 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); |
415 | 415 | #endif |
416 | 416 | return 0; |
439 | 439 | } |
440 | 440 | } |
441 | 441 | } |
442 | else | |
442 | else if (!arg_quiet) | |
443 | 443 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); |
444 | 444 | #endif |
445 | 445 | return 0; |
467 | 467 | // } |
468 | 468 | |
469 | 469 | } |
470 | else | |
470 | else if (!arg_quiet) | |
471 | 471 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); |
472 | 472 | #endif |
473 | 473 | return 0; |
481 | 481 | exit(1); |
482 | 482 | } |
483 | 483 | } |
484 | else | |
484 | else if (!arg_quiet) | |
485 | 485 | fprintf(stderr, "Warning: networking features are disabled in Firejail configuration file\n"); |
486 | 486 | #endif |
487 | 487 | return 0; |
498 | 498 | #ifdef HAVE_SECCOMP |
499 | 499 | if (checkcfg(CFG_SECCOMP)) |
500 | 500 | protocol_store(ptr + 9); |
501 | else | |
501 | else if (!arg_quiet) | |
502 | 502 | fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); |
503 | 503 | #endif |
504 | 504 | return 0; |
522 | 522 | if (!cfg.seccomp_list) |
523 | 523 | errExit("strdup"); |
524 | 524 | } |
525 | else | |
525 | else if (!arg_quiet) | |
526 | 526 | fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); |
527 | 527 | #endif |
528 | 528 | |
538 | 538 | if (!cfg.seccomp_list_drop) |
539 | 539 | errExit("strdup"); |
540 | 540 | } |
541 | else | |
541 | else if (!arg_quiet) | |
542 | 542 | fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); |
543 | 543 | #endif |
544 | 544 | return 0; |
553 | 553 | if (!cfg.seccomp_list_keep) |
554 | 554 | errExit("strdup"); |
555 | 555 | } |
556 | else | |
556 | else if (!arg_quiet) | |
557 | 557 | fprintf(stderr, "Warning: user seccomp feature is disabled in Firejail configuration file\n"); |
558 | 558 | #endif |
559 | 559 | return 0; |
779 | 779 | *(dname2 - 1) = ','; |
780 | 780 | return 1; |
781 | 781 | } |
782 | else { | |
782 | else if (!arg_quiet) { | |
783 | 783 | fprintf(stderr, "Warning: bind feature is disabled in Firejail configuration file\n"); |
784 | 784 | return 0; |
785 | 785 | } |
295 | 295 | void start_application(void) { |
296 | 296 | //if (setsid() == -1) |
297 | 297 | //errExit("setsid"); |
298 | ||
299 | // set environment | |
300 | env_defaults(); | |
301 | env_apply(); | |
302 | if (arg_debug) { | |
303 | printf("starting application\n"); | |
304 | printf("LD_PRELOAD=%s\n", getenv("LD_PRELOAD")); | |
305 | } | |
306 | ||
298 | 307 | //**************************************** |
299 | 308 | // audit |
300 | 309 | //**************************************** |
775 | 784 | } |
776 | 785 | } |
777 | 786 | |
778 | // set environment | |
779 | env_defaults(); | |
780 | ||
781 | // set user-supplied environment variables | |
782 | env_apply(); | |
783 | ||
784 | 787 | // set nice |
785 | 788 | if (arg_nice) { |
786 | 789 | errno = 0; |
252 | 252 | } |
253 | 253 | |
254 | 254 | for (i = 0; i < (int) strlen(xephyr_extra_params)-1; i++) { |
255 | if (pos >= (sizeof(server_argv)/sizeof(*server_argv))) { | |
255 | if (pos >= (sizeof(server_argv)/sizeof(*server_argv)) - 2) { | |
256 | 256 | fprintf(stderr, "Error: arg count limit exceeded while parsing xephyr_extra_params\n"); |
257 | 257 | exit(1); |
258 | 258 | } |
310 | 310 | if (server == 0) { |
311 | 311 | if (arg_debug) |
312 | 312 | printf("Starting xephyr...\n"); |
313 | ||
313 | ||
314 | // running without privileges - see drop_privs call above | |
315 | assert(getenv("LD_PRELOAD") == NULL); | |
314 | 316 | execvp(server_argv[0], server_argv); |
315 | 317 | perror("execvp"); |
316 | 318 | _exit(1); |
352 | 354 | if (!arg_quiet) |
353 | 355 | printf("\n*** Attaching to Xephyr display %d ***\n\n", display); |
354 | 356 | |
357 | // running without privileges - see drop_privs call above | |
358 | assert(getenv("LD_PRELOAD") == NULL); | |
355 | 359 | execvp(jail_argv[0], jail_argv); |
356 | 360 | perror("execvp"); |
357 | 361 | _exit(1); |
431 | 435 | dup2(fd_null,2); |
432 | 436 | } |
433 | 437 | |
438 | // running without privileges - see drop_privs call above | |
439 | assert(getenv("LD_PRELOAD") == NULL); | |
434 | 440 | execvp(server_argv[0], server_argv); |
435 | 441 | perror("execvp"); |
436 | 442 | _exit(1); |
477 | 483 | if (!arg_quiet) |
478 | 484 | printf("\n*** Attaching to xpra display %d ***\n\n", display); |
479 | 485 | |
486 | // running without privileges - see drop_privs call above | |
487 | assert(getenv("LD_PRELOAD") == NULL); | |
480 | 488 | execvp(attach_argv[0], attach_argv); |
481 | 489 | perror("execvp"); |
482 | 490 | _exit(1); |
507 | 515 | if (jail < 0) |
508 | 516 | errExit("fork"); |
509 | 517 | if (jail == 0) { |
518 | // running without privileges - see drop_privs call above | |
519 | assert(getenv("LD_PRELOAD") == NULL); | |
510 | 520 | if (firejail_argv[0]) // shut up llvm scan-build |
511 | 521 | execvp(firejail_argv[0], firejail_argv); |
512 | 522 | perror("execvp"); |
533 | 543 | dup2(fd_null,1); |
534 | 544 | dup2(fd_null,2); |
535 | 545 | } |
546 | // running without privileges - see drop_privs call above | |
547 | assert(getenv("LD_PRELOAD") == NULL); | |
536 | 548 | execvp(stop_argv[0], stop_argv); |
537 | 549 | perror("execvp"); |
538 | 550 | _exit(1); |
631 | 643 | |
632 | 644 | void x11_xorg(void) { |
633 | 645 | #ifdef HAVE_X11 |
634 | // destination | |
646 | // destination - create an empty ~/.Xauthotrity file if it doesn't exist already, and use it as a mount point | |
635 | 647 | char *dest; |
636 | 648 | if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1) |
637 | 649 | errExit("asprintf"); |
645 | 657 | fclose(fp); |
646 | 658 | } |
647 | 659 | |
660 | // check xauth utility is present in the system | |
648 | 661 | if (stat("/usr/bin/xauth", &s) == -1) { |
649 | 662 | fprintf(stderr, "Error: cannot find /usr/bin/xauth executable\n"); |
650 | 663 | exit(1); |
651 | 664 | } |
665 | ||
666 | // create a temporary .Xauthority file | |
667 | char tmpfname[] = "/tmp/.tmpXauth-XXXXXX"; | |
668 | int fd = mkstemp(tmpfname); | |
669 | if (fd == -1) { | |
670 | fprintf(stderr, "Error: cannot create .Xauthority file\n"); | |
671 | exit(1); | |
672 | } | |
673 | close(fd); | |
674 | if (chown(tmpfname, getuid(), getgid()) == -1) | |
675 | errExit("chown"); | |
652 | 676 | |
653 | 677 | pid_t child = fork(); |
654 | 678 | if (child < 0) |
655 | 679 | errExit("fork"); |
656 | 680 | if (child == 0) { |
657 | // generate a new .Xauthority file | |
681 | // generate the new .Xauthority file using xauth utility | |
658 | 682 | if (arg_debug) |
659 | 683 | printf("Generating a new .Xauthority file\n"); |
660 | ||
661 | // elevate privileges - files in /run/firejail/mnt directory belong to root | |
662 | if (setreuid(0, 0) < 0) | |
663 | errExit("setreuid"); | |
664 | if (setregid(0, 0) < 0) | |
665 | errExit("setregid"); | |
666 | ||
684 | drop_privs(1); | |
685 | ||
667 | 686 | char *display = getenv("DISPLAY"); |
668 | 687 | if (!display) |
669 | 688 | display = ":0.0"; |
670 | ||
671 | execlp("/usr/bin/xauth", "/usr/bin/xauth", "-f", RUN_XAUTHORITY_SEC_FILE, | |
689 | ||
690 | clearenv(); | |
691 | execlp("/usr/bin/xauth", "/usr/bin/xauth", "-f", tmpfname, | |
672 | 692 | "generate", display, "MIT-MAGIC-COOKIE-1", "untrusted", NULL); |
673 | 693 | |
674 | 694 | _exit(0); |
675 | 695 | } |
696 | ||
676 | 697 | // wait for the child to finish |
677 | 698 | waitpid(child, NULL, 0); |
678 | 699 | |
679 | 700 | // check the file was created and set mode and ownership |
680 | if (stat(RUN_XAUTHORITY_SEC_FILE, &s) == -1) { | |
701 | if (stat(tmpfname, &s) == -1) { | |
681 | 702 | fprintf(stderr, "Error: cannot create the new .Xauthority file\n"); |
703 | exit(1); | |
704 | } | |
705 | if (chown(tmpfname, getuid(), getgid()) == -1) | |
706 | errExit("chown"); | |
707 | if (chmod(tmpfname, 0600) == -1) | |
708 | errExit("chmod"); | |
709 | ||
710 | // move the temporary file in RUN_XAUTHORITY_SEC_FILE in order to have it deleted | |
711 | // automatically when the sandbox is closed | |
712 | if (copy_file(tmpfname, RUN_XAUTHORITY_SEC_FILE, getuid(), getgid(), 0600)) { | |
713 | fprintf(stderr, "asdfdsfError: cannot create the new .Xauthority file\n"); | |
682 | 714 | exit(1); |
683 | 715 | } |
684 | 716 | if (chown(RUN_XAUTHORITY_SEC_FILE, getuid(), getgid()) == -1) |
685 | 717 | errExit("chown"); |
686 | 718 | if (chmod(RUN_XAUTHORITY_SEC_FILE, 0600) == -1) |
687 | 719 | errExit("chmod"); |
720 | unlink(tmpfname); | |
688 | 721 | |
689 | 722 | // mount |
690 | 723 | if (mount(RUN_XAUTHORITY_SEC_FILE, dest, "none", MS_BIND, "mode=0600") == -1) { |
1856 | 1856 | .TP |
1857 | 1857 | \fB\-\-get=name|pid filename |
1858 | 1858 | Retrieve the container file and store it on the host in the current working directory. |
1859 | The container is specified by name or PID. | |
1859 | The container is specified by name or PID. This option is not available for sandboxes | |
1860 | using --chroot. | |
1860 | 1861 | |
1861 | 1862 | .TP |
1862 | 1863 | \fB\-\-ls=name|pid dir_or_filename |
1865 | 1866 | .TP |
1866 | 1867 | \fB\-\-put=name|pid src-filename dest-filename |
1867 | 1868 | Put src-filename in sandbox container. |
1868 | The container is specified by name or PID. | |
1869 | The container is specified by name or PID. This option is not available for sandboxes | |
1870 | using --chroot. | |
1869 | 1871 | |
1870 | 1872 | .TP |
1871 | 1873 | Examples: |