diff options
Diffstat (limited to 'src/firejail/main.c')
-rw-r--r-- | src/firejail/main.c | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/src/firejail/main.c b/src/firejail/main.c index faa4972e2..61f507f36 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -157,12 +157,35 @@ static void myexit(int rv) { | |||
157 | exit(rv); | 157 | exit(rv); |
158 | } | 158 | } |
159 | 159 | ||
160 | static void my_handler(int s){ | 160 | static void my_handler(int s) { |
161 | EUID_ROOT(); | ||
162 | fmessage("\nParent received signal %d, shutting down the child process...\n", s); | 161 | fmessage("\nParent received signal %d, shutting down the child process...\n", s); |
163 | logsignal(s); | 162 | logsignal(s); |
164 | kill(child, SIGTERM); | 163 | if (waitpid(child, NULL, WNOHANG) == 0) { |
165 | myexit(1); | 164 | if (has_handler(child, s)) // signals are not delivered if there is no handler yet |
165 | kill(child, s); | ||
166 | else | ||
167 | kill(child, SIGKILL); | ||
168 | waitpid(child, NULL, 0); | ||
169 | } | ||
170 | myexit(s); | ||
171 | } | ||
172 | |||
173 | static void install_handler(void) { | ||
174 | struct sigaction sga; | ||
175 | |||
176 | // block SIGTERM while handling SIGINT | ||
177 | sigemptyset(&sga.sa_mask); | ||
178 | sigaddset(&sga.sa_mask, SIGTERM); | ||
179 | sga.sa_handler = my_handler; | ||
180 | sga.sa_flags = 0; | ||
181 | sigaction(SIGINT, &sga, NULL); | ||
182 | |||
183 | // block SIGINT while handling SIGTERM | ||
184 | sigemptyset(&sga.sa_mask); | ||
185 | sigaddset(&sga.sa_mask, SIGINT); | ||
186 | sga.sa_handler = my_handler; | ||
187 | sga.sa_flags = 0; | ||
188 | sigaction(SIGTERM, &sga, NULL); | ||
166 | } | 189 | } |
167 | 190 | ||
168 | // return 1 if error, 0 if a valid pid was found | 191 | // return 1 if error, 0 if a valid pid was found |
@@ -2601,16 +2624,25 @@ int main(int argc, char **argv) { | |||
2601 | flock(lockfd_network, LOCK_UN); | 2624 | flock(lockfd_network, LOCK_UN); |
2602 | close(lockfd_network); | 2625 | close(lockfd_network); |
2603 | } | 2626 | } |
2627 | EUID_USER(); | ||
2628 | |||
2629 | int status = 0; | ||
2630 | //***************************** | ||
2631 | // following code is signal-safe | ||
2604 | 2632 | ||
2605 | // handle CTRL-C in parent | 2633 | // handle CTRL-C in parent |
2606 | signal (SIGINT, my_handler); | 2634 | install_handler(); |
2607 | signal (SIGTERM, my_handler); | ||
2608 | 2635 | ||
2609 | // wait for the child to finish | 2636 | // wait for the child to finish |
2610 | EUID_USER(); | ||
2611 | int status = 0; | ||
2612 | waitpid(child, &status, 0); | 2637 | waitpid(child, &status, 0); |
2613 | 2638 | ||
2639 | // restore default signal actions | ||
2640 | signal(SIGTERM, SIG_DFL); | ||
2641 | signal(SIGINT, SIG_DFL); | ||
2642 | |||
2643 | // end of signal-safe code | ||
2644 | //***************************** | ||
2645 | |||
2614 | // free globals | 2646 | // free globals |
2615 | if (cfg.profile) { | 2647 | if (cfg.profile) { |
2616 | ProfileEntry *prf = cfg.profile; | 2648 | ProfileEntry *prf = cfg.profile; |