summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--ssh-agent.c36
2 files changed, 22 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 5fbca0934..e961d1a2f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -73,6 +73,13 @@
73 - djm@cvs.openbsd.org 2009/08/31 21:01:29 73 - djm@cvs.openbsd.org 2009/08/31 21:01:29
74 [sftp-server.8] 74 [sftp-server.8]
75 document -e and -h; prodded by jmc@ 75 document -e and -h; prodded by jmc@
76 - djm@cvs.openbsd.org 2009/09/01 14:43:17
77 [ssh-agent.c]
78 fix a race condition in ssh-agent that could result in a wedged or
79 spinning agent: don't read off the end of the allocated fd_sets, and
80 don't issue blocking read/write on agent sockets - just fall back to
81 select() on retriable read/write errors. bz#1633 reported and tested
82 by "noodle10000 AT googlemail.com"; ok dtucker@ markus@
76 83
7720091002 8420091002
78 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. 85 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps.
diff --git a/ssh-agent.c b/ssh-agent.c
index f77dea3a6..df3a87d9a 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.161 2009/03/23 19:38:04 tobias Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.162 2009/09/01 14:43:17 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -919,11 +919,11 @@ after_select(fd_set *readset, fd_set *writeset)
919 socklen_t slen; 919 socklen_t slen;
920 char buf[1024]; 920 char buf[1024];
921 int len, sock; 921 int len, sock;
922 u_int i; 922 u_int i, orig_alloc;
923 uid_t euid; 923 uid_t euid;
924 gid_t egid; 924 gid_t egid;
925 925
926 for (i = 0; i < sockets_alloc; i++) 926 for (i = 0, orig_alloc = sockets_alloc; i < orig_alloc; i++)
927 switch (sockets[i].type) { 927 switch (sockets[i].type) {
928 case AUTH_UNUSED: 928 case AUTH_UNUSED:
929 break; 929 break;
@@ -956,16 +956,13 @@ after_select(fd_set *readset, fd_set *writeset)
956 case AUTH_CONNECTION: 956 case AUTH_CONNECTION:
957 if (buffer_len(&sockets[i].output) > 0 && 957 if (buffer_len(&sockets[i].output) > 0 &&
958 FD_ISSET(sockets[i].fd, writeset)) { 958 FD_ISSET(sockets[i].fd, writeset)) {
959 do { 959 len = write(sockets[i].fd,
960 len = write(sockets[i].fd, 960 buffer_ptr(&sockets[i].output),
961 buffer_ptr(&sockets[i].output), 961 buffer_len(&sockets[i].output));
962 buffer_len(&sockets[i].output)); 962 if (len == -1 && (errno == EAGAIN ||
963 if (len == -1 && (errno == EAGAIN || 963 errno == EWOULDBLOCK ||
964 errno == EINTR || 964 errno == EINTR))
965 errno == EWOULDBLOCK)) 965 continue;
966 continue;
967 break;
968 } while (1);
969 if (len <= 0) { 966 if (len <= 0) {
970 close_socket(&sockets[i]); 967 close_socket(&sockets[i]);
971 break; 968 break;
@@ -973,14 +970,11 @@ after_select(fd_set *readset, fd_set *writeset)
973 buffer_consume(&sockets[i].output, len); 970 buffer_consume(&sockets[i].output, len);
974 } 971 }
975 if (FD_ISSET(sockets[i].fd, readset)) { 972 if (FD_ISSET(sockets[i].fd, readset)) {
976 do { 973 len = read(sockets[i].fd, buf, sizeof(buf));
977 len = read(sockets[i].fd, buf, sizeof(buf)); 974 if (len == -1 && (errno == EAGAIN ||
978 if (len == -1 && (errno == EAGAIN || 975 errno == EWOULDBLOCK ||
979 errno == EINTR || 976 errno == EINTR))
980 errno == EWOULDBLOCK)) 977 continue;
981 continue;
982 break;
983 } while (1);
984 if (len <= 0) { 978 if (len <= 0) {
985 close_socket(&sockets[i]); 979 close_socket(&sockets[i]);
986 break; 980 break;