diff options
author | netblue30 <netblue30@yahoo.com> | 2016-04-13 20:47:18 -0400 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2016-04-13 20:47:18 -0400 |
commit | c85acb7ba71b153806632256b511b915b872c5bc (patch) | |
tree | 0b7d6a11cde99266be994fd319b6edaa4ccd21cf /src | |
parent | profile fixes (diff) | |
download | firejail-c85acb7ba71b153806632256b511b915b872c5bc.tar.gz firejail-c85acb7ba71b153806632256b511b915b872c5bc.tar.zst firejail-c85acb7ba71b153806632256b511b915b872c5bc.zip |
wait up to 10 seconds for sandbox shutdown
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/main.c | 4 | ||||
-rw-r--r-- | src/firejail/sandbox.c | 50 | ||||
-rw-r--r-- | src/firejail/shutdown.c | 56 |
3 files changed, 81 insertions, 29 deletions
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); |