From ab790c2880bf0f6e4d9c6fe263cbc0c2c93e3dc7 Mon Sep 17 00:00:00 2001 From: X-Ryl669 Date: Fri, 29 Sep 2023 17:33:23 +0200 Subject: [PATCH] [mdns] Fix select issue on FreeBSD. As reported in issue #1654, using select to test for a (non-blocking) connection success crashes on FreeBSD when the number of opened file descriptor is higher than FDSET_SIZE. Instead of returning with an error in that case, this commit uses poll instead that's not limited to the number of opened file descriptors, preventing an out-of-bound write. --- src/mdns_avahi.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/mdns_avahi.c b/src/mdns_avahi.c index d0102071c8..e776b10d8e 100644 --- a/src/mdns_avahi.c +++ b/src/mdns_avahi.c @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -582,8 +583,7 @@ connection_test(int family, const char *address, const char *address_log, int po struct addrinfo *ai; char strport[32]; int sock; - fd_set fdset; - struct timeval timeout = { MDNS_CONNECT_TEST_TIMEOUT, 0 }; + struct pollfd fd; socklen_t len; int flags; int error; @@ -639,10 +639,11 @@ connection_test(int family, const char *address, const char *address_log, int po // the case, but FreeBSD connect() sometimes returns immediate success. if (ret != 0) { - FD_ZERO(&fdset); - FD_SET(sock, &fdset); - - ret = select(sock + 1, NULL, &fdset, NULL, &timeout); + // Use poll here since select requires using fdset that would be overflowed in FreeBSD + fd.fd = sock; + fd.events = POLLOUT; + + ret = poll(&fd, 1, MDNS_CONNECT_TEST_TIMEOUT * 1000); if (ret < 0) { DPRINTF(E_WARN, L_MDNS, "Connection test to %s:%d failed with select error: %s\n", address_log, port, strerror(errno));