diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fbuilder/build_home.c | 2 | ||||
-rw-r--r-- | src/fbuilder/build_profile.c | 26 | ||||
-rw-r--r-- | src/firecfg/firecfg.config | 4 | ||||
-rw-r--r-- | src/firejail/fs_lib.c | 2 | ||||
-rw-r--r-- | src/firejail/join.c | 10 | ||||
-rw-r--r-- | src/firejail/util.c | 31 | ||||
-rw-r--r-- | src/lib/syscall.c | 1 | ||||
-rw-r--r-- | src/man/firejail-profile.txt | 5 | ||||
-rw-r--r-- | src/man/firejail.txt | 2 |
9 files changed, 47 insertions, 36 deletions
diff --git a/src/fbuilder/build_home.c b/src/fbuilder/build_home.c index fca3396c4..c0f4a3407 100644 --- a/src/fbuilder/build_home.c +++ b/src/fbuilder/build_home.c | |||
@@ -24,7 +24,7 @@ static FileDB *db_skip = NULL; | |||
24 | static FileDB *db_out = NULL; | 24 | static FileDB *db_out = NULL; |
25 | 25 | ||
26 | static void load_whitelist_common(void) { | 26 | static void load_whitelist_common(void) { |
27 | FILE *fp = fopen("/etc/firejail/whitelist-common.inc", "r"); | 27 | FILE *fp = fopen(SYSCONFDIR "/whitelist-common.inc", "r"); |
28 | if (!fp) { | 28 | if (!fp) { |
29 | fprintf(stderr, "Error: cannot open whitelist-common.inc\n"); | 29 | fprintf(stderr, "Error: cannot open whitelist-common.inc\n"); |
30 | exit(1); | 30 | exit(1); |
diff --git a/src/fbuilder/build_profile.c b/src/fbuilder/build_profile.c index adc00e67b..0517c837e 100644 --- a/src/fbuilder/build_profile.c +++ b/src/fbuilder/build_profile.c | |||
@@ -80,10 +80,19 @@ void build_profile(int argc, char **argv, int index, FILE *fp) { | |||
80 | stroutput, | 80 | stroutput, |
81 | }; | 81 | }; |
82 | 82 | ||
83 | // detect strace | 83 | // detect strace and check if Yama LSM allows us to use it |
84 | int have_strace = 0; | 84 | int have_strace = 0; |
85 | if (access("/usr/bin/strace", X_OK) == 0) | 85 | int have_yama_permission = 1; |
86 | if (access("/usr/bin/strace", X_OK) == 0) { | ||
86 | have_strace = 1; | 87 | have_strace = 1; |
88 | FILE *fp = fopen("/proc/sys/kernel/yama/ptrace_scope", "r"); | ||
89 | if (fp) { | ||
90 | unsigned val; | ||
91 | if (fscanf(fp, "%u", &val) == 1) | ||
92 | have_yama_permission = (val < 2); | ||
93 | fclose(fp); | ||
94 | } | ||
95 | } | ||
87 | 96 | ||
88 | // calculate command length | 97 | // calculate command length |
89 | unsigned len = (int) sizeof(cmdlist) / sizeof(char*) + argc - index + 1; | 98 | unsigned len = (int) sizeof(cmdlist) / sizeof(char*) + argc - index + 1; |
@@ -93,10 +102,11 @@ void build_profile(int argc, char **argv, int index, FILE *fp) { | |||
93 | cmd[0] = cmdlist[0]; // explicit assignment to clean scan-build error | 102 | cmd[0] = cmdlist[0]; // explicit assignment to clean scan-build error |
94 | 103 | ||
95 | // build command | 104 | // build command |
105 | int skip_strace = !(have_strace && have_yama_permission); | ||
96 | unsigned i = 0; | 106 | unsigned i = 0; |
97 | for (i = 0; i < (int) sizeof(cmdlist) / sizeof(char*); i++) { | 107 | for (i = 0; i < (int) sizeof(cmdlist) / sizeof(char*); i++) { |
98 | // skip strace if not installed | 108 | // skip strace if not installed, or no permission to use it |
99 | if (have_strace == 0 && strcmp(cmdlist[i], "/usr/bin/strace") == 0) | 109 | if (skip_strace && strcmp(cmdlist[i], "/usr/bin/strace") == 0) |
100 | break; | 110 | break; |
101 | cmd[i] = cmdlist[i]; | 111 | cmd[i] = cmdlist[i]; |
102 | } | 112 | } |
@@ -172,12 +182,14 @@ void build_profile(int argc, char **argv, int index, FILE *fp) { | |||
172 | fprintf(fp, "caps.drop all\n"); | 182 | fprintf(fp, "caps.drop all\n"); |
173 | fprintf(fp, "nonewprivs\n"); | 183 | fprintf(fp, "nonewprivs\n"); |
174 | fprintf(fp, "seccomp\n"); | 184 | fprintf(fp, "seccomp\n"); |
175 | if (have_strace) | 185 | if (!have_strace) { |
176 | build_seccomp(strace_output, fp); | ||
177 | else { | ||
178 | fprintf(fp, "# If you install strace on your system, Firejail will also create a\n"); | 186 | fprintf(fp, "# If you install strace on your system, Firejail will also create a\n"); |
179 | fprintf(fp, "# whitelisted seccomp filter.\n"); | 187 | fprintf(fp, "# whitelisted seccomp filter.\n"); |
180 | } | 188 | } |
189 | else if (!have_yama_permission) | ||
190 | fprintf(fp, "# Yama security module prevents creation of a whitelisted seccomp filter\n"); | ||
191 | else | ||
192 | build_seccomp(strace_output, fp); | ||
181 | fprintf(fp, "\n"); | 193 | fprintf(fp, "\n"); |
182 | 194 | ||
183 | fprintf(fp, "### network\n"); | 195 | fprintf(fp, "### network\n"); |
diff --git a/src/firecfg/firecfg.config b/src/firecfg/firecfg.config index 23b1e364a..109f89f39 100644 --- a/src/firecfg/firecfg.config +++ b/src/firecfg/firecfg.config | |||
@@ -455,6 +455,7 @@ macrofusion | |||
455 | magicor | 455 | magicor |
456 | # man | 456 | # man |
457 | manaplus | 457 | manaplus |
458 | marker | ||
458 | masterpdfeditor | 459 | masterpdfeditor |
459 | masterpdfeditor4 | 460 | masterpdfeditor4 |
460 | masterpdfeditor5 | 461 | masterpdfeditor5 |
@@ -621,6 +622,7 @@ qemu-launcher | |||
621 | qgis | 622 | qgis |
622 | qlipper | 623 | qlipper |
623 | qmmp | 624 | qmmp |
625 | qnapi | ||
624 | qpdfview | 626 | qpdfview |
625 | qt-faststart | 627 | qt-faststart |
626 | qtox | 628 | qtox |
@@ -662,6 +664,7 @@ secret-tool | |||
662 | shellcheck | 664 | shellcheck |
663 | shortwave | 665 | shortwave |
664 | shotcut | 666 | shotcut |
667 | shotwell | ||
665 | signal-cli | 668 | signal-cli |
666 | signal-desktop | 669 | signal-desktop |
667 | silentarmy | 670 | silentarmy |
@@ -771,6 +774,7 @@ tremulous | |||
771 | trojita | 774 | trojita |
772 | truecraft | 775 | truecraft |
773 | tshark | 776 | tshark |
777 | tutanota-desktop | ||
774 | tuxguitar | 778 | tuxguitar |
775 | tvbrowser | 779 | tvbrowser |
776 | twitch | 780 | twitch |
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c index 941d6ad82..b76999d8f 100644 --- a/src/firejail/fs_lib.c +++ b/src/firejail/fs_lib.c | |||
@@ -165,7 +165,7 @@ void fslib_copy_dir(const char *full_path) { | |||
165 | mkdir_attr(dest, 0755, 0, 0); | 165 | mkdir_attr(dest, 0755, 0, 0); |
166 | 166 | ||
167 | if (mount(full_path, dest, NULL, MS_BIND|MS_REC, NULL) < 0 || | 167 | if (mount(full_path, dest, NULL, MS_BIND|MS_REC, NULL) < 0 || |
168 | mount(NULL, dest, NULL, MS_BIND|MS_REMOUNT|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0) | 168 | mount(NULL, dest, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NOSUID|MS_NODEV|MS_REC, NULL) < 0) |
169 | errExit("mount bind"); | 169 | errExit("mount bind"); |
170 | fs_logger2("clone", full_path); | 170 | fs_logger2("clone", full_path); |
171 | fs_logger2("mount", full_path); | 171 | fs_logger2("mount", full_path); |
diff --git a/src/firejail/join.c b/src/firejail/join.c index d2f802add..4f0210f95 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c | |||
@@ -296,7 +296,7 @@ static void extract_umask(pid_t pid) { | |||
296 | fprintf(stderr, "Error: cannot open umask file\n"); | 296 | fprintf(stderr, "Error: cannot open umask file\n"); |
297 | exit(1); | 297 | exit(1); |
298 | } | 298 | } |
299 | if (fscanf(fp, "%o", &orig_umask) != 1) { | 299 | if (fscanf(fp, "%3o", &orig_umask) != 1) { |
300 | fprintf(stderr, "Error: cannot read umask\n"); | 300 | fprintf(stderr, "Error: cannot read umask\n"); |
301 | exit(1); | 301 | exit(1); |
302 | } | 302 | } |
@@ -335,7 +335,7 @@ bool is_ready_for_join(const pid_t pid) { | |||
335 | struct stat s; | 335 | struct stat s; |
336 | if (fstat(fd, &s) == -1) | 336 | if (fstat(fd, &s) == -1) |
337 | errExit("fstat"); | 337 | errExit("fstat"); |
338 | if (!S_ISREG(s.st_mode) || s.st_uid != 0) { | 338 | if (!S_ISREG(s.st_mode) || s.st_uid != 0 || s.st_size != 1) { |
339 | close(fd); | 339 | close(fd); |
340 | return false; | 340 | return false; |
341 | } | 341 | } |
@@ -411,7 +411,7 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
411 | extract_x11_display(parent); | 411 | extract_x11_display(parent); |
412 | 412 | ||
413 | int shfd = -1; | 413 | int shfd = -1; |
414 | if (!arg_shell_none) | 414 | if (!arg_shell_none && !arg_audit) |
415 | shfd = open_shell(); | 415 | shfd = open_shell(); |
416 | 416 | ||
417 | EUID_ROOT(); | 417 | EUID_ROOT(); |
@@ -423,6 +423,7 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
423 | extract_cgroup(pid); | 423 | extract_cgroup(pid); |
424 | extract_nogroups(pid); | 424 | extract_nogroups(pid); |
425 | extract_user_namespace(pid); | 425 | extract_user_namespace(pid); |
426 | extract_umask(pid); | ||
426 | #ifdef HAVE_APPARMOR | 427 | #ifdef HAVE_APPARMOR |
427 | extract_apparmor(pid); | 428 | extract_apparmor(pid); |
428 | #endif | 429 | #endif |
@@ -432,9 +433,6 @@ void join(pid_t pid, int argc, char **argv, int index) { | |||
432 | if (cfg.cgroup) // not available for uid 0 | 433 | if (cfg.cgroup) // not available for uid 0 |
433 | set_cgroup(cfg.cgroup); | 434 | set_cgroup(cfg.cgroup); |
434 | 435 | ||
435 | // set umask, also uid 0 | ||
436 | extract_umask(pid); | ||
437 | |||
438 | // join namespaces | 436 | // join namespaces |
439 | if (arg_join_network) { | 437 | if (arg_join_network) { |
440 | if (join_namespace(pid, "net")) | 438 | if (join_namespace(pid, "net")) |
diff --git a/src/firejail/util.c b/src/firejail/util.c index 0b095e1be..911c8bd94 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -565,27 +565,18 @@ char *clean_pathname(const char *path) { | |||
565 | if (!rv) | 565 | if (!rv) |
566 | errExit("malloc"); | 566 | errExit("malloc"); |
567 | 567 | ||
568 | if (len > 0) { | 568 | size_t i = 0; |
569 | size_t i = 0, j = 0, cnt = 0; | 569 | size_t j = 0; |
570 | for (; i < len; i++) { | 570 | while (path[i]) { |
571 | if (path[i] == '/') | 571 | while (path[i] == '/' && path[i+1] == '/') |
572 | cnt++; | 572 | i++; |
573 | else | 573 | rv[j++] = path[i++]; |
574 | cnt = 0; | ||
575 | |||
576 | if (cnt < 2) { | ||
577 | rv[j] = path[i]; | ||
578 | j++; | ||
579 | } | ||
580 | } | ||
581 | rv[j] = '\0'; | ||
582 | |||
583 | // remove a trailing slash | ||
584 | if (j > 1 && rv[j - 1] == '/') | ||
585 | rv[j - 1] = '\0'; | ||
586 | } | 574 | } |
587 | else | 575 | rv[j] = '\0'; |
588 | *rv = '\0'; | 576 | |
577 | // remove a trailing slash | ||
578 | if (j > 1 && rv[j - 1] == '/') | ||
579 | rv[j - 1] = '\0'; | ||
589 | 580 | ||
590 | return rv; | 581 | return rv; |
591 | } | 582 | } |
diff --git a/src/lib/syscall.c b/src/lib/syscall.c index 4903971ad..6823d0ae6 100644 --- a/src/lib/syscall.c +++ b/src/lib/syscall.c | |||
@@ -336,6 +336,7 @@ static const SyscallGroupList sysgroups[] = { | |||
336 | #endif | 336 | #endif |
337 | }, | 337 | }, |
338 | { .name = "@default-keep", .list = | 338 | { .name = "@default-keep", .list = |
339 | "execveat," // commonly used by fexecve | ||
339 | "execve," | 340 | "execve," |
340 | "prctl" | 341 | "prctl" |
341 | }, | 342 | }, |
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt index 9524254c1..030a3c95c 100644 --- a/src/man/firejail-profile.txt +++ b/src/man/firejail-profile.txt | |||
@@ -862,6 +862,11 @@ the parent interface specified by --net is not configured. An IP address and | |||
862 | a default gateway address also have to be added. | 862 | a default gateway address also have to be added. |
863 | 863 | ||
864 | .TP | 864 | .TP |
865 | \fBnetns namespace | ||
866 | Run the program in a named, persistent network namespace. These can | ||
867 | be created and configured using "ip netns". | ||
868 | |||
869 | .TP | ||
865 | \fBveth-name name | 870 | \fBveth-name name |
866 | Use this name for the interface connected to the bridge for --net=bridge_interface commands, | 871 | Use this name for the interface connected to the bridge for --net=bridge_interface commands, |
867 | instead of the default one. | 872 | instead of the default one. |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index 347e2b31b..e72ef48c2 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -2273,7 +2273,7 @@ rm: cannot remove `testfile': Operation not permitted | |||
2273 | .TP | 2273 | .TP |
2274 | \fB\-\-seccomp.keep=syscall,@group,!syscall2 | 2274 | \fB\-\-seccomp.keep=syscall,@group,!syscall2 |
2275 | Enable seccomp filter, blacklist all syscall not listed and "syscall2". | 2275 | Enable seccomp filter, blacklist all syscall not listed and "syscall2". |
2276 | The system calls needed by Firejail (group @default-keep: prctl, execve) | 2276 | The system calls needed by Firejail (group @default-keep: prctl, execve, execveat) |
2277 | are handled with the preload library. On a 64 bit architecture, an | 2277 | are handled with the preload library. On a 64 bit architecture, an |
2278 | additional filter for 32 bit system calls can be installed with | 2278 | additional filter for 32 bit system calls can be installed with |
2279 | \-\-seccomp.32.keep. | 2279 | \-\-seccomp.32.keep. |