]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix a race in socket code
authorWitold Kręcicki <wpk@isc.org>
Wed, 3 Oct 2018 20:39:39 +0000 (20:39 +0000)
committerWitold Kręcicki <wpk@isc.org>
Wed, 24 Oct 2018 07:10:20 +0000 (07:10 +0000)
lib/isc/unix/socket.c

index 10db7d0aec8c7dce05a3a8d6fd56a09df89339d9..6afa5d289693c6c0ff3244a9cb65864742094afa 100644 (file)
@@ -2807,6 +2807,7 @@ isc_socket_attach(isc_socket_t *sock0, isc_socket_t **socketp) {
        REQUIRE(socketp != NULL && *socketp == NULL);
 
        LOCK(&sock->lock);
+       REQUIRE(sock->references > 0);
        sock->references++;
        UNLOCK(&sock->lock);
 
@@ -2850,7 +2851,6 @@ isc_socket_close(isc_socket_t *sock0) {
 
        LOCK(&sock->lock);
 
-       REQUIRE(sock->references == 1);
        REQUIRE(sock->fd >= 0 && sock->fd < (int)sock->manager->maxsocks);
 
        INSIST(!sock->connecting);
@@ -3341,32 +3341,29 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable,
                unwatch_write = writeable;
                goto unlock_fd;
        }
+       if (SOCK_DEAD(sock)) { /* Sock is being closed, bail */
+               UNLOCK(&sock->lock);
+               UNLOCK(&thread->fdlock[lockid]);
+               return;
+       }
 
        LOCK(&sock->lock);
        sock->references++;
        UNLOCK(&sock->lock);
 
        if (readable) {
-               if (!SOCK_DEAD(sock)) {
-                       if (sock->listener)
-                               internal_accept(sock);
-                       else
-                               internal_recv(sock);
-               }
+               if (sock->listener)
+                       internal_accept(sock);
+               else
+                       internal_recv(sock);
                unwatch_read = true;
        }
 
        if (writeable) {
-               if (sock == NULL) {
-                       unwatch_write = true;
-                       goto unlock_fd;
-               }
-               if (!SOCK_DEAD(sock)) {
-                       if (sock->connecting)
-                               internal_connect(sock);
-                       else
-                               internal_send(sock);
-               }
+               if (sock->connecting)
+                       internal_connect(sock);
+               else
+                       internal_send(sock);
                unwatch_write = true;
        }