summaryrefslogtreecommitdiff
path: root/ssh-agent.c
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2009-10-07 09:01:03 +1100
committerDarren Tucker <dtucker@zip.com.au>2009-10-07 09:01:03 +1100
commit72473c6b09b61b5ea2a7bda7728062b89a46b394 (patch)
treec8166be5f1fdfcd660647955cf7607a634df4a76 /ssh-agent.c
parent7bee06ab3b84c9f141666cc47abb349067551ef6 (diff)
- djm@cvs.openbsd.org 2009/09/01 14:43:17
[ssh-agent.c] 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 'ssh-agent.c')
-rw-r--r--ssh-agent.c36
1 files changed, 15 insertions, 21 deletions
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;