Skip to contentSkip to conversation

login: fix signal race

PATCH In review Tobias Stoeckmann 2 participants 2 messages Sep 25, 2017 – Sep 26, 2017 Util-Linux package

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 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.

---
 login-utils/login.c | 17 ++++++++++-------
 po/ca.po            |  6 +++---
 po/cs.po            |  6 +++---
 po/da.po            |  6 +++---
 po/de.po            |  6 +++---
 po/es.po            |  6 +++---
 po/et.po            |  6 +++---
 po/eu.po            |  4 ++--
 po/fi.po            |  6 +++---
 po/fr.po            |  6 +++---
 po/gl.po            |  4 ++--
 po/hr.po            |  4 ++--
 po/hu.po            |  6 +++---
 po/id.po            |  6 +++---
 po/it.po            |  6 +++---
 po/ja.po            |  6 +++---
 po/nl.po            |  6 +++---
 po/pl.po            |  6 +++---
 po/pt_BR.po         |  6 +++---
 po/ru.po            |  6 +++---
 po/sl.po            |  6 +++---
 po/sv.po            |  6 +++---
 po/tr.po            |  6 +++---
 po/uk.po            |  6 +++---
 po/util-linux.pot   |  4 ++--
 po/vi.po            |  6 +++---
 po/zh_CN.po         |  6 +++---
 po/zh_TW.po         |  6 +++---
 28 files changed, 87 insertions(+), 84 deletions(-)
login-utils/login.c +10 -7
index 7f311536e..7cccd1a0f 100644
@@ -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);
+	write(STDERR_FILENO, timeout_msg, strlen(timeout_msg));
 	signal(SIGALRM, SIG_IGN);
 	alarm(0);
 	timedout2(0);
@@ -1134,6 +1134,13 @@ 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"), argv[0], timeout);
 	signal(SIGALRM, timedout);
 	(void) sigaction(SIGALRM, NULL, &act);
 	act.sa_flags &= ~SA_RESTART;
@@ -1142,10 +1149,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);
 
po/ca.po +3 -3
index 40fa73801..cdceefd22 100644
@@ -7913,10 +7913,10 @@ msgid "user attribute not changed: %s"
 msgstr ""
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, fuzzy, c-format
-msgid "timed out after %u seconds"
-msgstr "S'ha excedit el temps d'espera per a l'entrada al cap de %d segons.\n"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: S'ha excedit el temps d'espera per a l'entrada al cap de %u segons."
 
 #: login-utils/login.c:291
 #, fuzzy, c-format
po/cs.po +3 -3
index c1cfa90e3..f1ad5d7a1 100644
@@ -7501,10 +7501,10 @@ msgid "user attribute not changed: %s"
 msgstr "vlastnost uživatele nezměněna: %s"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
-msgstr "vypršel časový limit %u sekund"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: vypršel časový limit %u sekund"
 
 #: login-utils/login.c:291
 #, c-format
po/da.po +3 -3
index bc5425afd..00fd1ce98 100644
@@ -7488,10 +7488,10 @@ msgid "user attribute not changed: %s"
 msgstr "brugerattribut blev ikke ændret: %s"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
-msgstr "udløb efter %u sekunder"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: udløb efter %u sekunder"
 
 #: login-utils/login.c:291
 #, c-format
po/de.po +3 -3
index 7caa444e2..638509cd3 100644
@@ -7522,10 +7522,10 @@ msgid "user attribute not changed: %s"
 msgstr "Benutzerattribut wurde nicht geändert: %s"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
-msgstr "Zeit überschritten nach %u Sekunden"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: Zeit überschritten nach %u Sekunden"
 
 #: login-utils/login.c:291
 #, c-format
po/es.po +3 -3
index f5901346c..595a1969d 100644
@@ -7400,10 +7400,10 @@ msgid "user attribute not changed: %s"
 msgstr "atributo de usuario no modificado: %s"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
