]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix a use-after-free bug in dns_zonemgr_releasezone()
authorAram Sargsyan <aram@isc.org>
Thu, 5 Jan 2023 15:01:35 +0000 (15:01 +0000)
committerAram Sargsyan <aram@isc.org>
Wed, 11 Jan 2023 12:17:27 +0000 (12:17 +0000)
The dns_zonemgr_releasezone() function makes a decision to destroy
'zmgr' (based on its references count, after decreasing it) inside
a lock, and then destroys the object outside of the lock.

This causes a race with dns_zonemgr_detach(), which could destroy
the object in the meantime.

Change dns_zonemgr_releasezone() to detach from 'zmgr' and destroy
the object (if needed) using dns_zonemgr_detach(), outside of the
lock.

(cherry picked from commit c1fc2122531bdd27ca38434a2632e8dac532bc13)

lib/dns/zone.c

index 7d26ab705c90ffb8a338493147b24daa9970cfad..51e2fc6cf263e6f60685af7af7c4f9336a1a6eb2 100644 (file)
@@ -18880,8 +18880,6 @@ unlock:
 
 void
 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
-       bool free_now = false;
-
        REQUIRE(DNS_ZONE_VALID(zone));
        REQUIRE(DNS_ZONEMGR_VALID(zmgr));
        REQUIRE(zone->zmgr == zmgr);
@@ -18896,19 +18894,13 @@ dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
                ENSURE(zone->kfio == NULL);
        }
 
+       /* Detach below, outside of the write lock. */
        zone->zmgr = NULL;
 
-       if (isc_refcount_decrement(&zmgr->refs) == 1) {
-               free_now = true;
-       }
-
        UNLOCK_ZONE(zone);
        RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
 
-       if (free_now) {
-               zonemgr_free(zmgr);
-       }
-       ENSURE(zone->zmgr == NULL);
+       dns_zonemgr_detach(&zmgr);
 }
 
 void