[pacman-dev] [PATCH] reset signal handlers before running scripts/hooks

Allan McRae allan at archlinux.org
Sun Oct 21 09:19:04 UTC 2018


On 3/10/18 5:42 pm, Andrew Gregory wrote:
> 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 at gmail.com>
> ---
> 
> Hopefully nobody ignores or depends on signals outside of the POSIX
> list.  As far as I can tell, the only way to reset all signal handlers
> is to iterate over the entire range of positive integers.

I know of no other way either.  Patch looks fine.

A

> 
>  lib/libalpm/util.c                          | 20 ++++++++++++++++++++
>  test/pacman/tests/TESTS                     |  1 +
>  test/pacman/tests/scriptlet-signal-reset.py | 11 +++++++++++
>  3 files changed, 32 insertions(+)
>  create mode 100644 test/pacman/tests/scriptlet-signal-reset.py
> 
> 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));
> diff --git a/test/pacman/tests/TESTS b/test/pacman/tests/TESTS
> index b11cb511..5deb93c4 100644
> --- a/test/pacman/tests/TESTS
> +++ b/test/pacman/tests/TESTS
> @@ -150,6 +150,7 @@ TESTS += test/pacman/tests/replace102.py
>  TESTS += test/pacman/tests/replace103.py
>  TESTS += test/pacman/tests/replace104.py
>  TESTS += test/pacman/tests/replace110.py
> +TESTS += test/pacman/tests/scriptlet-signal-reset.py
>  TESTS += test/pacman/tests/scriptlet001.py
>  TESTS += test/pacman/tests/scriptlet002.py
>  TESTS += test/pacman/tests/sign001.py
> diff --git a/test/pacman/tests/scriptlet-signal-reset.py b/test/pacman/tests/scriptlet-signal-reset.py
> new file mode 100644
> index 00000000..27246d12
> --- /dev/null
> +++ b/test/pacman/tests/scriptlet-signal-reset.py
> @@ -0,0 +1,11 @@
> +self.description = "Reset signals before running scriptlets/hooks"
> +
> +p1 = pmpkg("dummy")
> +# check if SIGPIPE is ignored, it should be fatal, but GPGME ignores it
> +p1.install['post_install'] = "kill -PIPE $$; echo fail > sigpipe_was_ignored"
> +self.addpkg(p1)
> +
> +self.args = "-U %s" % p1.filename()
> +
> +self.addrule("PACMAN_RETCODE=0")
> +self.addrule("!FILE_EXIST=sigpipe_was_ignored")
> 


More information about the pacman-dev mailing list