-msgstr "superado el tiempo de espera tras %u segundos"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: superado el tiempo de espera tras %u segundos"
 
 #: login-utils/login.c:291
 #, c-format
po/et.po +3 -3
index 12d61e7d5..cebc95d77 100644
@@ -7833,10 +7833,10 @@ msgid "user attribute not changed: %s"
 msgstr ""
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, fuzzy, c-format
-msgid "timed out after %u seconds"
-msgstr "Login timed out after %d seconds\n"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: Login timed out after %u seconds"
 
 #: login-utils/login.c:291
 #, fuzzy, c-format
po/eu.po +2 -2
index e07e5d960..ce7632fdb 100644
@@ -7693,9 +7693,9 @@ msgid "user attribute not changed: %s"
 msgstr ""
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
+msgid "%s: timed out after %u seconds"
 msgstr ""
 
 #: login-utils/login.c:291
po/fi.po +3 -3
index ecf1ba436..ae4e3c71b 100644
@@ -7720,10 +7720,10 @@ msgid "user attribute not changed: %s"
 msgstr "%s: käyttäjää ei ole"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, fuzzy, c-format
-msgid "timed out after %u seconds"
-msgstr "Kirjautuminen aikakatkaistiin %d sekunnin jälkeen\n"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: Kirjautuminen aikakatkaistiin %u sekunnin jälkeen"
 
 #: login-utils/login.c:291
 #, fuzzy, c-format
po/fr.po +3 -3
index 7b1500831..d115e7b0d 100644
@@ -7400,10 +7400,10 @@ msgid "user attribute not changed: %s"
 msgstr "attribut d'utilisateur non modifié : %s"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
-msgstr "expiration du délai après %u secondes"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: expiration du délai après %u secondes"
 
 #: login-utils/login.c:291
 #, c-format
po/gl.po +2 -2
index 464a97700..d42cd686e 100644
@@ -7565,9 +7565,9 @@ msgid "user attribute not changed: %s"
 msgstr ""
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
+msgid "%s: timed out after %u seconds"
 msgstr ""
 
 #: login-utils/login.c:291
po/hr.po +2 -2
index 4d1611d39..9170512a1 100644
@@ -7409,9 +7409,9 @@ msgid "user attribute not changed: %s"
 msgstr ""
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
+msgid "%s: timed out after %u seconds"
 msgstr ""
 
 #: login-utils/login.c:291
po/hu.po +3 -3
index 04dbd0db8..58209e761 100644
@@ -7875,10 +7875,10 @@ msgid "user attribute not changed: %s"
 msgstr ""
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, fuzzy, c-format
-msgid "timed out after %u seconds"
-msgstr "A bejelentkezés %d másodperc után túllépte az időkorlátot\n"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: A bejelentkezés %u másodperc után túllépte az időkorlátot"
 
 #: login-utils/login.c:291
 #, fuzzy, c-format
po/id.po +3 -3
index eb73491f1..edd37137f 100644
@@ -7876,10 +7876,10 @@ msgid "user attribute not changed: %s"
 msgstr ""
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, fuzzy, c-format
-msgid "timed out after %u seconds"
-msgstr "Waktu habis untuk Login sesudah %d detik\n"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: Waktu habis untuk Login sesudah %u detik"
 
 #: login-utils/login.c:291
 #, fuzzy, c-format
po/it.po +3 -3
index 29ba33f6f..fdccaee98 100644
@@ -7869,10 +7869,10 @@ msgid "user attribute not changed: %s"
 msgstr ""
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, fuzzy, c-format
-msgid "timed out after %u seconds"
-msgstr "Login scaduto dopo %d secondi\n"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: Login scaduto dopo %u secondi"
 
 #: login-utils/login.c:291
 #, fuzzy, c-format
