]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Use sock->nchildren instead of mgr->nworkers when initializing NM
authorOndřej Surý <ondrej@isc.org>
Thu, 3 Dec 2020 16:58:10 +0000 (17:58 +0100)
committerOndřej Surý <ondrej@sury.org>
Wed, 9 Dec 2020 09:46:16 +0000 (10:46 +0100)
On Windows, we were limiting the number of listening children to just 1,
but we were then iterating on mgr->nworkers.  That lead to scheduling
more async_*listen() than actually allocated and out-of-bound read-write
operation on the heap.

(cherry picked from commit 87c5867202935c59dfe66321238275ba4a953b53)

lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/netmgr.c
lib/isc/netmgr/tcp.c
lib/isc/netmgr/tcpdns.c
lib/isc/netmgr/udp.c
lib/isc/netmgr/uv-compat.c

index 17e3e362766224c02ae87c544657f2994803f9bf..1997ec1cc3e0f29a504991f66cc35e6ca7da0353 100644 (file)
@@ -724,7 +724,7 @@ struct isc_nmsocket {
 
        /*% Child sockets for multi-socket setups */
        isc_nmsocket_t *children;
-       int nchildren;
+       uint_fast32_t nchildren;
        isc_nmiface_t *iface;
        isc_nmhandle_t *statichandle;
        isc_nmhandle_t *outerhandle;
index 03928224f8fdf6d17f67bec2125158091bf4b743..feb21c24da0b09602e39f25fff09cfc67785f3f3 100644 (file)
@@ -913,7 +913,7 @@ nmsocket_cleanup(isc_nmsocket_t *sock, bool dofree FLARG) {
                 * We shouldn't be here unless there are no active handles,
                 * so we can clean up and free the children.
                 */
-               for (int i = 0; i < sock->nchildren; i++) {
+               for (size_t i = 0; i < sock->nchildren; i++) {
                        if (!atomic_load(&sock->children[i].destroying)) {
                                nmsocket_cleanup(&sock->children[i],
                                                 false FLARG_PASS);
@@ -1023,7 +1023,7 @@ nmsocket_maybe_destroy(isc_nmsocket_t *sock FLARG) {
 
        active_handles = atomic_load(&sock->ah);
        if (sock->children != NULL) {
-               for (int i = 0; i < sock->nchildren; i++) {
+               for (size_t i = 0; i < sock->nchildren; i++) {
                        LOCK(&sock->children[i].lock);
                        active_handles += atomic_load(&sock->children[i].ah);
                        UNLOCK(&sock->children[i].lock);
@@ -1065,7 +1065,7 @@ isc___nmsocket_prep_destroy(isc_nmsocket_t *sock FLARG) {
         * so they can be cleaned up too.
         */
        if (sock->children != NULL) {
-               for (int i = 0; i < sock->nchildren; i++) {
+               for (size_t i = 0; i < sock->nchildren; i++) {
                        atomic_store(&sock->children[i].active, false);
                }
        }
index 41afed53eb5200659172d1833762a1c055e77788..db6ef3ad8df0c400e5b40f048587a49800a7def9 100644 (file)
@@ -424,14 +424,14 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
        memset(sock->children, 0, children_size);
 
        sock->result = ISC_R_DEFAULT;
-       sock->tid = isc_random_uniform(mgr->nworkers);
+       sock->tid = isc_random_uniform(sock->nchildren);
        sock->fd = -1;
 
 #if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
        fd = isc__nm_tcp_lb_socket(sa_family);
 #endif
 
-       for (size_t i = 0; i < mgr->nworkers; i++) {
+       for (size_t i = 0; i < sock->nchildren; i++) {
                isc__netievent_tcplisten_t *ievent = NULL;
                isc_nmsocket_t *csock = &sock->children[i];
 
@@ -466,7 +466,7 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
 #endif
 
        LOCK(&sock->lock);
-       while (sock->rchildren != mgr->nworkers) {
+       while (sock->rchildren != sock->nchildren) {
                WAIT(&sock->cond, &sock->lock);
        }
        result = sock->result;
@@ -476,7 +476,7 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
        INSIST(result != ISC_R_DEFAULT);
 
        if (result == ISC_R_SUCCESS) {
-               REQUIRE(sock->rchildren == mgr->nworkers);
+               REQUIRE(sock->rchildren == sock->nchildren);
                *sockp = sock;
        } else {
                atomic_store(&sock->active, false);
@@ -1323,7 +1323,7 @@ stop_tcp_parent(isc_nmsocket_t *sock) {
        REQUIRE(VALID_NMSOCK(sock));
        REQUIRE(sock->type == isc_nm_tcplistener);
 
-       for (int i = 0; i < sock->nchildren; i++) {
+       for (size_t i = 0; i < sock->nchildren; i++) {
                isc__netievent_tcpstop_t *ievent = NULL;
                isc_nmsocket_t *csock = &sock->children[i];
                REQUIRE(VALID_NMSOCK(csock));
index edcbff6539c6fb82b7253b241faa18ff9edafe78..f52cbca3e9e00618e2f65f665a6faa31e425a0fa 100644 (file)
@@ -468,14 +468,14 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface,
        memset(sock->children, 0, children_size);
 
        sock->result = ISC_R_DEFAULT;
-       sock->tid = isc_random_uniform(mgr->nworkers);
+       sock->tid = isc_random_uniform(sock->nchildren);
        sock->fd = -1;
 
 #if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
        fd = isc__nm_tcpdns_lb_socket(sa_family);
 #endif
 
-       for (size_t i = 0; i < mgr->nworkers; i++) {
+       for (size_t i = 0; i < sock->nchildren; i++) {
                isc__netievent_tcpdnslisten_t *ievent = NULL;
                isc_nmsocket_t *csock = &sock->children[i];
 
@@ -512,7 +512,7 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface,
 #endif
 
        LOCK(&sock->lock);
-       while (sock->rchildren != mgr->nworkers) {
+       while (sock->rchildren != sock->nchildren) {
                WAIT(&sock->cond, &sock->lock);
        }
        result = sock->result;
@@ -522,7 +522,7 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_nmiface_t *iface,
        INSIST(result != ISC_R_DEFAULT);
 
        if (result == ISC_R_SUCCESS) {
-               REQUIRE(sock->rchildren == mgr->nworkers);
+               REQUIRE(sock->rchildren == sock->nchildren);
                *sockp = sock;
        } else {
                atomic_store(&sock->active, false);
@@ -1420,7 +1420,7 @@ stop_tcpdns_parent(isc_nmsocket_t *sock) {
        REQUIRE(VALID_NMSOCK(sock));
        REQUIRE(sock->type == isc_nm_tcpdnslistener);
 
-       for (int i = 0; i < sock->nchildren; i++) {
+       for (size_t i = 0; i < sock->nchildren; i++) {
                isc__netievent_tcpdnsstop_t *ievent = NULL;
                isc_nmsocket_t *csock = &sock->children[i];
                REQUIRE(VALID_NMSOCK(csock));
index 85469a4a1cbcf2033c8f8ec708fd60431962ea8f..f69f6feb197f62f169c17a81b78e43168b677919 100644 (file)
@@ -132,14 +132,14 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
        sock->recv_cbarg = cbarg;
        sock->extrahandlesize = extrahandlesize;
        sock->result = ISC_R_DEFAULT;
-       sock->tid = isc_random_uniform(mgr->nworkers);
+       sock->tid = isc_random_uniform(sock->nchildren);
        sock->fd = -1;
 
 #if !HAVE_SO_REUSEPORT_LB && !defined(WIN32)
        fd = isc__nm_udp_lb_socket(sa_family);
 #endif
 
-       for (size_t i = 0; i < mgr->nworkers; i++) {
+       for (size_t i = 0; i < sock->nchildren; i++) {
                isc__netievent_udplisten_t *ievent = NULL;
                isc_nmsocket_t *csock = &sock->children[i];
 
@@ -169,7 +169,7 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
 #endif
 
        LOCK(&sock->lock);
-       while (sock->rchildren != mgr->nworkers) {
+       while (sock->rchildren != sock->nchildren) {
                WAIT(&sock->cond, &sock->lock);
        }
        result = sock->result;
@@ -179,7 +179,7 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb,
        INSIST(result != ISC_R_DEFAULT);
 
        if (result == ISC_R_SUCCESS) {
-               REQUIRE(sock->rchildren == mgr->nworkers);
+               REQUIRE(sock->rchildren == sock->nchildren);
                *sockp = sock;
        } else {
                atomic_store(&sock->active, false);
@@ -1119,7 +1119,7 @@ stop_udp_parent(isc_nmsocket_t *sock) {
        REQUIRE(VALID_NMSOCK(sock));
        REQUIRE(sock->type == isc_nm_udplistener);
 
-       for (int i = 0; i < sock->nchildren; i++) {
+       for (size_t i = 0; i < sock->nchildren; i++) {
                isc__netievent_udpstop_t *ievent = NULL;
                isc_nmsocket_t *csock = &sock->children[i];
                REQUIRE(VALID_NMSOCK(csock));
index 1d60ae63120e9830bef5fb9fb94a44d87088ea01..a0e1add2d788c804fd09ead1e8201d999b68e0e6 100644 (file)
@@ -52,13 +52,17 @@ int
 isc_uv_udp_freebind(uv_udp_t *handle, const struct sockaddr *addr,
                    unsigned int flags) {
        int r;
-       int fd;
+       uv_os_sock_t fd;
 
        r = uv_fileno((const uv_handle_t *)handle, (uv_os_fd_t *)&fd);
        if (r < 0) {
                return (r);
        }
 
+#if defined(WIN32)
+       REQUIRE(fd != INVALID_SOCKET);
+#endif
+
        r = uv_udp_bind(handle, addr, flags);
        if (r == UV_EADDRNOTAVAIL &&
            isc__nm_socket_freebind(fd, addr->sa_family) == ISC_R_SUCCESS)
@@ -104,7 +108,7 @@ int
 isc_uv_tcp_freebind(uv_tcp_t *handle, const struct sockaddr *addr,
                    unsigned int flags) {
        int r;
-       int fd;
+       uv_os_sock_t fd;
 
        r = uv_fileno((const uv_handle_t *)handle, (uv_os_fd_t *)&fd);
        if (r < 0) {