]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Don't destroy a non-closed socket, wait for all the callbacks.
authorEvan Hunt <each@isc.org>
Wed, 1 Jul 2020 07:49:12 +0000 (00:49 -0700)
committerWitold Kręcicki <wpk@isc.org>
Wed, 1 Jul 2020 15:35:10 +0000 (17:35 +0200)
We erroneously tried to destroy a socket after issuing
isc__nm_tcp{,dns}_close. Under some (race) circumstances we could get
nm_socket_cleanup to be called twice for the same socket, causing an
access to a dead memory.

lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/netmgr.c

index 1637741f5128954f759aa6cac6d4273a9f4dd154..277601d5ab8c1f6aaed0fdb38f32a0cea8c8fcd2 100644 (file)
@@ -79,8 +79,10 @@ typedef struct isc__networker {
  * connections we have peer address here, so both TCP and UDP can be
  * handled with a simple send-like function
  */
-#define NMHANDLE_MAGIC   ISC_MAGIC('N', 'M', 'H', 'D')
-#define VALID_NMHANDLE(t) ISC_MAGIC_VALID(t, NMHANDLE_MAGIC)
+#define NMHANDLE_MAGIC ISC_MAGIC('N', 'M', 'H', 'D')
+#define VALID_NMHANDLE(t)                      \
+       (ISC_MAGIC_VALID(t, NMHANDLE_MAGIC) && \
+        atomic_load(&(t)->references) > 0)
 
 typedef void (*isc__nm_closecb)(isc_nmhandle_t *);
 
index da5df23abdc55441282bcca67517c1b6dbd8a08b..432d612dbebaf5f66928fdfb3d75955e49265fcc 100644 (file)
@@ -877,10 +877,10 @@ isc__nmsocket_prep_destroy(isc_nmsocket_t *sock) {
                switch (sock->type) {
                case isc_nm_tcpsocket:
                        isc__nm_tcp_close(sock);
-                       break;
+                       return;
                case isc_nm_tcpdnssocket:
                        isc__nm_tcpdns_close(sock);
-                       break;
+                       return;
                default:
                        break;
                }
@@ -1068,8 +1068,8 @@ isc__nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t *peer,
        if (handle == NULL) {
                handle = alloc_handle(sock);
        } else {
-               INSIST(VALID_NMHANDLE(handle));
                isc_refcount_increment0(&handle->references);
+               INSIST(VALID_NMHANDLE(handle));
        }
 
        isc__nmsocket_attach(sock, &handle->sock);