po/ja.po +3 -3
index 630727f00..5b8abf790 100644
@@ -7420,10 +7420,10 @@ msgid "user attribute not changed: %s"
 msgstr "ユーザ属性を変更しませんでした: %s"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
-msgstr "%u 秒で時間切れになりました"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: %u 秒で時間切れになりました"
 
 #: login-utils/login.c:291
 #, c-format
po/nl.po +3 -3
index 0184c8ce7..30939df5e 100644
@@ -7510,10 +7510,10 @@ msgid "user attribute not changed: %s"
 msgstr "gebruikerseigenschap is niet gewijzigd: %s"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
-msgstr "afgebroken na %u seconden"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: afgebroken na %u seconden"
 
 #: login-utils/login.c:291
 #, c-format
po/pl.po +3 -3
index 625201b11..d7a430f97 100644
@@ -7381,10 +7381,10 @@ msgid "user attribute not changed: %s"
 msgstr "atrybut użytkownika nie zmieniony: %s"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
-msgstr "przekroczony limit czasu logowania (%u s)"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: przekroczony limit czasu logowania (%u s)"
 
 #: login-utils/login.c:291
 #, c-format
po/pt_BR.po +3 -3
index 2b05cb79b..394230a75 100644
@@ -7435,10 +7435,10 @@ msgid "user attribute not changed: %s"
 msgstr "atributo de usuário não alterado: %s"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
-msgstr "tempo esgotado após %u segundos"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: tempo esgotado após %u segundos"
 
 #: login-utils/login.c:291
 #, c-format
po/ru.po +3 -3
index 1ef1d8218..b90e68e5d 100644
@@ -7497,10 +7497,10 @@ msgid "user attribute not changed: %s"
 msgstr "атрибуты пользователя не изменены: %s"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
-msgstr "истекло время ожидания в %u секунд"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: истекло время ожидания в %u секунд"
 
 #: login-utils/login.c:291
 #, c-format
po/sl.po +3 -3
index 2b06573d8..9820e5b78 100644
@@ -7885,10 +7885,10 @@ msgid "user attribute not changed: %s"
 msgstr ""
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, fuzzy, c-format
-msgid "timed out after %u seconds"
-msgstr "Prijava je potekla po %d sekundah.\n"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: Prijava je potekla po %u sekundah."
 
 #: login-utils/login.c:291
 #, fuzzy, c-format
po/sv.po +3 -3
index c2fea3598..6e6d71a4b 100644
@@ -7370,10 +7370,10 @@ msgid "user attribute not changed: %s"
 msgstr "användarattribut inte ändrat: %s"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
-msgstr "tidutlösare efter %u sekunder"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: tidutlösare efter %u sekunder"
 
 #: login-utils/login.c:291
 #, c-format
po/tr.po +3 -3
index 939650f21..1fb6dcd57 100644
@@ -7386,10 +7386,10 @@ msgid "user attribute not changed: %s"
 msgstr "kullanıcı özniteliği değişmedi: %s"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
-msgstr "%u saniye sonra zaman aşımı"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: %u saniye sonra zaman aşımı"
 
 #: login-utils/login.c:291
 #, c-format
po/uk.po +3 -3
index 78e79db63..2f7a03df9 100644
@@ -7393,10 +7393,10 @@ msgid "user attribute not changed: %s"
 msgstr "атрибут користувача не змінено: %s"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
-msgstr "час очікування було вичерпано за %u секунд"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: час очікування було вичерпано за %u секунд"
 
 #: login-utils/login.c:291
 #, c-format
po/util-linux.pot +2 -2
index 949932903..475816bdf 100644
@@ -7318,9 +7318,9 @@ msgid "user attribute not changed: %s"
 msgstr ""
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
+msgid "%s: timed out after %u seconds"
 msgstr ""
 
 #: login-utils/login.c:291
po/vi.po +3 -3
index 6d2e23fad..d07086bd9 100644
@@ -7499,10 +7499,10 @@ msgid "user attribute not changed: %s"
 msgstr "thuộc tính người dùng không thay đổi: %s"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
