From c4c4a23bfd19c258beb7254be9d96716914ad03f Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Mon, 25 Sep 2023 10:11:14 +0200 Subject: [PATCH 1/2] DNS_Mgr: Replace ares_fds() with ares_getsock() On Slack, a user reported "fortify source" aborts within ares_fds() due to the FDs used by c-ares exceeding 1024 and thereby larger than the maximum fd value that a fd_set can hold. Switch to ares_get_socks() and poll() to avoid this. Closes #3309. --- src/DNS_Mgr.cc | 60 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/src/DNS_Mgr.cc b/src/DNS_Mgr.cc index 9b06eb3f8b..d95b1e7d50 100644 --- a/src/DNS_Mgr.cc +++ b/src/DNS_Mgr.cc @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include @@ -992,23 +992,54 @@ void DNS_Mgr::Resolve() { int nfds = 0; struct timeval *tvp, tv; - fd_set read_fds, write_fds; + struct pollfd pollfds[ARES_GETSOCK_MAXNUM]; + ares_socket_t socks[ARES_GETSOCK_MAXNUM]; tv.tv_sec = DNS_TIMEOUT; tv.tv_usec = 0; for ( int i = 0; i < MAX_PENDING_REQUESTS; i++ ) { - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - nfds = ares_fds(channel, &read_fds, &write_fds); + int nfds = 0; + int bitmap = ares_getsock(channel, socks, ARES_GETSOCK_MAXNUM); + + for ( int i = 0; i < ARES_GETSOCK_MAXNUM; i++ ) + { + bool rd = ARES_GETSOCK_READABLE(bitmap, i); + bool wr = ARES_GETSOCK_WRITABLE(bitmap, i); + if ( rd || wr ) + { + pollfds[nfds].fd = socks[i]; + pollfds[nfds].events = rd ? POLLIN : 0; + pollfds[nfds].events |= wr ? POLLOUT : 0; + ++nfds; + } + } + + // Do we have any sockets that are read or writable? if ( nfds == 0 ) break; + // poll() timeout is in milliseconds. tvp = ares_timeout(channel, &tv, &tv); - int res = select(nfds, &read_fds, &write_fds, NULL, tvp); - if ( res >= 0 ) - ares_process(channel, &read_fds, &write_fds); + int timeout_ms = tvp->tv_sec * 1000 + tvp->tv_usec / 1000; + + int res = poll(pollfds, nfds, timeout_ms); + + if ( res > 0 ) + { + for ( int i = 0; i < nfds; i++ ) + { + int rdfd = pollfds[i].revents | POLLIN ? pollfds[i].fd : ARES_SOCKET_BAD; + int wrfd = pollfds[i].revents | POLLOUT ? pollfds[i].fd : ARES_SOCKET_BAD; + + if ( rdfd != ARES_SOCKET_BAD || wrfd != ARES_SOCKET_BAD ) + ares_process_fd(channel, rdfd, wrfd); + } + } + else if ( res == 0 ) + // Do timeout processing when poll() timed out. + ares_process_fd(channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD); } } @@ -1442,11 +1473,16 @@ double DNS_Mgr::GetNextTimeout() if ( asyncs_pending == 0 ) return -1; - fd_set read_fds, write_fds; + int nfds = 0; + ares_socket_t socks[ARES_GETSOCK_MAXNUM]; + int bitmap = ares_getsock(channel, socks, ARES_GETSOCK_MAXNUM); + for ( int i = 0; i < ARES_GETSOCK_MAXNUM; i++ ) + { + if ( ARES_GETSOCK_READABLE(bitmap, i) || ARES_GETSOCK_WRITABLE(bitmap, i) ) + ++nfds; + } - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - int nfds = ares_fds(channel, &read_fds, &write_fds); + // Do we have any sockets that are read or writable? if ( nfds == 0 ) return -1; From 0668c15cf90268d7b79b5161b83aba45a9838d42 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 26 Sep 2023 09:56:50 +0200 Subject: [PATCH 2/2] auxil/libunistd: Bump for poll() inclusion --- auxil/libunistd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auxil/libunistd b/auxil/libunistd index 2766a0c45a..b38e9c8ebf 160000 --- a/auxil/libunistd +++ b/auxil/libunistd @@ -1 +1 @@ -Subproject commit 2766a0c45a6dbcdcf26cd1209a73a13323854961 +Subproject commit b38e9c8ebff08959a712a5663ba25e0624a3af00