From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id 21828138454 for ; Fri, 11 Sep 2015 07:54:07 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 79FAC21C048; Fri, 11 Sep 2015 07:53:40 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id F3B1621C046 for ; Fri, 11 Sep 2015 07:53:34 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 15F1A340A6A for ; Fri, 11 Sep 2015 07:53:29 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id C519A185 for ; Fri, 11 Sep 2015 07:53:27 +0000 (UTC) From: "Mike Frysinger" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Mike Frysinger" Message-ID: <1361595167.c119fe8e393540224c803ab5036ddb80b800716c.vapier@gentoo> Subject: [gentoo-commits] proj/sandbox:master commit in: src/ X-VCS-Repository: proj/sandbox X-VCS-Files: src/sandbox.c X-VCS-Directories: src/ X-VCS-Committer: vapier X-VCS-Committer-Name: Mike Frysinger X-VCS-Revision: c119fe8e393540224c803ab5036ddb80b800716c X-VCS-Branch: master Date: Fri, 11 Sep 2015 07:53:27 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: b5ef2e68-e9c4-43dc-82a2-7c549e4c88ff X-Archives-Hash: 40c0b22a2996cc6d82a90e2d59ea0485 commit: c119fe8e393540224c803ab5036ddb80b800716c Author: Mike Frysinger gentoo org> AuthorDate: Sat Feb 23 04:52:47 2013 +0000 Commit: Mike Frysinger gentoo org> CommitDate: Sat Feb 23 04:52:47 2013 +0000 URL: https://gitweb.gentoo.org/proj/sandbox.git/commit/?id=c119fe8e sandbox: pass child signals back up to the parent We were incorrectly passing signal information back up to the parent. See the URL for more information. URL: http://www.cons.org/cracauer/sigint.html Signed-off-by: Mike Frysinger gentoo.org> src/sandbox.c | 72 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/src/sandbox.c b/src/sandbox.c index 3783bca..c2a1d25 100644 --- a/src/sandbox.c +++ b/src/sandbox.c @@ -131,7 +131,7 @@ static void print_sandbox_log(char *sandbox_log) static void stop(int signum) { if (0 == stop_called) { - stop_called = 1; + stop_called = signum; sb_warn("caught signal %d in pid %d", signum, getpid()); } else sb_warn("signal already caught and busy still cleaning up!"); @@ -140,7 +140,7 @@ static void stop(int signum) static void usr1_handler(int signum, siginfo_t *siginfo, void *ucontext) { if (0 == stop_called) { - stop_called = 1; + stop_called = signum; sb_warn("caught signal %d in pid %d", signum, getpid()); /* FIXME: This is really bad form, as we should kill the whole process @@ -183,12 +183,11 @@ static int spawn_shell(char *argv_bash[], char **env, int debug) sb_pwarn("failed to waitpid for child"); return 1; } else if (status != 0) { - if (WIFSIGNALED(status)) { + if (WIFSIGNALED(status)) psignal(WTERMSIG(status), "Sandboxed process killed by signal"); - return 128 + WTERMSIG(status); - } else if (debug) + else if (debug) sb_warn("process returned with failed exit status %d!", WEXITSTATUS(status)); - return WEXITSTATUS(status) ? : 1; + return status; } return 0; @@ -196,8 +195,6 @@ static int spawn_shell(char *argv_bash[], char **env, int debug) int main(int argc, char **argv) { - struct sigaction act_new; - int sandbox_log_presence = 0; struct sandbox_info_t sandbox_info; @@ -308,26 +305,39 @@ int main(int argc, char **argv) } } - /* set up the required signal handlers ... but allow SIGHUP to be - * ignored in case people are running `nohup ...` #217898 - */ - if (signal(SIGHUP, &stop) == SIG_IGN) - signal(SIGHUP, SIG_IGN); -#define wsignal(sig, act) \ + /* Set up the required signal handlers */ + int sigs[] = { SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGUSR1, }; + struct sigaction act_new, act_old[ARRAY_SIZE(sigs)]; + size_t si = 0; + +#define wsigaction() \ do { \ - sighandler_t _old = signal(sig, act); \ - if (_old == SIG_ERR) \ - sb_pwarn("unable to bind signal %s", #sig); \ - else if (_old != SIG_DFL && _old != SIG_IGN) \ - sb_warn("signal %s already had a handler ...", #sig); \ + if (sigaction(sigs[si], &act_new, &act_old[si])) \ + sb_pwarn("unable to bind signal %i", sigs[si]); \ + else if (act_old[si].sa_handler != SIG_DFL && \ + act_old[si].sa_handler != SIG_IGN) \ + sb_warn("signal %i already had a handler ...", sigs[si]); \ + ++si; \ } while (0) - wsignal(SIGINT, &stop); - wsignal(SIGQUIT, &stop); - wsignal(SIGTERM, &stop); + + sigemptyset(&act_new.sa_mask); + act_new.sa_sigaction = NULL; + act_new.sa_handler = stop; + act_new.sa_flags = SA_RESTART; + wsigaction(); + wsigaction(); + wsigaction(); + wsigaction(); + + sigemptyset(&act_new.sa_mask); + act_new.sa_handler = NULL; act_new.sa_sigaction = usr1_handler; - sigemptyset (&act_new.sa_mask); act_new.sa_flags = SA_SIGINFO | SA_RESTART; - sigaction (SIGUSR1, &act_new, NULL); + wsigaction(); + + /* Allow SIGHUP to be ignored in case people are running `nohup ...` #217898 */ + if (act_old[0].sa_handler == SIG_IGN) + sigaction(SIGHUP, &act_old[0], NULL); /* STARTING PROTECTED ENVIRONMENT */ dputs("The protected environment has been started."); @@ -353,6 +363,20 @@ int main(int argc, char **argv) } else dputs(sandbox_footer); + /* Do the right thing and pass the signal back up. See: + * http://www.cons.org/cracauer/sigint.html + */ + if (stop_called != SIGUSR1 && WIFSIGNALED(shell_exit)) { + int signum = WTERMSIG(shell_exit); + for (si = 0; si < ARRAY_SIZE(sigs); ++si) + sigaction(sigs[si], &act_old[si], NULL); + kill(getpid(), signum); + return 128 + signum; + } else if (WIFEXITED(shell_exit)) + shell_exit = WEXITSTATUS(shell_exit); + else + shell_exit = 1; /* ??? */ + if (!is_env_on(ENV_SANDBOX_TESTING)) if (sandbox_log_presence && shell_exit == 0) shell_exit = 1;