summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAndrew Gregory <andrew.gregory.8@gmail.com>2018-10-03 00:42:38 -0700
committerAllan McRae <allan@archlinux.org>2018-10-21 19:18:29 +1000
commit9886566abb375043740167ce5066f1a186c71176 (patch)
tree2602d3412873b77e6facc3f69c5beffed9891820 /lib
parent2c91d08e62dd13979192df4a0b2ca76bde87cfd0 (diff)
downloadpacman-9886566abb375043740167ce5066f1a186c71176.tar.xz
reset signal handlers before running scripts/hooks
Front-ends or libraries may set signals to be ignored, which gets inherited across fork and exec. This can cause scripts to malfunction if they expect the signal. To make matters worse, scripts written in bash can't reset signals that were ignored when bash was started. Fixes FS#56756 Signed-off-by: Andrew Gregory <andrew.gregory.8@gmail.com> Signed-off-by: Allan McRae <allan@archlinux.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/libalpm/util.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index a06f5bfd..eaf85e93 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -548,6 +548,25 @@ static int _alpm_chroot_read_from_child(alpm_handle_t *handle, int fd,
return 0;
}
+static void _alpm_reset_signals(void)
+{
+ /* reset POSIX defined signals (see signal.h) */
+ /* there are likely more but there is no easy way
+ * to get the full list of valid signals */
+ int *i, signals[] = {
+ SIGABRT, SIGALRM, SIGBUS, SIGCHLD, SIGCONT, SIGFPE, SIGHUP, SIGILL,
+ SIGINT, SIGKILL, SIGPIPE, SIGQUIT, SIGSEGV, SIGSTOP, SIGTERM, SIGTSTP,
+ SIGTTIN, SIGTTOU, SIGUSR1, SIGUSR2, SIGPOLL, SIGPROF, SIGSYS, SIGTRAP,
+ SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ,
+ 0
+ };
+ struct sigaction def;
+ def.sa_handler = SIG_DFL;
+ for(i = signals; *i; i++) {
+ sigaction(*i, &def, NULL);
+ }
+}
+
/** Execute a command with arguments in a chroot.
* @param handle the context handle
* @param cmd command to execute
@@ -633,6 +652,7 @@ int _alpm_run_chroot(alpm_handle_t *handle, const char *cmd, char *const argv[],
exit(1);
}
umask(0022);
+ _alpm_reset_signals();
execv(cmd, argv);
/* execv only returns if there was an error */
fprintf(stderr, _("call to execv failed (%s)\n"), strerror(errno));