-msgstr "lỗi quá lâu sau %u giây"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: lỗi quá lâu sau %u giây"
 
 #: login-utils/login.c:291
 #, c-format
po/zh_CN.po +3 -3
index ed6aee077..64a596446 100644
@@ -7365,10 +7365,10 @@ msgid "user attribute not changed: %s"
 msgstr "用户属性未更改:%s"
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, c-format
-msgid "timed out after %u seconds"
-msgstr "%u 秒后超时"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: %u 秒后超时"
 
 #: login-utils/login.c:291
 #, c-format
po/zh_TW.po +3 -3
index 3d08f23da..f4b64611a 100644
@@ -7899,10 +7899,10 @@ msgid "user attribute not changed: %s"
 msgstr ""
 
 #. TRANSLATORS: The standard value for %u is 60.
-#: login-utils/login.c:185
+#: login-utils/login.c:1142
 #, fuzzy, c-format
-msgid "timed out after %u seconds"
-msgstr "已逾時之後 %u 秒"
+msgid "%s: timed out after %u seconds"
+msgstr "%s: 已逾時之後 %u 秒"
 
 #: login-utils/login.c:291
 #, fuzzy, c-format
Signature · 1 line
2.14.1
maintainer
#1 lore raw
Quoted 3 lines · Tobias Stoeckmann

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.

Applied with small changes:

Quoted 19 lines
 po/ca.po            |  6 +++---
 po/cs.po            |  6 +++---
 po/da.po            |  6 +++---
 po/de.po            |  6 +++---
 po/es.po            |  6 +++---
 po/et.po            |  6 +++---
 po/eu.po            |  4 ++--
 po/fi.po            |  6 +++---
 po/fr.po            |  6 +++---
 po/gl.po            |  4 ++--
 po/hr.po            |  4 ++--
 po/hu.po            |  6 +++---
 po/id.po            |  6 +++---
 po/it.po            |  6 +++---
 po/ja.po            |  6 +++---
 po/nl.po            |  6 +++---
 po/pl.po            |  6 +++---
 po/pt_BR.po         |  6 +++---
 po/ru.po            |  6 +++---
Quoted 8 lines
 po/sl.po            |  6 +++---
 po/sv.po            |  6 +++---
 po/tr.po            |  6 +++---
 po/uk.po            |  6 +++---
 po/util-linux.pot   |  4 ++--
 po/vi.po            |  6 +++---
 po/zh_CN.po         |  6 +++---
 po/zh_TW.po         |  6 +++---

Please, don't send patches with po/ stuff ("git checkout -f po/" is fine), it's updated before release by maintainer.

login-utils/login.c timedout2(int sig __attribute__ ((__unused__))) · line 185

Quoted 7 lines

static void timedout(int sig __attribute__ ((__unused__))) {

login-utils/login.c +1 -2
 	signal(SIGALRM, timedout2);
 	alarm(10);
-	/* TRANSLATORS: The standard value for %u is 60. */
-	warnx(_("timed out after %u seconds"), timeout);
+	write(STDERR_FILENO, timeout_msg, strlen(timeout_msg));

It seems we need our ignore_result() here to keep compiler happy, because write() is marked as warn_unused_result in glibc header files...

Quoted 4 lines
login-utils/login.c +0 -0
 	signal(SIGALRM, SIG_IGN);
 	alarm(0);
 	timedout2(0);

login-utils/login.c int main(int argc, char **argv) · line 1143

Quoted 10 lines
login-utils/login.c +7 -0
@@ -1134,6 +1134,13 @@ 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"), argv[0], timeout);

I've replaced argv[0] with program_invocation_short_name.

Thanks, good catch!

Karel

Signature · 2 lines
 Karel Zak  <[email protected]>
 http://karelzak.blogspot.com