Bugzilla – Attachment 3142 Details for
Bug 2576
ssh-agent enters busy loop when running out of fds
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
updated to current
bz2576.diff (text/plain), 3.63 KB, created by
Damien Miller
on 2018-04-13 14:36:35 AEST
(
hide
)
Description:
updated to current
Filename:
MIME Type:
Creator:
Damien Miller
Created:
2018-04-13 14:36:35 AEST
Size:
3.63 KB
patch
obsolete
>diff --git a/ssh-agent.c b/ssh-agent.c >index ffcdb8c..e32b11a 100644 >--- a/ssh-agent.c >+++ b/ssh-agent.c >@@ -871,10 +871,10 @@ handle_conn_write(u_int socknum) > } > > static void >-after_poll(struct pollfd *pfd, size_t npfd) >+after_poll(struct pollfd *pfd, size_t npfd, u_int maxfds) > { > size_t i; >- u_int socknum; >+ u_int socknum, activefds = npfd; > > for (i = 0; i < npfd; i++) { > if (pfd[i].revents == 0) >@@ -894,18 +894,30 @@ after_poll(struct pollfd *pfd, size_t npfd) > /* Process events */ > switch (sockets[socknum].type) { > case AUTH_SOCKET: >- if ((pfd[i].revents & (POLLIN|POLLERR)) != 0) >- handle_socket_read(socknum); >+ if ((pfd[i].revents & (POLLIN|POLLERR)) == 0) >+ break; >+ if (npfd > maxfds) { >+ debug3("out of fds (active %u >= limit %u); " >+ "skipping accept", activefds, maxfds); >+ break; >+ } >+ if (handle_socket_read(socknum) == 0) >+ activefds++; > break; > case AUTH_CONNECTION: > if ((pfd[i].revents & (POLLIN|POLLERR)) != 0 && > handle_conn_read(socknum) != 0) { >- close_socket(&sockets[socknum]); >- break; >+ goto close_sock; > } > if ((pfd[i].revents & (POLLOUT|POLLHUP)) != 0 && >- handle_conn_write(socknum) != 0) >+ handle_conn_write(socknum) != 0) { >+ close_sock: >+ if (activefds == 0) >+ fatal("activefds == 0 at close_sock"); > close_socket(&sockets[socknum]); >+ activefds--; >+ break; >+ } > break; > default: > break; >@@ -914,7 +926,7 @@ after_poll(struct pollfd *pfd, size_t npfd) > } > > static int >-prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp) >+prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp, u_int maxfds) > { > struct pollfd *pfd = *pfdp; > size_t i, j, npfd = 0; >@@ -943,6 +955,16 @@ prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp) > for (i = j = 0; i < sockets_alloc; i++) { > switch (sockets[i].type) { > case AUTH_SOCKET: >+ if (npfd > maxfds) { >+ debug3("out of fds (active %zu >= limit %u); " >+ "skipping arming listener", npfd, maxfds); >+ break; >+ } >+ pfd[j].fd = sockets[i].fd; >+ pfd[j].revents = 0; >+ pfd[j].events = POLLIN; >+ j++; >+ break; > case AUTH_CONNECTION: > pfd[j].fd = sockets[i].fd; > pfd[j].revents = 0; >@@ -1041,6 +1063,7 @@ main(int ac, char **av) > int timeout = -1; /* INFTIM */ > struct pollfd *pfd = NULL; > size_t npfd = 0; >+ u_int maxfds; > > ssh_malloc_init(); /* must be called before any mallocs */ > /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ >@@ -1050,6 +1073,9 @@ main(int ac, char **av) > setegid(getgid()); > setgid(getgid()); > >+ if (getrlimit(RLIMIT_NOFILE, &rlim) == -1) >+ fatal("%s: getrlimit: %s", __progname, strerror(errno)); >+ > #ifdef WITH_OPENSSL > OpenSSL_add_all_algorithms(); > #endif >@@ -1143,6 +1169,16 @@ main(int ac, char **av) > printf("echo Agent pid %ld killed;\n", (long)pid); > exit(0); > } >+ >+ /* >+ * Minimum file descriptors: >+ * stdio (3) + listener (1) + syslog (1 maybe) + connection (1). >+ */ >+ if (rlim.rlim_cur < (3+1+1+1)) >+ fatal("%s: file descriptior rlimit %lld too low", >+ __progname, (long long)rlim.rlim_cur); >+ maxfds = rlim.rlim_cur - (3+1+1); >+ > parent_pid = getpid(); > > if (agentsocket == NULL) { >@@ -1259,7 +1295,7 @@ skip: > fatal("%s: pledge: %s", __progname, strerror(errno)); > > while (1) { >- prepare_poll(&pfd, &npfd, &timeout); >+ prepare_poll(&pfd, &npfd, &timeout, maxfds); > result = poll(pfd, npfd, timeout); > saved_errno = errno; > if (parent_alive_interval != 0) >@@ -1270,7 +1306,7 @@ skip: > continue; > fatal("poll: %s", strerror(saved_errno)); > } else if (result > 0) >- after_poll(pfd, npfd); >+ after_poll(pfd, npfd, maxfds); > } > /* NOTREACHED */ > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
dtucker
:
ok+
Actions:
View
|
Diff
Attachments on
bug 2576
:
2818
| 3142