diff options
author | Austin Morton <austinpmorton@gmail.com> | 2019-05-20 20:50:48 -0400 |
---|---|---|
committer | Austin Morton <austinpmorton@gmail.com> | 2019-05-20 20:59:49 -0400 |
commit | d380de39f039cf23a992b08c506cc200a7cf6292 (patch) | |
tree | 681aa830ee7c657a7bfe2e0c8de92d91e38d19bf | |
parent | Create a profile for mp3splt-gtk (diff) | |
download | firejail-d380de39f039cf23a992b08c506cc200a7cf6292.tar.gz firejail-d380de39f039cf23a992b08c506cc200a7cf6292.tar.zst firejail-d380de39f039cf23a992b08c506cc200a7cf6292.zip |
Add deterministic-exit-code option to ensure firejail exits with the first childs exit code regardless of the termination ordering of orphaned children
-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 | 7 | ||||
-rw-r--r-- | src/firejail/usage.c | 1 | ||||
-rw-r--r-- | src/man/firejail-profile.txt | 4 | ||||
-rw-r--r-- | src/man/firejail.txt | 4 | ||||
-rwxr-xr-x | test/environment/deterministic-exit-code.exp | 55 | ||||
-rwxr-xr-x | test/environment/environment.sh | 3 |
9 files changed, 82 insertions, 2 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index e0f3a6a16..b2083d6ad 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -315,6 +315,7 @@ extern int arg_notv; // --notv | |||
315 | extern int arg_nodvd; // --nodvd | 315 | extern int arg_nodvd; // --nodvd |
316 | extern int arg_nou2f; // --nou2f | 316 | extern int arg_nou2f; // --nou2f |
317 | extern int arg_nodbus; // -nodbus | 317 | extern int arg_nodbus; // -nodbus |
318 | extern int arg_deterministic_exit_code; // always exit with first childs exit status | ||
318 | 319 | ||
319 | extern int login_shell; | 320 | extern int login_shell; |
320 | extern int parent_to_child_fds[2]; | 321 | extern int parent_to_child_fds[2]; |
diff --git a/src/firejail/main.c b/src/firejail/main.c index f3dc72944..3e2cc3a17 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -125,6 +125,7 @@ int arg_notv = 0; // --notv | |||
125 | int arg_nodvd = 0; // --nodvd | 125 | int arg_nodvd = 0; // --nodvd |
126 | int arg_nodbus = 0; // -nodbus | 126 | int arg_nodbus = 0; // -nodbus |
127 | int arg_nou2f = 0; // --nou2f | 127 | int arg_nou2f = 0; // --nou2f |
128 | int arg_deterministic_exit_code = 0; // always exit with first childs exit status | ||
128 | int login_shell = 0; | 129 | int login_shell = 0; |
129 | 130 | ||
130 | 131 | ||
@@ -2275,6 +2276,9 @@ int main(int argc, char **argv) { | |||
2275 | return 1; | 2276 | return 1; |
2276 | } | 2277 | } |
2277 | } | 2278 | } |
2279 | else if (strcmp(argv[i], "--deterministic-exit-code") == 0) { | ||
2280 | arg_deterministic_exit_code = 1; | ||
2281 | } | ||
2278 | else { | 2282 | else { |
2279 | // double dash - positional params to follow | 2283 | // double dash - positional params to follow |
2280 | if (strcmp(argv[i], "--") == 0) { | 2284 | if (strcmp(argv[i], "--") == 0) { |
diff --git a/src/firejail/profile.c b/src/firejail/profile.c index c8619f7e2..55d3cf5b0 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c | |||
@@ -1301,6 +1301,11 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { | |||
1301 | return 0; | 1301 | return 0; |
1302 | } | 1302 | } |
1303 | 1303 | ||
1304 | if (strcmp(ptr, "deterministic-exit-code") == 0) { | ||
1305 | arg_deterministic_exit_code = 1; | ||
1306 | return 0; | ||
1307 | } | ||
1308 | |||
1304 | // rest of filesystem | 1309 | // rest of filesystem |
1305 | if (strncmp(ptr, "blacklist ", 10) == 0) | 1310 | if (strncmp(ptr, "blacklist ", 10) == 0) |
1306 | ptr += 10; | 1311 | ptr += 10; |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 9f0a5f25c..c09a1bc73 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -271,6 +271,7 @@ static int monitor_application(pid_t app_pid) { | |||
271 | } | 271 | } |
272 | 272 | ||
273 | int status = 0; | 273 | int status = 0; |
274 | int app_status = 0; | ||
274 | while (monitored_pid) { | 275 | while (monitored_pid) { |
275 | usleep(20000); | 276 | usleep(20000); |
276 | char *msg; | 277 | char *msg; |
@@ -295,6 +296,8 @@ static int monitor_application(pid_t app_pid) { | |||
295 | sleep(1); | 296 | sleep(1); |
296 | break; | 297 | break; |
297 | } | 298 | } |
299 | else if (rv == app_pid) | ||
300 | app_status = status; | ||
298 | 301 | ||
299 | // handle --timeout | 302 | // handle --timeout |
300 | if (options) { | 303 | if (options) { |
@@ -352,8 +355,8 @@ static int monitor_application(pid_t app_pid) { | |||
352 | printf("Sandbox monitor: monitoring %d\n", monitored_pid); | 355 | printf("Sandbox monitor: monitoring %d\n", monitored_pid); |
353 | } | 356 | } |
354 | 357 | ||
355 | // return the latest exit status. | 358 | // return the appropriate exit status. |
356 | return status; | 359 | return arg_deterministic_exit_code ? app_status : status; |
357 | } | 360 | } |
358 | 361 | ||
359 | static void print_time(void) { | 362 | static void print_time(void) { |
diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 7620bba82..ab749413b 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c | |||
@@ -66,6 +66,7 @@ static char *usage_str = | |||
66 | #ifdef HAVE_NETWORK | 66 | #ifdef HAVE_NETWORK |
67 | " --defaultgw=address - configure default gateway.\n" | 67 | " --defaultgw=address - configure default gateway.\n" |
68 | #endif | 68 | #endif |
69 | " --deterministic-exit-code - always exit with first childs status code.\n" | ||
69 | " --dns=address - set DNS server.\n" | 70 | " --dns=address - set DNS server.\n" |
70 | " --dns.print=name|pid - print DNS configuration.\n" | 71 | " --dns.print=name|pid - print DNS configuration.\n" |
71 | " --env=name=value - set environment variable.\n" | 72 | " --env=name=value - set environment variable.\n" |
diff --git a/src/man/firejail-profile.txt b/src/man/firejail-profile.txt index 703fac30f..cbc745af7 100644 --- a/src/man/firejail-profile.txt +++ b/src/man/firejail-profile.txt | |||
@@ -661,6 +661,10 @@ instead of the default one. | |||
661 | Join the sandbox identified by name or start a new one. | 661 | Join the sandbox identified by name or start a new one. |
662 | Same as "firejail --join=sandboxname" command if sandbox with specified name exists, otherwise same as "name sandboxname". | 662 | Same as "firejail --join=sandboxname" command if sandbox with specified name exists, otherwise same as "name sandboxname". |
663 | 663 | ||
664 | .TP | ||
665 | \fBdeterministic-exit-code | ||
666 | Always exit firejail with the first childs exit status. The default behavior is to use the exit status of the final child to exit, which can be nondeterministic. | ||
667 | |||
664 | .SH FILES | 668 | .SH FILES |
665 | /etc/firejail/filename.profile, $HOME/.config/firejail/filename.profile | 669 | /etc/firejail/filename.profile, $HOME/.config/firejail/filename.profile |
666 | 670 | ||
diff --git a/src/man/firejail.txt b/src/man/firejail.txt index e6826448b..fcc7f66d7 100644 --- a/src/man/firejail.txt +++ b/src/man/firejail.txt | |||
@@ -410,6 +410,10 @@ Example: | |||
410 | $ firejail \-\-disable-mnt firefox | 410 | $ firejail \-\-disable-mnt firefox |
411 | 411 | ||
412 | .TP | 412 | .TP |
413 | \fB\-\-deterministic-exit-code | ||
414 | Always exit firejail with the first childs exit status. The default behavior is to use the exit status of the final child to exit, which can be nondeterministic. | ||
415 | |||
416 | .TP | ||
413 | \fB\-\-dns=address | 417 | \fB\-\-dns=address |
414 | Set a DNS server for the sandbox. Up to three DNS servers can be defined. | 418 | Set a DNS server for the sandbox. Up to three DNS servers can be defined. |
415 | Use this option if you don't trust the DNS setup on your network. | 419 | Use this option if you don't trust the DNS setup on your network. |
diff --git a/test/environment/deterministic-exit-code.exp b/test/environment/deterministic-exit-code.exp new file mode 100755 index 000000000..165b9ebe0 --- /dev/null +++ b/test/environment/deterministic-exit-code.exp | |||
@@ -0,0 +1,55 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | # This file is part of Firejail project | ||
3 | # Copyright (C) 2014-2019 Firejail Authors | ||
4 | # License GPL v2 | ||
5 | |||
6 | set timeout 4 | ||
7 | spawn $env(SHELL) | ||
8 | match_max 100000 | ||
9 | |||
10 | send -- "firejail\r" | ||
11 | expect { | ||
12 | timeout {puts "TESTING ERROR 0\n";exit} | ||
13 | "Child process initialized" | ||
14 | } | ||
15 | sleep 1 | ||
16 | |||
17 | send -- "({ nohup bash -c \"sleep 0.2; exit 53\" &> /dev/null & } &)\r" | ||
18 | send -- "exit 35\r" | ||
19 | expect { | ||
20 | timeout {puts "TESTING ERROR 1\n";exit} | ||
21 | "Parent is shutting down" | ||
22 | } | ||
23 | after 300 | ||
24 | |||
25 | send -- "echo $?\r" | ||
26 | expect { | ||
27 | timeout {puts "TESTING ERROR 2\n";exit} | ||
28 | "53" | ||
29 | } | ||
30 | after 100 | ||
31 | |||
32 | send -- "firejail --deterministic-exit-code\r" | ||
33 | expect { | ||
34 | timeout {puts "TESTING ERROR 3\n";exit} | ||
35 | "Child process initialized" | ||
36 | } | ||
37 | sleep 1 | ||
38 | |||
39 | send -- "({ nohup bash -c \"sleep 0.2; exit 53\" &> /dev/null & } &)\r" | ||
40 | send -- "exit 35\r" | ||
41 | expect { | ||
42 | timeout {puts "TESTING ERROR 4\n";exit} | ||
43 | "Parent is shutting down" | ||
44 | } | ||
45 | after 300 | ||
46 | |||
47 | send -- "echo $?\r" | ||
48 | expect { | ||
49 | timeout {puts "TESTING ERROR 5\n";exit} | ||
50 | "35" | ||
51 | } | ||
52 | after 100 | ||
53 | |||
54 | |||
55 | puts "\nall done\n" | ||
diff --git a/test/environment/environment.sh b/test/environment/environment.sh index 85d6c0873..5b4aa32f4 100755 --- a/test/environment/environment.sh +++ b/test/environment/environment.sh | |||
@@ -116,3 +116,6 @@ echo "TESTING: rlimit errors (test/environment/rlimit-bad.exp)" | |||
116 | 116 | ||
117 | echo "TESTING: rlimit errors profile (test/environment/rlimit-bad-profile.exp)" | 117 | echo "TESTING: rlimit errors profile (test/environment/rlimit-bad-profile.exp)" |
118 | ./rlimit-bad-profile.exp | 118 | ./rlimit-bad-profile.exp |
119 | |||
120 | echo "TESTING: deterministic exit code (test/environment/deterministic-exit-code.exp" | ||
121 | ./deterministic-exit-code.exp | ||