diff --git a/CHANGES b/CHANGES index 7b73f13973..33e6f91b4c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +5105. [bug] Fix a race between process_fd and socketclose in + unix socket code. [GL #744] + 5104. [cleanup] Log clearer informational message when a catz zone is overridden by a zone in named.conf. Thanks to Tony Finch. [GL !1157] diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index 2a5648c126..2ef71b68c8 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -473,8 +473,6 @@ static void setdscp(isc__socket_t *sock, isc_dscp_t dscp); #define SELECT_POKE_CONNECT (-4) /*%< Same as _WRITE */ #define SELECT_POKE_CLOSE (-5) -#define SOCK_DEAD(s) (isc_refcount_current(&((s)->references)) == 0) - /*% * Shortcut index arrays to get access to statistics counters. */ @@ -3253,11 +3251,15 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable, UNLOCK(&thread->fdlock[lockid]); return; } - if (SOCK_DEAD(sock)) { /* Sock is being closed, bail */ - goto unlock_fd; - } - isc_refcount_increment(&sock->references); + if (isc_refcount_increment(&sock->references) == 0) { + /* + * Sock is being closed, it will be destroyed, bail. + */ + isc_refcount_decrement(&sock->references); + UNLOCK(&thread->fdlock[lockid]); + return; + } if (readable) { if (sock->listener) { @@ -3275,12 +3277,9 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable, } } - unlock_fd: UNLOCK(&thread->fdlock[lockid]); - if (sock != NULL) { - if (isc_refcount_decrement(&sock->references) == 1) { - destroy(&sock); - } + if (isc_refcount_decrement(&sock->references) == 1) { + destroy(&sock); } }