summaryrefslogtreecommitdiff
path: root/lib/libc
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@cvs.openbsd.org>2010-01-13 10:20:55 +0000
committerDarren Tucker <dtucker@cvs.openbsd.org>2010-01-13 10:20:55 +0000
commit07e18b91084eaf190029df2d443d1319d1b72d15 (patch)
tree38dd4e7341e2c933da154ddac680785ff3a594f1 /lib/libc
parentf82df811b8763b9d92637e4ddf7d93d23d6cabc3 (diff)
If a process receives two different signals while in readpassphrase, only
the most recent one will be stored for later re-delivery. When the signal handlers are restored, all except the most recent signal will be lost. Replace the single variable with an array so signals are not lost. ok deraadt@
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/gen/readpassphrase.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/lib/libc/gen/readpassphrase.c b/lib/libc/gen/readpassphrase.c
index 470dc94c7c5..3f467a57332 100644
--- a/lib/libc/gen/readpassphrase.c
+++ b/lib/libc/gen/readpassphrase.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: readpassphrase.c,v 1.21 2008/01/17 16:27:07 millert Exp $ */
+/* $OpenBSD: readpassphrase.c,v 1.22 2010/01/13 10:20:54 dtucker Exp $ */
/*
* Copyright (c) 2000-2002, 2007 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -31,7 +31,7 @@
#include <unistd.h>
#include <readpassphrase.h>
-static volatile sig_atomic_t signo;
+static volatile sig_atomic_t signo[_NSIG];
static void handler(int);
@@ -39,7 +39,7 @@ char *
readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
{
ssize_t nr;
- int input, output, save_errno;
+ int input, output, save_errno, i, need_restart;
char ch, *p, *end;
struct termios term, oterm;
struct sigaction sa, savealrm, saveint, savehup, savequit, saveterm;
@@ -52,9 +52,11 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
}
restart:
- signo = 0;
+ for (i = 0; i < _NSIG; i++)
+ signo[i] = 0;
nr = -1;
save_errno = 0;
+ need_restart = 0;
/*
* Read and write to /dev/tty if available. If not, read from
* stdin and write to stderr unless a tty is required.
@@ -103,7 +105,7 @@ restart:
}
/* No I/O if we are already backgrounded. */
- if (signo != SIGTTOU && signo != SIGTTIN) {
+ if (signo[SIGTTOU] != 1 && signo[SIGTTIN] != 1) {
if (!(flags & RPP_STDIN))
(void)write(output, prompt, strlen(prompt));
end = buf + bufsiz - 1;
@@ -149,15 +151,19 @@ restart:
* If we were interrupted by a signal, resend it to ourselves
* now that we have restored the signal handlers.
*/
- if (signo) {
- kill(getpid(), signo);
- switch (signo) {
- case SIGTSTP:
- case SIGTTIN:
- case SIGTTOU:
- goto restart;
+ for (i = 0; i < _NSIG; i++) {
+ if (signo[i]) {
+ kill(getpid(), i);
+ switch (i) {
+ case SIGTSTP:
+ case SIGTTIN:
+ case SIGTTOU:
+ need_restart = 1;
+ }
}
}
+ if (need_restart)
+ goto restart;
if (save_errno)
errno = save_errno;
@@ -175,5 +181,5 @@ getpass(const char *prompt)
static void handler(int s)
{
- signo = s;
+ signo[s] = 1;
}