aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2021-10-24 16:46:28 +0200
committerLibravatar smitsohu <smitsohu@gmail.com>2021-10-28 13:41:52 +0200
commite20960ab4561f1cb97c69114f56b19b48db311c3 (patch)
treeaa29b076a625ab5c751c780fc4ad13a525ca0890
parentAdd disable-proc to firefox-common (diff)
downloadfirejail-e20960ab4561f1cb97c69114f56b19b48db311c3.tar.gz
firejail-e20960ab4561f1cb97c69114f56b19b48db311c3.tar.zst
firejail-e20960ab4561f1cb97c69114f56b19b48db311c3.zip
deterministic-shutdown option
-rw-r--r--contrib/vim/syntax/firejail.vim2
-rw-r--r--etc/profile-a-l/akregator.profile1
-rw-r--r--etc/profile-a-l/default.profile1
-rw-r--r--etc/profile-a-l/dillo.profile2
-rw-r--r--etc/profile-a-l/ktorrent.profile1
-rw-r--r--etc/profile-m-z/server.profile1
-rw-r--r--etc/templates/profile.template1
-rw-r--r--src/firejail/firejail.h1
-rw-r--r--src/firejail/main.c4
-rw-r--r--src/firejail/profile.c5
-rw-r--r--src/firejail/sandbox.c21
-rw-r--r--src/firejail/usage.c1
-rw-r--r--src/man/firejail-profile.txt5
-rw-r--r--src/man/firejail.txt6
-rw-r--r--src/zsh_completion/_firejail.in1
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)
52syn 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 52syn 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
54syn 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 54syn 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
55syn match fjCommand /ignore / nextgroup=fjCommand,fjCommandNoCond skipwhite contained 55syn match fjCommand /ignore / nextgroup=fjCommand,fjCommandNoCond skipwhite contained
56syn match fjCommand /caps\.drop / nextgroup=fjCapability,fjAll skipwhite contained 56syn match fjCommand /caps\.drop / nextgroup=fjCapability,fjAll skipwhite contained
57syn match fjCommand /caps\.keep / nextgroup=fjCapability skipwhite contained 57syn 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
49private-dev 49private-dev
50private-tmp 50private-tmp
51 51
52deterministic-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
36private-dev 36private-dev
37private-tmp 37private-tmp
38
39deterministic-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
63private-tmp 63private-tmp
64 64
65deterministic-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
83dbus-user none 83dbus-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
350extern int arg_nou2f; // --nou2f 350extern int arg_nou2f; // --nou2f
351extern int arg_noinput; // --noinput 351extern int arg_noinput; // --noinput
352extern int arg_deterministic_exit_code; // always exit with first child's exit status 352extern int arg_deterministic_exit_code; // always exit with first child's exit status
353extern int arg_deterministic_shutdown; // shut down the sandbox if first child dies
353 354
354typedef enum { 355typedef 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
147int arg_nou2f = 0; // --nou2f 147int arg_nou2f = 0; // --nou2f
148int arg_noinput = 0; // --noinput 148int arg_noinput = 0; // --noinput
149int arg_deterministic_exit_code = 0; // always exit with first child's exit status 149int arg_deterministic_exit_code = 0; // always exit with first child's exit status
150int arg_deterministic_shutdown = 0; // shut down the sandbox if first child dies
150DbusPolicy arg_dbus_user = DBUS_POLICY_ALLOW; // --dbus-user 151DbusPolicy arg_dbus_user = DBUS_POLICY_ALLOW; // --dbus-user
151DbusPolicy arg_dbus_system = DBUS_POLICY_ALLOW; // --dbus-system 152DbusPolicy arg_dbus_system = DBUS_POLICY_ALLOW; // --dbus-system
152const char *arg_dbus_log_file = NULL; 153const 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".
954Use this name for the interface connected to the bridge for --net=bridge_interface commands, 954Use this name for the interface connected to the bridge for --net=bridge_interface commands,
955instead of the default one. 955instead 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
960Always 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. 961Always 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
965Always 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
964Join the sandbox identified by name or start a new one. 969Join the sandbox identified by name or start a new one.
965Same as "firejail --join=sandboxname" command if sandbox with specified name exists, otherwise same as "name sandboxname". 970Same 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
707Always 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. 707Always 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
712Always 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
711Blacklist /mnt, /media, /run/mount and /run/media access. 717Blacklist /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]: :'