summaryrefslogtreecommitdiffstats
path: root/login-utils
diff options
context:
space:
mode:
authorKarel Zak2017-08-11 17:05:00 +0200
committerKarel Zak2017-09-18 11:48:56 +0200
commit8ce9c38690103fa18fc17fa209996ce747186cd4 (patch)
tree6f0ac7897a3519f166f97b6f524e63d290acf168 /login-utils
parentsu: clean up signals usage (diff)
downloadkernel-qcow2-util-linux-8ce9c38690103fa18fc17fa209996ce747186cd4.tar.gz
kernel-qcow2-util-linux-8ce9c38690103fa18fc17fa209996ce747186cd4.tar.xz
kernel-qcow2-util-linux-8ce9c38690103fa18fc17fa209996ce747186cd4.zip
su: unblock signals is all initialized
This patch a little bit reorders signals initialization. The original code unblocks SIGINT SIGQUIT before signal handler is set for the signals. It means there is a small possible race. It seems better to compose wanted mask, setup handlers and then unblock all the wanted signals. Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'login-utils')
-rw-r--r--login-utils/su-common.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/login-utils/su-common.c b/login-utils/su-common.c
index 542f9f07d..d2b0ad1ea 100644
--- a/login-utils/su-common.c
+++ b/login-utils/su-common.c
@@ -364,12 +364,9 @@ static void create_watching_parent(struct su_context *su)
warn(_("cannot change directory to %s"), "/");
/*
+ * Signals setup
+ *
* 1) block all signals
- * 2) add handler for SIGTERM
- * 3) unblock signals:
- * - SIGINT SIGQUIT (if no session)
- * - SIGTERM SIGALRM
- * 4) add handler for SIGINT SIGQUIT (if no session)
*/
sigfillset(&ourset);
if (sigprocmask(SIG_BLOCK, &ourset, NULL)) {
@@ -382,32 +379,51 @@ static void create_watching_parent(struct su_context *su)
action.sa_handler = su_catch_sig;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
+
sigemptyset(&ourset);
+ /* 2a) add wanted signals to the mask (for session) */
if (!su->same_session
&& (sigaddset(&ourset, SIGINT)
|| sigaddset(&ourset, SIGQUIT))) {
- warn(_("cannot set signal handler"));
+ warn(_("cannot initialize signal mask for session"));
caught_signal = true;
}
+ /* 2b) add wanted generic signals to the mask */
if (!caught_signal
&& (sigaddset(&ourset, SIGTERM)
- || sigaddset(&ourset, SIGALRM)
- || sigaction(SIGTERM, &action, &oldact[SIGTERM_IDX])
- || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) {
+ || sigaddset(&ourset, SIGALRM))) {
- warn(_("cannot set signal handler"));
+ warn(_("cannot initialize signal mask"));
caught_signal = true;
}
+
+ /* 3a) set signal handlers (for session) */
if (!caught_signal
&& !su->same_session
&& (sigaction(SIGINT, &action, &oldact[SIGINT_IDX])
|| sigaction(SIGQUIT, &action, &oldact[SIGQUIT_IDX]))) {
+ warn(_("cannot set signal handler for session"));
+ caught_signal = true;
+ }
+
+ /* 3b) set signal handlers */
+ if (!caught_signal
+ && sigaction(SIGTERM, &action, &oldact[SIGTERM_IDX])) {
+
warn(_("cannot set signal handler"));
caught_signal = true;
}
+
+ /* 4) unblock wanted signals */
+ if (!caught_signal
+ && sigprocmask(SIG_UNBLOCK, &ourset, NULL)) {
+
+ warn(_("cannot set signal mask"));
+ caught_signal = true;
+ }
}
/*