diff options
-rw-r--r-- | etc/deluge.profile | 3 | ||||
-rw-r--r-- | src/firejail/main.c | 4 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 50 | ||||
-rw-r--r-- | src/firejail/shutdown.c | 56 | ||||
-rwxr-xr-x | test/catchsignal-master.sh | 4 | ||||
-rwxr-xr-x | test/catchsignal.sh | 27 | ||||
-rwxr-xr-x | test/catchsignal2.sh | 49 | ||||
-rwxr-xr-x | test/option-shutdown2.exp | 42 | ||||
-rwxr-xr-x | test/option-shutdown3.exp | 62 | ||||
-rwxr-xr-x | test/option-shutdown4.exp | 66 | ||||
-rwxr-xr-x | test/pid.exp | 2 | ||||
-rwxr-xr-x | test/test.sh | 9 |
12 files changed, 343 insertions, 31 deletions
diff --git a/etc/deluge.profile b/etc/deluge.profile index d8ffc8ec5..4043f58f5 100644 --- a/etc/deluge.profile +++ b/etc/deluge.profile | |||
@@ -1,7 +1,8 @@ | |||
1 | # deluge bittorernt client profile | 1 | # deluge bittorernt client profile |
2 | include /etc/firejail/disable-common.inc | 2 | include /etc/firejail/disable-common.inc |
3 | include /etc/firejail/disable-programs.inc | 3 | include /etc/firejail/disable-programs.inc |
4 | include /etc/firejail/disable-devel.inc | 4 | # deluge is using python on Debian |
5 | #include /etc/firejail/disable-devel.inc | ||
5 | include /etc/firejail/disable-passwdmgr.inc | 6 | include /etc/firejail/disable-passwdmgr.inc |
6 | 7 | ||
7 | caps.drop all | 8 | caps.drop all |
diff --git a/src/firejail/main.c b/src/firejail/main.c index c183a7675..bdf960b96 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -132,8 +132,10 @@ static void myexit(int rv) { | |||
132 | 132 | ||
133 | static void my_handler(int s){ | 133 | static void my_handler(int s){ |
134 | EUID_ROOT(); | 134 | EUID_ROOT(); |
135 | if (!arg_quiet) | 135 | if (!arg_quiet) { |
136 | printf("\nParent received signal %d, shutting down the child process...\n", s); | 136 | printf("\nParent received signal %d, shutting down the child process...\n", s); |
137 | fflush(0); | ||
138 | } | ||
137 | logsignal(s); | 139 | logsignal(s); |
138 | kill(child, SIGTERM); | 140 | kill(child, SIGTERM); |
139 | myexit(1); | 141 | myexit(1); |
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 4a4956687..3f3564295 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c | |||
@@ -34,17 +34,45 @@ | |||
34 | #define CLONE_NEWUSER 0x10000000 | 34 | #define CLONE_NEWUSER 0x10000000 |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | static monitored_pid = 0; | 37 | static int monitored_pid = 0; |
38 | static void sandbox_handler(int s){ | 38 | static void sandbox_handler(int sig){ |
39 | if (!arg_quiet) | 39 | if (!arg_quiet) { |
40 | printf("\nChild received signal %d, shutting down the sandbox...\n", s); | 40 | printf("\nChild received signal %d, shutting down the sandbox...\n", sig); |
41 | fflush(0); | ||
42 | } | ||
43 | |||
44 | // broadcast sigterm to all processes in the group | ||
45 | kill(-1, SIGTERM); | ||
46 | sleep(1); | ||
47 | |||
41 | if (monitored_pid) { | 48 | if (monitored_pid) { |
42 | kill(monitored_pid, SIGTERM); | 49 | int monsec = 9; |
43 | sleep(1); | 50 | char *monfile; |
44 | kill(monitored_pid, SIGKILL); | 51 | if (asprintf(&monfile, "/proc/%d/cmdline", monitored_pid) == -1) |
52 | errExit("asprintf"); | ||
53 | while (monsec) { | ||
54 | FILE *fp = fopen(monfile, "r"); | ||
55 | if (!fp) | ||
56 | break; | ||
57 | |||
58 | char c; | ||
59 | size_t count = fread(&c, 1, 1, fp); | ||
60 | fclose(fp); | ||
61 | if (count == 0) | ||
62 | break; | ||
63 | |||
64 | if (arg_debug) | ||
65 | printf("Waiting on PID %d to finish\n", monitored_pid); | ||
66 | sleep(1); | ||
67 | monsec--; | ||
68 | } | ||
69 | free(monfile); | ||
70 | |||
45 | } | 71 | } |
46 | 72 | ||
47 | exit(s); | 73 | // broadcast a SIGKILL |
74 | kill(-1, SIGKILL); | ||
75 | exit(sig); | ||
48 | } | 76 | } |
49 | 77 | ||
50 | 78 | ||
@@ -149,13 +177,15 @@ static int monitor_application(pid_t app_pid) { | |||
149 | signal (SIGTERM, sandbox_handler); | 177 | signal (SIGTERM, sandbox_handler); |
150 | EUID_USER(); | 178 | EUID_USER(); |
151 | 179 | ||
152 | int status; | 180 | int status = 0; |
153 | while (monitored_pid) { | 181 | while (monitored_pid) { |
154 | usleep(20000); | 182 | usleep(20000); |
155 | char *msg; | 183 | char *msg; |
156 | if (asprintf(&msg, "monitoring pid %d\n", monitored_pid) == -1) | 184 | if (asprintf(&msg, "monitoring pid %d\n", monitored_pid) == -1) |
157 | errExit("asprintf"); | 185 | errExit("asprintf"); |
158 | logmsg(msg); | 186 | logmsg(msg); |
187 | if (arg_debug) | ||
188 | printf("%s\n", msg); | ||
159 | free(msg); | 189 | free(msg); |
160 | 190 | ||
161 | pid_t rv; | 191 | pid_t rv; |
diff --git a/src/firejail/shutdown.c b/src/firejail/shutdown.c index 94ca0a816..8d8035bfb 100644 --- a/src/firejail/shutdown.c +++ b/src/firejail/shutdown.c | |||
@@ -77,26 +77,46 @@ void shut(pid_t pid) { | |||
77 | EUID_ROOT(); | 77 | EUID_ROOT(); |
78 | printf("Sending SIGTERM to %u\n", pid); | 78 | printf("Sending SIGTERM to %u\n", pid); |
79 | kill(pid, SIGTERM); | 79 | kill(pid, SIGTERM); |
80 | sleep(2); | ||
81 | 80 | ||
82 | // if the process is still running, terminate it using SIGKILL | 81 | // wait for not more than 10 seconds |
83 | // try to open stat file | 82 | sleep(2); |
84 | char *file; | 83 | int monsec = 8; |
85 | if (asprintf(&file, "/proc/%u/status", pid) == -1) { | 84 | char *monfile; |
86 | perror("asprintf"); | 85 | if (asprintf(&monfile, "/proc/%d/cmdline", pid) == -1) |
87 | exit(1); | 86 | errExit("asprintf"); |
87 | int killdone = 0; | ||
88 | |||
89 | while (monsec) { | ||
90 | FILE *fp = fopen(monfile, "r"); | ||
91 | if (!fp) { | ||
92 | killdone = 1; | ||
93 | break; | ||
94 | } | ||
95 | |||
96 | char c; | ||
97 | size_t count = fread(&c, 1, 1, fp); | ||
98 | fclose(fp); | ||
99 | if (count == 0) { | ||
100 | // all done | ||
101 | killdone = 1; | ||
102 | break; | ||
103 | } | ||
104 | |||
105 | sleep(1); | ||
106 | monsec--; | ||
88 | } | 107 | } |
89 | FILE *fp = fopen(file, "r"); | 108 | free(monfile); |
90 | if (!fp) | 109 | |
91 | return; | 110 | |
92 | fclose(fp); | 111 | // force SIGKILL |
93 | 112 | if (!killdone) { | |
94 | // kill the process and also the parent | 113 | // kill the process and also the parent |
95 | printf("Sending SIGKILL to %u\n", pid); | 114 | printf("Sending SIGKILL to %u\n", pid); |
96 | kill(pid, SIGKILL); | 115 | kill(pid, SIGKILL); |
97 | if (parent != pid) { | 116 | if (parent != pid) { |
98 | printf("Sending SIGKILL to %u\n", parent); | 117 | printf("Sending SIGKILL to %u\n", parent); |
99 | kill(parent, SIGKILL); | 118 | kill(parent, SIGKILL); |
119 | } | ||
100 | } | 120 | } |
101 | 121 | ||
102 | clear_run_files(parent); | 122 | clear_run_files(parent); |
diff --git a/test/catchsignal-master.sh b/test/catchsignal-master.sh new file mode 100755 index 000000000..62a1801cc --- /dev/null +++ b/test/catchsignal-master.sh | |||
@@ -0,0 +1,4 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | ./catchsignal.sh & | ||
4 | ./catchsignal.sh & | ||
diff --git a/test/catchsignal.sh b/test/catchsignal.sh new file mode 100755 index 000000000..87a1d0adf --- /dev/null +++ b/test/catchsignal.sh | |||
@@ -0,0 +1,27 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | _term() { | ||
4 | echo "Caught Signal" | ||
5 | echo 1 | ||
6 | sleep 1 | ||
7 | echo 2 | ||
8 | sleep 1 | ||
9 | echo 3 | ||
10 | sleep 1 | ||
11 | echo 4 | ||
12 | sleep 1 | ||
13 | echo 5 | ||
14 | sleep 1 | ||
15 | |||
16 | kill $pid | ||
17 | exit | ||
18 | } | ||
19 | |||
20 | trap _term SIGTERM | ||
21 | trap _term SIGINT | ||
22 | |||
23 | echo "Sleeping..." | ||
24 | |||
25 | sleep inf & | ||
26 | pid=$! | ||
27 | wait $pid | ||
diff --git a/test/catchsignal2.sh b/test/catchsignal2.sh new file mode 100755 index 000000000..424350397 --- /dev/null +++ b/test/catchsignal2.sh | |||
@@ -0,0 +1,49 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | _term() { | ||
4 | echo "Caught Signal" | ||
5 | echo 1 | ||
6 | sleep 1 | ||
7 | echo 2 | ||
8 | sleep 1 | ||
9 | echo 3 | ||
10 | sleep 1 | ||
11 | echo 4 | ||
12 | sleep 1 | ||
13 | echo 5 | ||
14 | sleep 1 | ||
15 | |||
16 | echo 10 | ||
17 | sleep 1 | ||
18 | echo 20 | ||
19 | sleep 1 | ||
20 | echo 30 | ||
21 | sleep 1 | ||
22 | echo 40 | ||
23 | sleep 1 | ||
24 | echo 50 | ||
25 | sleep 1 | ||
26 | |||
27 | echo 100 | ||
28 | sleep 1 | ||
29 | echo 200 | ||
30 | sleep 1 | ||
31 | echo 300 | ||
32 | sleep 1 | ||
33 | echo 400 | ||
34 | sleep 1 | ||
35 | echo 500 | ||
36 | sleep 1 | ||
37 | |||
38 | kill $pid | ||
39 | exit | ||
40 | } | ||
41 | |||
42 | trap _term SIGTERM | ||
43 | trap _term SIGINT | ||
44 | |||
45 | echo "Sleeping..." | ||
46 | |||
47 | sleep inf & | ||
48 | pid=$! | ||
49 | wait $pid | ||
diff --git a/test/option-shutdown2.exp b/test/option-shutdown2.exp new file mode 100755 index 000000000..403bc30be --- /dev/null +++ b/test/option-shutdown2.exp | |||
@@ -0,0 +1,42 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | set firstspawn $spawn_id | ||
8 | |||
9 | send -- "firejail --name=shutdowntesting ./catchsignal.sh\r" | ||
10 | expect { | ||
11 | timeout {puts "TESTING ERROR 0\n";exit} | ||
12 | "Child process initialized" | ||
13 | } | ||
14 | sleep 2 | ||
15 | |||
16 | spawn $env(SHELL) | ||
17 | send -- "firejail --shutdown=shutdowntesting\r" | ||
18 | |||
19 | set spawn_id $firstspawn | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 1\n";exit} | ||
22 | "1" | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 2\n";exit} | ||
26 | "2" | ||
27 | } | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 3\n";exit} | ||
30 | "3" | ||
31 | } | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 4\n";exit} | ||
34 | "4" | ||
35 | } | ||
36 | expect { | ||
37 | timeout {puts "TESTING ERROR 5\n";exit} | ||
38 | "5" | ||
39 | } | ||
40 | sleep 1 | ||
41 | |||
42 | puts "\nalldone\n" | ||
diff --git a/test/option-shutdown3.exp b/test/option-shutdown3.exp new file mode 100755 index 000000000..0ef371cd8 --- /dev/null +++ b/test/option-shutdown3.exp | |||
@@ -0,0 +1,62 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | set firstspawn $spawn_id | ||
8 | |||
9 | send -- "firejail --name=shutdowntesting ./catchsignal-master.sh\r" | ||
10 | expect { | ||
11 | timeout {puts "TESTING ERROR 0\n";exit} | ||
12 | "Child process initialized" | ||
13 | } | ||
14 | sleep 2 | ||
15 | |||
16 | spawn $env(SHELL) | ||
17 | send -- "firejail --shutdown=shutdowntesting\r" | ||
18 | |||
19 | set spawn_id $firstspawn | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 1\n";exit} | ||
22 | "1" | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 2\n";exit} | ||
26 | "1" | ||
27 | } | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 3\n";exit} | ||
30 | "2" | ||
31 | } | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 4\n";exit} | ||
34 | "2" | ||
35 | } | ||
36 | expect { | ||
37 | timeout {puts "TESTING ERROR 5\n";exit} | ||
38 | "3" | ||
39 | } | ||
40 | expect { | ||
41 | timeout {puts "TESTING ERROR 6\n";exit} | ||
42 | "3" | ||
43 | } | ||
44 | expect { | ||
45 | timeout {puts "TESTING ERROR 7\n";exit} | ||
46 | "4" | ||
47 | } | ||
48 | expect { | ||
49 | timeout {puts "TESTING ERROR 8\n";exit} | ||
50 | "4" | ||
51 | } | ||
52 | expect { | ||
53 | timeout {puts "TESTING ERROR 9\n";exit} | ||
54 | "5" | ||
55 | } | ||
56 | expect { | ||
57 | timeout {puts "TESTING ERROR 10\n";exit} | ||
58 | "5" | ||
59 | } | ||
60 | sleep 1 | ||
61 | |||
62 | puts "\nalldone\n" | ||
diff --git a/test/option-shutdown4.exp b/test/option-shutdown4.exp new file mode 100755 index 000000000..f188ec66d --- /dev/null +++ b/test/option-shutdown4.exp | |||
@@ -0,0 +1,66 @@ | |||
1 | #!/usr/bin/expect -f | ||
2 | |||
3 | set timeout 10 | ||
4 | spawn $env(SHELL) | ||
5 | match_max 100000 | ||
6 | |||
7 | set firstspawn $spawn_id | ||
8 | |||
9 | send -- "firejail --name=shutdowntesting ./catchsignal2.sh\r" | ||
10 | expect { | ||
11 | timeout {puts "TESTING ERROR 0\n";exit} | ||
12 | "Child process initialized" | ||
13 | } | ||
14 | sleep 2 | ||
15 | |||
16 | spawn $env(SHELL) | ||
17 | send -- "firejail --shutdown=shutdowntesting\r" | ||
18 | |||
19 | set spawn_id $firstspawn | ||
20 | expect { | ||
21 | timeout {puts "TESTING ERROR 1\n";exit} | ||
22 | "1" | ||
23 | } | ||
24 | expect { | ||
25 | timeout {puts "TESTING ERROR 2\n";exit} | ||
26 | "2" | ||
27 | } | ||
28 | expect { | ||
29 | timeout {puts "TESTING ERROR 3\n";exit} | ||
30 | "3" | ||
31 | } | ||
32 | expect { | ||
33 | timeout {puts "TESTING ERROR 4\n";exit} | ||
34 | "4" | ||
35 | } | ||
36 | expect { | ||
37 | timeout {puts "TESTING ERROR 5\n";exit} | ||
38 | "5" | ||
39 | } | ||
40 | expect { | ||
41 | timeout {puts "TESTING ERROR 10\n";exit} | ||
42 | "10" | ||
43 | } | ||
44 | expect { | ||
45 | timeout {puts "TESTING ERROR 20\n";exit} | ||
46 | "20" | ||
47 | } | ||
48 | expect { | ||
49 | timeout {puts "TESTING ERROR 30\n";exit} | ||
50 | "30" | ||
51 | } | ||
52 | expect { | ||
53 | timeout {puts "TESTING ERROR 40\n";exit} | ||
54 | "40" | ||
55 | } | ||
56 | expect { | ||
57 | timeout {puts "TESTING ERROR 50\n";exit} | ||
58 | "50" | ||
59 | } | ||
60 | expect { | ||
61 | timeout {puts "TESTING ERROR 60\n";exit} | ||
62 | "Killed" | ||
63 | } | ||
64 | sleep 1 | ||
65 | |||
66 | puts "\nalldone\n" | ||
diff --git a/test/pid.exp b/test/pid.exp index fb5b90f04..cdeb9d5fb 100755 --- a/test/pid.exp +++ b/test/pid.exp | |||
@@ -37,7 +37,7 @@ sleep 1 | |||
37 | send -- "ps aux |wc -l; pwd\r" | 37 | send -- "ps aux |wc -l; pwd\r" |
38 | expect { | 38 | expect { |
39 | timeout {puts "TESTING ERROR 5\n";exit} | 39 | timeout {puts "TESTING ERROR 5\n";exit} |
40 | "6" {puts "normal system\n'} | 40 | "6" {puts "normal system\n"} |
41 | "5" {puts "grsecurity\n"} | 41 | "5" {puts "grsecurity\n"} |
42 | } | 42 | } |
43 | expect { | 43 | expect { |
diff --git a/test/test.sh b/test/test.sh index 96ef8f423..c6fe4f299 100755 --- a/test/test.sh +++ b/test/test.sh | |||
@@ -133,6 +133,15 @@ echo "TESTING: rlimit (option_rlimit.exp)" | |||
133 | echo "TESTING: shutdown (option_shutdown.exp)" | 133 | echo "TESTING: shutdown (option_shutdown.exp)" |
134 | ./option-shutdown.exp | 134 | ./option-shutdown.exp |
135 | 135 | ||
136 | echo "TESTING: shutdown2 (option_shutdown2.exp)" | ||
137 | ./option-shutdown2.exp | ||
138 | |||
139 | echo "TESTING: shutdown3 (option_shutdown3.exp)" | ||
140 | ./option-shutdown3.exp | ||
141 | |||
142 | echo "TESTING: shutdown4 (option_shutdown4.exp)" | ||
143 | ./option-shutdown4.exp | ||
144 | |||
136 | echo "TESTING: join (option-join.exp)" | 145 | echo "TESTING: join (option-join.exp)" |
137 | ./option-join.exp | 146 | ./option-join.exp |
138 | 147 | ||