diff options
-rw-r--r-- | contrib/vim/syntax/firejail.vim | 2 | ||||
-rw-r--r-- | etc/profile-a-l/akregator.profile | 1 | ||||
-rw-r--r-- | etc/profile-a-l/default.profile | 1 | ||||
-rw-r--r-- | etc/profile-a-l/dillo.profile | 2 | ||||
-rw-r--r-- | etc/profile-a-l/ktorrent.profile | 1 | ||||
-rw-r--r-- | etc/profile-m-z/server.profile | 1 | ||||
-rw-r--r-- | etc/templates/profile.template | 1 | ||||
-rw-r--r-- | src/firejail/firejail.h | 1 | ||||
-rw-r--r-- | src/firejail/main.c | 4 | ||||
-rw-r--r-- | src/firejail/profile.c | 5 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 21 | ||||
-rw-r--r-- | src/firejail/usage.c | 1 | ||||
-rw-r--r-- | src/man/firejail-profile.txt | 5 | ||||
-rw-r--r-- | src/man/firejail.txt | 6 | ||||
-rw-r--r-- | src/zsh_completion/_firejail.in | 1 |
15 files changed, 40 insertions, 13 deletions
diff --git a/contrib/vim/syntax/firejail.vim b/contrib/vim/syntax/firejail.vim index fa80a9c00..bcaa85a9c 100644 --- a/contrib/vim/syntax/firejail.vim +++ b/contrib/vim/syntax/firejail.vim | |||
@@ -51,7 +51,7 @@ syn match fjVar /\v\$\{(CFG|DESKTOP|DOCUMENTS|DOWNLOADS|HOME|MUSIC|PATH|PICTURES | |||
51 | " Generate list with: { rg -o 'strn?cmp\(ptr, "([^"]+) "' -r '$1' src/firejail/profile.c; echo private-lib; } | grep -vEx '(include|ignore|caps\.drop|caps\.keep|protocol|seccomp|seccomp\.drop|seccomp\.keep|env|rmenv|net|ip)' | sort -u | tr $'\n' '|' # private-lib is special-cased in the code and doesn't match the regex; grep-ed patterns are handled later with 'syn match nextgroup=' directives (except for include which is special-cased as a fjCommandNoCond keyword) | 51 | " Generate list with: { rg -o 'strn?cmp\(ptr, "([^"]+) "' -r '$1' src/firejail/profile.c; echo private-lib; } | grep -vEx '(include|ignore|caps\.drop|caps\.keep|protocol|seccomp|seccomp\.drop|seccomp\.keep|env|rmenv|net|ip)' | sort -u | tr $'\n' '|' # private-lib is special-cased in the code and doesn't match the regex; grep-ed patterns are handled later with 'syn match nextgroup=' directives (except for include which is special-cased as a fjCommandNoCond keyword) |
52 | syn match fjCommand /\v(bind|blacklist|blacklist-nolog|cgroup|cpu|defaultgw|dns|hostname|hosts-file|ip6|iprange|join-or-start|mac|mkdir|mkfile|mtu|name|netfilter|netfilter6|netmask|nice|noblacklist|noexec|nowhitelist|overlay-named|private|private-bin|private-cwd|private-etc|private-home|private-lib|private-opt|private-srv|read-only|read-write|rlimit-as|rlimit-cpu|rlimit-fsize|rlimit-nofile|rlimit-nproc|rlimit-sigpending|timeout|tmpfs|veth-name|whitelist|xephyr-screen) / skipwhite contained | 52 | syn match fjCommand /\v(bind|blacklist|blacklist-nolog|cgroup|cpu|defaultgw|dns|hostname|hosts-file|ip6|iprange|join-or-start|mac|mkdir|mkfile|mtu|name|netfilter|netfilter6|netmask|nice|noblacklist|noexec|nowhitelist|overlay-named|private|private-bin|private-cwd|private-etc|private-home|private-lib|private-opt|private-srv|read-only|read-write|rlimit-as|rlimit-cpu|rlimit-fsize|rlimit-nofile|rlimit-nproc|rlimit-sigpending|timeout|tmpfs|veth-name|whitelist|xephyr-screen) / skipwhite contained |
53 | " Generate list with: rg -o 'strn?cmp\(ptr, "([^ "]*[^ ])"' -r '$1' src/firejail/profile.c | grep -vEx '(include|rlimit|quiet)' | sed -e 's/\./\\./' | sort -u | tr $'\n' '|' # include/rlimit are false positives, quiet is special-cased below | 53 | " Generate list with: rg -o 'strn?cmp\(ptr, "([^ "]*[^ ])"' -r '$1' src/firejail/profile.c | grep -vEx '(include|rlimit|quiet)' | sed -e 's/\./\\./' | sort -u | tr $'\n' '|' # include/rlimit are false positives, quiet is special-cased below |
54 | syn match fjCommand /\v(allow-debuggers|allusers|apparmor|caps|disable-mnt|ipc-namespace|keep-config-pulse|keep-dev-shm|keep-var-tmp|machine-id|memory-deny-write-execute|netfilter|no3d|noautopulse|nodbus|nodvd|nogroups|noinput|nonewprivs|noroot|nosound|notv|nou2f|novideo|overlay|overlay-tmpfs|private|private-cache|private-cwd|private-dev|private-lib|private-tmp|seccomp|seccomp\.32|seccomp\.block-secondary|tracelog|writable-etc|writable-run-user|writable-var|writable-var-log|x11)$/ contained | 54 | syn match fjCommand /\v(allow-debuggers|allusers|apparmor|caps|deterministic-exit-code|deterministic-shutdown|disable-mnt|ipc-namespace|keep-config-pulse|keep-dev-shm|keep-var-tmp|machine-id|memory-deny-write-execute|netfilter|no3d|noautopulse|nodbus|nodvd|nogroups|noinput|nonewprivs|noroot|nosound|notv|nou2f|novideo|overlay|overlay-tmpfs|private|private-cache|private-cwd|private-dev|private-lib|private-tmp|seccomp|seccomp\.32|seccomp\.block-secondary|tracelog|writable-etc|writable-run-user|writable-var|writable-var-log|x11)$/ contained |
55 | syn match fjCommand /ignore / nextgroup=fjCommand,fjCommandNoCond skipwhite contained | 55 | syn match fjCommand /ignore / nextgroup=fjCommand,fjCommandNoCond skipwhite contained |
56 | syn match fjCommand /caps\.drop / nextgroup=fjCapability,fjAll skipwhite contained | 56 | syn match fjCommand /caps\.drop / nextgroup=fjCapability,fjAll skipwhite contained |
57 | syn match fjCommand /caps\.keep / nextgroup=fjCapability skipwhite contained | 57 | syn match fjCommand /caps\.keep / nextgroup=fjCapability skipwhite contained |
diff --git a/etc/profile-a-l/akregator.profile b/etc/profile-a-l/akregator.profile index 39008d67a..47468a658 100644 --- a/etc/profile-a-l/akregator.profile +++ b/etc/profile-a-l/akregator.profile | |||
@@ -49,3 +49,4 @@ private-bin akregator,akregatorstorageexporter,dbus-launch,kdeinit4,kdeinit4_shu | |||
49 | private-dev | 49 | private-dev |
50 | private-tmp | 50 | private-tmp |
51 | 51 | ||
52 | deterministic-shutdown | ||
diff --git a/etc/profile-a-l/default.profile b/etc/profile-a-l/default.profile index 0d8c224d7..dac842bb6 100644 --- a/etc/profile-a-l/default.profile +++ b/etc/profile-a-l/default.profile | |||
@@ -57,5 +57,6 @@ seccomp | |||
57 | # dbus-user none | 57 | # dbus-user none |
58 | # dbus-system none | 58 | # dbus-system none |
59 | 59 | ||
60 | # deterministic-shutdown | ||
60 | # memory-deny-write-execute | 61 | # memory-deny-write-execute |
61 | # read-only ${HOME} | 62 | # read-only ${HOME} |
diff --git a/etc/profile-a-l/dillo.profile b/etc/profile-a-l/dillo.profile index 276ee251a..19b99b5fd 100644 --- a/etc/profile-a-l/dillo.profile +++ b/etc/profile-a-l/dillo.profile | |||
@@ -35,3 +35,5 @@ tracelog | |||
35 | 35 | ||
36 | private-dev | 36 | private-dev |
37 | private-tmp | 37 | private-tmp |
38 | |||
39 | deterministic-shutdown | ||
diff --git a/etc/profile-a-l/ktorrent.profile b/etc/profile-a-l/ktorrent.profile index 6e3b0c875..f3eae6780 100644 --- a/etc/profile-a-l/ktorrent.profile +++ b/etc/profile-a-l/ktorrent.profile | |||
@@ -62,4 +62,5 @@ private-dev | |||
62 | # private-lib - problems on Arch | 62 | # private-lib - problems on Arch |
63 | private-tmp | 63 | private-tmp |
64 | 64 | ||
65 | deterministic-shutdown | ||
65 | # memory-deny-write-execute | 66 | # memory-deny-write-execute |
diff --git a/etc/profile-m-z/server.profile b/etc/profile-m-z/server.profile index 3c9ef3a86..9e40796a6 100644 --- a/etc/profile-m-z/server.profile +++ b/etc/profile-m-z/server.profile | |||
@@ -83,6 +83,7 @@ private-tmp | |||
83 | dbus-user none | 83 | dbus-user none |
84 | # dbus-system none | 84 | # dbus-system none |
85 | 85 | ||
86 | # deterministic-shutdown | ||
86 | # memory-deny-write-execute | 87 | # memory-deny-write-execute |
87 | # read-only ${HOME} | 88 | # read-only ${HOME} |
88 | # writable-run-user | 89 | # writable-run-user |
diff --git a/etc/templates/profile.template b/etc/templates/profile.template index 44197b547..1a4c8fef9 100644 --- a/etc/templates/profile.template +++ b/etc/templates/profile.template | |||
@@ -220,6 +220,7 @@ include globals.local | |||
220 | #dbus-user.talk org.freedesktop.Notifications | 220 | #dbus-user.talk org.freedesktop.Notifications |
221 | #dbus-system none | 221 | #dbus-system none |
222 | 222 | ||
223 | ##deterministic-shutdown | ||
223 | ##env VAR=VALUE | 224 | ##env VAR=VALUE |
224 | ##join-or-start NAME | 225 | ##join-or-start NAME |
225 | #memory-deny-write-execute | 226 | #memory-deny-write-execute |
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index ec789cd63..adfe77f41 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -350,6 +350,7 @@ extern int arg_nodvd; // --nodvd | |||
350 | extern int arg_nou2f; // --nou2f | 350 | extern int arg_nou2f; // --nou2f |
351 | extern int arg_noinput; // --noinput | 351 | extern int arg_noinput; // --noinput |
352 | extern int arg_deterministic_exit_code; // always exit with first child's exit status | 352 | extern int arg_deterministic_exit_code; // always exit with first child's exit status |
353 | extern int arg_deterministic_shutdown; // shut down the sandbox if first child dies | ||
353 | 354 | ||
354 | typedef enum { | 355 | typedef enum { |
355 | DBUS_POLICY_ALLOW, // Allow unrestricted access to the bus | 356 | DBUS_POLICY_ALLOW, // Allow unrestricted access to the bus |
diff --git a/src/firejail/main.c b/src/firejail/main.c index 1ba70b0bd..4bcf98035 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -147,6 +147,7 @@ int arg_nodvd = 0; // --nodvd | |||
147 | int arg_nou2f = 0; // --nou2f | 147 | int arg_nou2f = 0; // --nou2f |
148 | int arg_noinput = 0; // --noinput | 148 | int arg_noinput = 0; // --noinput |
149 | int arg_deterministic_exit_code = 0; // always exit with first child's exit status | 149 | int arg_deterministic_exit_code = 0; // always exit with first child's exit status |
150 | int arg_deterministic_shutdown = 0; // shut down the sandbox if first child dies | ||
150 | DbusPolicy arg_dbus_user = DBUS_POLICY_ALLOW; // --dbus-user | 151 | DbusPolicy arg_dbus_user = DBUS_POLICY_ALLOW; // --dbus-user |
151 | DbusPolicy arg_dbus_system = DBUS_POLICY_ALLOW; // --dbus-system | 152 | DbusPolicy arg_dbus_system = DBUS_POLICY_ALLOW; // --dbus-system |
152 | const char *arg_dbus_log_file = NULL; | 153 | const char *arg_dbus_log_file = NULL; |
@@ -2765,6 +2766,9 @@ int main(int argc, char **argv, char **envp) { | |||
2765 | else if (strcmp(argv[i], "--deterministic-exit-code") == 0) { | 2766 | else if (strcmp(argv[i], "--deterministic-exit-code") == 0) { |
2766 | arg_deterministic_exit_code = 1; | 2767 | arg_deterministic_exit_code = 1; |
2767 | } | 2768 | } |
2769 | else if (strcmp(argv[i], "--deterministic-shutdown") == 0) { | ||
2770 | arg_deterministic_shutdown = 1; | ||
2771 | } | ||
2768 | else { | 2772 | else { |
2769 | // double dash - positional params to follow | 2773 | // double dash - positional params to follow |
2770 | if (strcmp(argv[i], "--") == 0) { | 2774 | if (strcmp(argv[i], "--") == 0) { |
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index babc3941e..d44b97ff6 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -1597,6 +1597,11 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
1597 | return 0; | 1597 | return 0; |
1598 | } | 1598 | } |
1599 | 1599 | ||
1600 | if (strcmp(ptr, "deterministic-shutdown") == 0) { | ||
1601 | arg_deterministic_shutdown = 1; | ||
1602 | return 0; | ||
1603 | } | ||
1604 | |||
1600 | // rest of filesystem | 1605 | // rest of filesystem |
1601 | if (strncmp(ptr, "blacklist ", 10) == 0) | 1606 | if (strncmp(ptr, "blacklist ", 10) == 0) |
1602 | ptr += 10; | 1607 | ptr += 10; |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index efa21c34b..3887b5701 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -356,6 +356,15 @@ static int monitor_application(pid_t app_pid) { | |||
356 | if (arg_debug) | 356 | if (arg_debug) |
357 | printf("Sandbox monitor: waitpid %d retval %d status %d\n", monitored_pid, rv, status); | 357 | printf("Sandbox monitor: waitpid %d retval %d status %d\n", monitored_pid, rv, status); |
358 | 358 | ||
359 | if (arg_deterministic_shutdown) { | ||
360 | if (arg_debug) | ||
361 | printf("Sandbox monitor: monitored process died, shut down the sandbox\n"); | ||
362 | kill(-1, SIGTERM); | ||
363 | usleep(100000); | ||
364 | kill(-1, SIGKILL); | ||
365 | break; | ||
366 | } | ||
367 | |||
359 | DIR *dir; | 368 | DIR *dir; |
360 | if (!(dir = opendir("/proc"))) { | 369 | if (!(dir = opendir("/proc"))) { |
361 | // sleep 2 seconds and try again | 370 | // sleep 2 seconds and try again |
@@ -377,18 +386,6 @@ static int monitor_application(pid_t app_pid) { | |||
377 | if ((pid_t) pid == dhclient4_pid || (pid_t) pid == dhclient6_pid) | 386 | if ((pid_t) pid == dhclient4_pid || (pid_t) pid == dhclient6_pid) |
378 | continue; | 387 | continue; |
379 | 388 | ||
380 | // todo: make this generic | ||
381 | // Dillo browser leaves a dpid process running, we need to shut it down | ||
382 | int found = 0; | ||
383 | if (strcmp(cfg.command_name, "dillo") == 0) { | ||
384 | char *pidname = pid_proc_comm(pid); | ||
385 | if (pidname && strcmp(pidname, "dpid") == 0) | ||
386 | found = 1; | ||
387 | free(pidname); | ||
388 | } | ||
389 | if (found) | ||
390 | break; | ||
391 | |||
392 | monitored_pid = pid; | 389 | monitored_pid = pid; |
393 | break; | 390 | break; |
394 | } | 391 | } |
diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 43f862b9d..92806d3f1 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c | |||
@@ -87,6 +87,7 @@ static char *usage_str = | |||
87 | " --defaultgw=address - configure default gateway.\n" | 87 | " --defaultgw=address - configure default gateway.\n" |
88 | #endif | 88 | #endif |
89 | " --deterministic-exit-code - always exit with first child's status code.\n" | 89 | " --deterministic-exit-code - always exit with first child's status code.\n" |
90 | " --deterministic-shutdown - terminate orphan processes.\n" | ||
90 | " --dns=address - set DNS server.\n" | 91 | " --dns=address - set DNS server.\n" |
91 | " --dns.print=name|pid - print DNS configuration.\n" | 92 | " --dns.print=name|pid - print DNS configuration.\n" |
92 | " --env=name=value - set environment variable.\n" | 93 | " --env=name=value - set environment variable.\n" |
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt index a1eccaa5e..f6c905d59 100644 --- a/src/man/firejail-profile.txt +++ b/src/man/firejail-profile.txt | |||
@@ -954,12 +954,17 @@ be created and configured using "ip netns". | |||
954 | Use this name for the interface connected to the bridge for --net=bridge_interface commands, | 954 | Use this name for the interface connected to the bridge for --net=bridge_interface commands, |
955 | instead of the default one. | 955 | instead of the default one. |
956 | #endif | 956 | #endif |
957 | |||
957 | .SH Other | 958 | .SH Other |
958 | .TP | 959 | .TP |
959 | \fBdeterministic-exit-code | 960 | \fBdeterministic-exit-code |
960 | Always exit firejail with the first child's exit status. The default behavior is to use the exit status of the final child to exit, which can be nondeterministic. | 961 | Always exit firejail with the first child's exit status. The default behavior is to use the exit status of the final child to exit, which can be nondeterministic. |
961 | 962 | ||
962 | .TP | 963 | .TP |
964 | \fBdeterministic-shutdown | ||
965 | Always shut down the sandbox after the first child has terminated. The default behavior is to keep the sandbox alive as long as it contains running processes. | ||
966 | |||
967 | .TP | ||
963 | \fBjoin-or-start sandboxname | 968 | \fBjoin-or-start sandboxname |
964 | Join the sandbox identified by name or start a new one. | 969 | Join the sandbox identified by name or start a new one. |
965 | Same as "firejail --join=sandboxname" command if sandbox with specified name exists, otherwise same as "name sandboxname". | 970 | Same as "firejail --join=sandboxname" command if sandbox with specified name exists, otherwise same as "name sandboxname". |
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index e724e4bb9..499339264 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -706,6 +706,12 @@ $ firejail \-\-net=eth0 \-\-defaultgw=10.10.20.1 firefox | |||
706 | \fB\-\-deterministic-exit-code | 706 | \fB\-\-deterministic-exit-code |
707 | Always exit firejail with the first child's exit status. The default behavior is to use the exit status of the final child to exit, which can be nondeterministic. | 707 | Always exit firejail with the first child's exit status. The default behavior is to use the exit status of the final child to exit, which can be nondeterministic. |
708 | .br | 708 | .br |
709 | |||
710 | .TP | ||
711 | \fB\-\-deterministic-shutdown | ||
712 | Always shut down the sandbox after the first child has terminated. The default behavior is to keep the sandbox alive as long as it contains running processes. | ||
713 | .br | ||
714 | |||
709 | .TP | 715 | .TP |
710 | \fB\-\-disable-mnt | 716 | \fB\-\-disable-mnt |
711 | Blacklist /mnt, /media, /run/mount and /run/media access. | 717 | Blacklist /mnt, /media, /run/mount and /run/media access. |
diff --git a/src/zsh_completion/_firejail.in b/src/zsh_completion/_firejail.in index c7f6ee3f1..b50c5cb46 100644 --- a/src/zsh_completion/_firejail.in +++ b/src/zsh_completion/_firejail.in | |||
@@ -94,6 +94,7 @@ _firejail_args=( | |||
94 | '--cpu=-[set cpu affinity]: :->cpus' | 94 | '--cpu=-[set cpu affinity]: :->cpus' |
95 | '*--deny=-[deny access to directory or file]: :_files' | 95 | '*--deny=-[deny access to directory or file]: :_files' |
96 | "--deterministic-exit-code[always exit with first child's status code]" | 96 | "--deterministic-exit-code[always exit with first child's status code]" |
97 | '--deterministic-shutdown[terminate orphan processes]' | ||
97 | '*--dns=-[set DNS server]: :' | 98 | '*--dns=-[set DNS server]: :' |
98 | '*--env=-[set environment variable]: :' | 99 | '*--env=-[set environment variable]: :' |
99 | '--hostname=-[set sandbox hostname]: :' | 100 | '--hostname=-[set sandbox hostname]: :' |