diff options
author | Karel Zak | 2017-09-07 10:31:21 +0200 |
---|---|---|
committer | Karel Zak | 2017-09-18 11:49:11 +0200 |
commit | 0214f438a6591e9b3b09e3f02329677f1b815223 (patch) | |
tree | ead737654436b6fd0b0c2c43b36677a3f488f164 /login-utils | |
parent | runuser: fix linking (diff) | |
download | kernel-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.c | 9 |
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 |