summaryrefslogtreecommitdiffstats
path: root/login-utils/login.c
diff options
context:
space:
mode:
authorTobias Stoeckmann2017-09-25 21:54:11 +0200
committerKarel Zak2017-09-26 12:03:24 +0200
commitf17bda66bd440fe8375f5fd13e2efa6bd3a0c942 (patch)
treeeab5e1fef8a164903f27bdcc8025f69d5fea7cbd /login-utils/login.c
parentdocs: add 2.30.2 to ReleaseNotes (diff)
downloadkernel-qcow2-util-linux-f17bda66bd440fe8375f5fd13e2efa6bd3a0c942.tar.gz
kernel-qcow2-util-linux-f17bda66bd440fe8375f5fd13e2efa6bd3a0c942.tar.xz
kernel-qcow2-util-linux-f17bda66bd440fe8375f5fd13e2efa6bd3a0c942.zip
login: fix signal race
The functions warnx(3) and gettext(3) are not safe to use within signal handlers and should be avoided. Preparing the message beforehand and calling write(2) as well as calling _exit(2) solves the problem. [kzak@redhat.com: - use program_invocation_short_name rather than argv[0], - use ignore_result() to keep compiler happy] Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'login-utils/login.c')
-rw-r--r--login-utils/login.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/login-utils/login.c b/login-utils/login.c
index 7f311536e..ae0d66d0a 100644
--- a/login-utils/login.c
+++ b/login-utils/login.c
@@ -139,6 +139,7 @@ struct login_context {
static unsigned int timeout = LOGIN_TIMEOUT;
static int child_pid = 0;
static volatile int got_sig = 0;
+static char timeout_msg[128];
#ifdef LOGIN_CHOWN_VCS
/* true if the filedescriptor fd is a console tty, very Linux specific */
@@ -174,15 +175,14 @@ timedout2(int sig __attribute__ ((__unused__)))
tcgetattr(0, &ti);
ti.c_lflag |= ECHO;
tcsetattr(0, TCSANOW, &ti);
- exit(EXIT_SUCCESS); /* %% */
+ _exit(EXIT_SUCCESS); /* %% */
}
static void timedout(int sig __attribute__ ((__unused__)))
{
signal(SIGALRM, timedout2);
alarm(10);
- /* TRANSLATORS: The standard value for %u is 60. */
- warnx(_("timed out after %u seconds"), timeout);
+ ignore_result( write(STDERR_FILENO, timeout_msg, strlen(timeout_msg)) );
signal(SIGALRM, SIG_IGN);
alarm(0);
timedout2(0);
@@ -1134,6 +1134,15 @@ int main(int argc, char **argv)
timeout = (unsigned int)getlogindefs_num("LOGIN_TIMEOUT", LOGIN_TIMEOUT);
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /* TRANSLATORS: The standard value for %u is 60. */
+ snprintf(timeout_msg, sizeof(timeout_msg),
+ _("%s: timed out after %u seconds"),
+ program_invocation_short_name, timeout);
+
signal(SIGALRM, timedout);
(void) sigaction(SIGALRM, NULL, &act);
act.sa_flags &= ~SA_RESTART;
@@ -1142,10 +1151,6 @@ int main(int argc, char **argv)
signal(SIGQUIT, SIG_IGN);
signal(SIGINT, SIG_IGN);
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
-
setpriority(PRIO_PROCESS, 0, 0);
initproctitle(argc, argv);