summaryrefslogtreecommitdiffstats
path: root/login-utils
diff options
context:
space:
mode:
authorKarel Zak2017-09-07 10:31:21 +0200
committerKarel Zak2017-09-18 11:49:11 +0200
commit0214f438a6591e9b3b09e3f02329677f1b815223 (patch)
treeead737654436b6fd0b0c2c43b36677a3f488f164 /login-utils
parentrunuser: fix linking (diff)
downloadkernel-qcow2-util-linux-0214f438a6591e9b3b09e3f02329677f1b815223.tar.gz
kernel-qcow2-util-linux-0214f438a6591e9b3b09e3f02329677f1b815223.tar.xz
kernel-qcow2-util-linux-0214f438a6591e9b3b09e3f02329677f1b815223.zip
su: (pty) fix child signal mask usage
The signal mask is used by pty_init_slave(), but it has never been uninitialized before fork(), so child gets 0 as a mask :-( Note that script(1) has no this issue because it opens signal-fd before fork(). Reported-by: Vaclav Dolezal <vdolezal@redhat.com> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'login-utils')
-rw-r--r--login-utils/su-common.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/login-utils/su-common.c b/login-utils/su-common.c
index 520ecb342..bfccb4643 100644
--- a/login-utils/su-common.c
+++ b/login-utils/su-common.c
@@ -135,7 +135,6 @@ struct su_context {
pid_t child; /* fork() baby */
struct sigaction oldact[SIGNALS_IDX_COUNT]; /* original sigactions indexed by SIG*_IDX */
- sigset_t oldsig; /* original signal mask */
#ifdef USE_PTY
struct termios stdin_attrs; /* stdin and slave terminal runtime attributes */
@@ -144,6 +143,7 @@ struct su_context {
int pty_sigfd; /* signalfd() */
int poll_timeout;
struct winsize win; /* terminal window size */
+ sigset_t oldsig; /* original signal mask */
#endif
unsigned int runuser :1, /* flase=su, true=runuser */
runuser_uopt :1, /* runuser -u specified */
@@ -460,7 +460,7 @@ static void pty_proxy_master(struct su_context *su)
* TODO: script(1) initializes this FD before fork, good or bad idea?
*/
sigfillset(&ourset);
- if (sigprocmask(SIG_BLOCK, &ourset, &su->oldsig)) {
+ if (sigprocmask(SIG_BLOCK, &ourset, NULL)) {
warn(_("cannot block signals"));
caught_signal = true;
return;
@@ -735,7 +735,7 @@ static void parent_setup_signals(struct su_context *su)
DBG(SIG, ul_debug("initialize signals"));
sigfillset(&ourset);
- if (sigprocmask(SIG_BLOCK, &ourset, &su->oldsig)) {
+ if (sigprocmask(SIG_BLOCK, &ourset, NULL)) {
warn(_("cannot block signals"));
caught_signal = true;
}
@@ -800,6 +800,9 @@ static void create_watching_parent(struct su_context *su)
DBG(MISC, ul_debug("forking..."));
#ifdef USE_PTY
+ /* no-op, just save original signal mask to oldsig */
+ sigprocmask(SIG_BLOCK, NULL, &su->oldsig);
+
if (su->pty)
pty_create(su);
#endif