summaryrefslogtreecommitdiff
path: root/usr.bin/ssh/ssh-agent.c
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2009-09-01 14:43:18 +0000
committerDamien Miller <djm@cvs.openbsd.org>2009-09-01 14:43:18 +0000
commit37fd8779ef76d6cf76686a771c9737aa0840f0ba (patch)
treead1ae52c288f6fcebb8b9e06dc638aed3ed5633f /usr.bin/ssh/ssh-agent.c
parent6fb41a10765db0e3b0ba0a163a759cb2564bde33 (diff)
fix a race condition in ssh-agent that could result in a wedged or
spinning agent: don't read off the end of the allocated fd_sets, and don't issue blocking read/write on agent sockets - just fall back to select() on retriable read/write errors. bz#1633 reported and tested by "noodle10000 AT googlemail.com"; ok dtucker@ markus@
Diffstat (limited to 'usr.bin/ssh/ssh-agent.c')
-rw-r--r--usr.bin/ssh/ssh-agent.c32
1 files changed, 13 insertions, 19 deletions
diff --git a/usr.bin/ssh/ssh-agent.c b/usr.bin/ssh/ssh-agent.c
index 95bb75177bd..79fcdfefa60 100644
--- a/usr.bin/ssh/ssh-agent.c
+++ b/usr.bin/ssh/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.161 2009/03/23 19:38:04 tobias Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.162 2009/09/01 14:43:17 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -905,11 +905,11 @@ after_select(fd_set *readset, fd_set *writeset)
socklen_t slen;
char buf[1024];
int len, sock;
- u_int i;
+ u_int i, orig_alloc;
uid_t euid;
gid_t egid;
- for (i = 0; i < sockets_alloc; i++)
+ for (i = 0, orig_alloc = sockets_alloc; i < orig_alloc; i++)
switch (sockets[i].type) {
case AUTH_UNUSED:
break;
@@ -942,15 +942,12 @@ after_select(fd_set *readset, fd_set *writeset)
case AUTH_CONNECTION:
if (buffer_len(&sockets[i].output) > 0 &&
FD_ISSET(sockets[i].fd, writeset)) {
- do {
- len = write(sockets[i].fd,
- buffer_ptr(&sockets[i].output),
- buffer_len(&sockets[i].output));
- if (len == -1 && (errno == EAGAIN ||
- errno == EINTR))
- continue;
- break;
- } while (1);
+ len = write(sockets[i].fd,
+ buffer_ptr(&sockets[i].output),
+ buffer_len(&sockets[i].output));
+ if (len == -1 && (errno == EAGAIN ||
+ errno == EINTR))
+ continue;
if (len <= 0) {
close_socket(&sockets[i]);
break;
@@ -958,13 +955,10 @@ after_select(fd_set *readset, fd_set *writeset)
buffer_consume(&sockets[i].output, len);
}
if (FD_ISSET(sockets[i].fd, readset)) {
- do {
- len = read(sockets[i].fd, buf, sizeof(buf));
- if (len == -1 && (errno == EAGAIN ||
- errno == EINTR))
- continue;
- break;
- } while (1);
+ len = read(sockets[i].fd, buf, sizeof(buf));
+ if (len == -1 && (errno == EAGAIN ||
+ errno == EINTR))
+ continue;
if (len <= 0) {
close_socket(&sockets[i]);
break;