diff options
author | Geoffrey Thomas <geofft@ldpreload.com> | 2015-10-19 19:33:28 +0530 |
---|---|---|
committer | Siddhesh Poyarekar <siddhesh@redhat.com> | 2015-10-19 19:33:28 +0530 |
commit | 2028f49dabb94bd56a85a7be16141bee4853aae6 (patch) | |
tree | 069f111a51dac97c261ca5a155f7168ea8a111b1 | |
parent | 361468f226cb99fdebd8fabb3d9428a3632dc2d1 (diff) | |
download | glibc-2028f49dabb94bd56a85a7be16141bee4853aae6.tar glibc-2028f49dabb94bd56a85a7be16141bee4853aae6.tar.gz glibc-2028f49dabb94bd56a85a7be16141bee4853aae6.tar.bz2 glibc-2028f49dabb94bd56a85a7be16141bee4853aae6.zip |
pt_chown: Clear any signal mask inherited from the parent process.
If grantpt() is called from a thread that is masking signals (for
instance, from a program using signalfd or using a dedicated
signal-handling thread), then that mask will get inherited to pt_chown.
This means that signals like SIGINT will not interrup pt_chown, so if it
hangs (e.g., because getgrnam("tty") hangs on a remote name service),
Ctrl-C will terminate the parent process but leave pt_chown around. Since
it's setuid, it's hard to kill any other way.
It is safe for pt_chown to unmask all signals, because grantpt() can be
(and usually is) called from an unprivileged process with all signals
unmasked.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | login/programs/pt_chown.c | 6 |
2 files changed, 11 insertions, 0 deletions
@@ -1,3 +1,8 @@ +2015-10-19 Geoffrey Thomas <geofft@ldpreload.com> + + * login/programs/pt_chown.c: Include signal.h + (main): Clear any signal mask from the parent process. + 2015-10-19 Joseph Myers <joseph@codesourcery.com> * configure.ac (libc_cv_gnu89_inline): Remove configure test. diff --git a/login/programs/pt_chown.c b/login/programs/pt_chown.c index e8d4716996..4f67af7d37 100644 --- a/login/programs/pt_chown.c +++ b/login/programs/pt_chown.c @@ -23,6 +23,7 @@ #include <grp.h> #include <libintl.h> #include <locale.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -148,6 +149,11 @@ main (int argc, char *argv[]) uid_t euid = geteuid (); uid_t uid = getuid (); int remaining; + sigset_t signalset; + + /* Clear any signal mask from the parent process. */ + sigemptyset (&signalset); + sigprocmask (SIG_SETMASK, &signalset, NULL); if (argc == 1 && euid == 0) { |