summaryrefslogtreecommitdiff
path: root/ssh-agent.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2018-08-24 12:49:36 +0100
committerColin Watson <cjwatson@debian.org>2018-08-24 12:49:36 +0100
commite6547182a54f0f268ee36e7c99319eeddffbaff2 (patch)
tree417527229ad3f3764ba71ea383f478a168895087 /ssh-agent.c
parented6ae9c1a014a08ff5db3d768f01f2e427eeb476 (diff)
parent71508e06fab14bc415a79a08f5535ad7bffa93d9 (diff)
Import openssh_7.8p1.orig.tar.gz
Diffstat (limited to 'ssh-agent.c')
-rw-r--r--ssh-agent.c63
1 files changed, 50 insertions, 13 deletions
diff --git a/ssh-agent.c b/ssh-agent.c
index 2a4578b03..d8a8260f9 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.228 2018/02/23 15:58:37 markus Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.231 2018/05/11 03:38:51 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
@@ -709,7 +709,7 @@ process_message(u_int socknum)
709 709
710 debug("%s: socket %u (fd=%d) type %d", __func__, socknum, e->fd, type); 710 debug("%s: socket %u (fd=%d) type %d", __func__, socknum, e->fd, type);
711 711
712 /* check wheter agent is locked */ 712 /* check whether agent is locked */
713 if (locked && type != SSH_AGENTC_UNLOCK) { 713 if (locked && type != SSH_AGENTC_UNLOCK) {
714 sshbuf_reset(e->request); 714 sshbuf_reset(e->request);
715 switch (type) { 715 switch (type) {
@@ -886,10 +886,10 @@ handle_conn_write(u_int socknum)
886} 886}
887 887
888static void 888static void
889after_poll(struct pollfd *pfd, size_t npfd) 889after_poll(struct pollfd *pfd, size_t npfd, u_int maxfds)
890{ 890{
891 size_t i; 891 size_t i;
892 u_int socknum; 892 u_int socknum, activefds = npfd;
893 893
894 for (i = 0; i < npfd; i++) { 894 for (i = 0; i < npfd; i++) {
895 if (pfd[i].revents == 0) 895 if (pfd[i].revents == 0)
@@ -909,19 +909,30 @@ after_poll(struct pollfd *pfd, size_t npfd)
909 /* Process events */ 909 /* Process events */
910 switch (sockets[socknum].type) { 910 switch (sockets[socknum].type) {
911 case AUTH_SOCKET: 911 case AUTH_SOCKET:
912 if ((pfd[i].revents & (POLLIN|POLLERR)) != 0 && 912 if ((pfd[i].revents & (POLLIN|POLLERR)) == 0)
913 handle_socket_read(socknum) != 0) 913 break;
914 close_socket(&sockets[socknum]); 914 if (npfd > maxfds) {
915 debug3("out of fds (active %u >= limit %u); "
916 "skipping accept", activefds, maxfds);
917 break;
918 }
919 if (handle_socket_read(socknum) == 0)
920 activefds++;
915 break; 921 break;
916 case AUTH_CONNECTION: 922 case AUTH_CONNECTION:
917 if ((pfd[i].revents & (POLLIN|POLLERR)) != 0 && 923 if ((pfd[i].revents & (POLLIN|POLLERR)) != 0 &&
918 handle_conn_read(socknum) != 0) { 924 handle_conn_read(socknum) != 0) {
919 close_socket(&sockets[socknum]); 925 goto close_sock;
920 break;
921 } 926 }
922 if ((pfd[i].revents & (POLLOUT|POLLHUP)) != 0 && 927 if ((pfd[i].revents & (POLLOUT|POLLHUP)) != 0 &&
923 handle_conn_write(socknum) != 0) 928 handle_conn_write(socknum) != 0) {
929 close_sock:
930 if (activefds == 0)
931 fatal("activefds == 0 at close_sock");
924 close_socket(&sockets[socknum]); 932 close_socket(&sockets[socknum]);
933 activefds--;
934 break;
935 }
925 break; 936 break;
926 default: 937 default:
927 break; 938 break;
@@ -930,7 +941,7 @@ after_poll(struct pollfd *pfd, size_t npfd)
930} 941}
931 942
932static int 943static int
933prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp) 944prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp, u_int maxfds)
934{ 945{
935 struct pollfd *pfd = *pfdp; 946 struct pollfd *pfd = *pfdp;
936 size_t i, j, npfd = 0; 947 size_t i, j, npfd = 0;
@@ -959,6 +970,16 @@ prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp)
959 for (i = j = 0; i < sockets_alloc; i++) { 970 for (i = j = 0; i < sockets_alloc; i++) {
960 switch (sockets[i].type) { 971 switch (sockets[i].type) {
961 case AUTH_SOCKET: 972 case AUTH_SOCKET:
973 if (npfd > maxfds) {
974 debug3("out of fds (active %zu >= limit %u); "
975 "skipping arming listener", npfd, maxfds);
976 break;
977 }
978 pfd[j].fd = sockets[i].fd;
979 pfd[j].revents = 0;
980 pfd[j].events = POLLIN;
981 j++;
982 break;
962 case AUTH_CONNECTION: 983 case AUTH_CONNECTION:
963 pfd[j].fd = sockets[i].fd; 984 pfd[j].fd = sockets[i].fd;
964 pfd[j].revents = 0; 985 pfd[j].revents = 0;
@@ -1059,6 +1080,7 @@ main(int ac, char **av)
1059 int timeout = -1; /* INFTIM */ 1080 int timeout = -1; /* INFTIM */
1060 struct pollfd *pfd = NULL; 1081 struct pollfd *pfd = NULL;
1061 size_t npfd = 0; 1082 size_t npfd = 0;
1083 u_int maxfds;
1062 1084
1063 ssh_malloc_init(); /* must be called before any mallocs */ 1085 ssh_malloc_init(); /* must be called before any mallocs */
1064 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 1086 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
@@ -1070,6 +1092,9 @@ main(int ac, char **av)
1070 1092
1071 platform_disable_tracing(0); /* strict=no */ 1093 platform_disable_tracing(0); /* strict=no */
1072 1094
1095 if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
1096 fatal("%s: getrlimit: %s", __progname, strerror(errno));
1097
1073#ifdef WITH_OPENSSL 1098#ifdef WITH_OPENSSL
1074 OpenSSL_add_all_algorithms(); 1099 OpenSSL_add_all_algorithms();
1075#endif 1100#endif
@@ -1166,6 +1191,18 @@ main(int ac, char **av)
1166 printf("echo Agent pid %ld killed;\n", (long)pid); 1191 printf("echo Agent pid %ld killed;\n", (long)pid);
1167 exit(0); 1192 exit(0);
1168 } 1193 }
1194
1195 /*
1196 * Minimum file descriptors:
1197 * stdio (3) + listener (1) + syslog (1 maybe) + connection (1) +
1198 * a few spare for libc / stack protectors / sanitisers, etc.
1199 */
1200#define SSH_AGENT_MIN_FDS (3+1+1+1+4)
1201 if (rlim.rlim_cur < SSH_AGENT_MIN_FDS)
1202 fatal("%s: file descriptior rlimit %lld too low (minimum %u)",
1203 __progname, (long long)rlim.rlim_cur, SSH_AGENT_MIN_FDS);
1204 maxfds = rlim.rlim_cur - SSH_AGENT_MIN_FDS;
1205
1169 parent_pid = getpid(); 1206 parent_pid = getpid();
1170 1207
1171 if (agentsocket == NULL) { 1208 if (agentsocket == NULL) {
@@ -1285,7 +1322,7 @@ skip:
1285 platform_pledge_agent(); 1322 platform_pledge_agent();
1286 1323
1287 while (1) { 1324 while (1) {
1288 prepare_poll(&pfd, &npfd, &timeout); 1325 prepare_poll(&pfd, &npfd, &timeout, maxfds);
1289 result = poll(pfd, npfd, timeout); 1326 result = poll(pfd, npfd, timeout);
1290 saved_errno = errno; 1327 saved_errno = errno;
1291 if (parent_alive_interval != 0) 1328 if (parent_alive_interval != 0)
@@ -1296,7 +1333,7 @@ skip:
1296 continue; 1333 continue;
1297 fatal("poll: %s", strerror(saved_errno)); 1334 fatal("poll: %s", strerror(saved_errno));
1298 } else if (result > 0) 1335 } else if (result > 0)
1299 after_poll(pfd, npfd); 1336 after_poll(pfd, npfd, maxfds);
1300 } 1337 }
1301 /* NOTREACHED */ 1338 /* NOTREACHED */
1302} 1339}