diff options
author | Colin Watson <cjwatson@debian.org> | 2018-08-24 12:49:36 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2018-08-24 12:49:36 +0100 |
commit | e6547182a54f0f268ee36e7c99319eeddffbaff2 (patch) | |
tree | 417527229ad3f3764ba71ea383f478a168895087 /ssh-agent.c | |
parent | ed6ae9c1a014a08ff5db3d768f01f2e427eeb476 (diff) | |
parent | 71508e06fab14bc415a79a08f5535ad7bffa93d9 (diff) |
Import openssh_7.8p1.orig.tar.gz
Diffstat (limited to 'ssh-agent.c')
-rw-r--r-- | ssh-agent.c | 63 |
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 | ||
888 | static void | 888 | static void |
889 | after_poll(struct pollfd *pfd, size_t npfd) | 889 | after_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 | ||
932 | static int | 943 | static int |
933 | prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp) | 944 | prepare_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 | } |