]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
r/w of rbtdb->current_version requires that rbtdb->lock be held
authorMark Andrews <marka@isc.org>
Thu, 28 Nov 2019 06:58:40 +0000 (17:58 +1100)
committerOndřej Surý <ondrej@isc.org>
Tue, 3 Dec 2019 09:09:52 +0000 (09:09 +0000)
(cherry picked from commit cd2469d3cdbc211ecf8a82c76c1a0a1c4a545fec)

lib/dns/rbtdb.c

index 95ac4103b5c083d905be90ae641972dd72f493aa..f3d181808f3997ec1c6c647bcc33224aac87e181 100644 (file)
@@ -1212,7 +1212,6 @@ detach(dns_db_t **dbp) {
        *dbp = NULL;
 
        if (isc_refcount_decrement(&rbtdb->references) == 1) {
-               (void)isc_refcount_current(&rbtdb->references);
                maybe_free_rbtdb(rbtdb);
        }
 }
@@ -1224,7 +1223,6 @@ currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
 
        REQUIRE(VALID_RBTDB(rbtdb));
 
-       /* XXXOND: Is the lock needed here? */
        RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
        version = rbtdb->current_version;
        isc_refcount_increment(&version->references);
@@ -6878,8 +6876,11 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
         * Update the zone's secure status.  If version is non-NULL
         * this is deferred until closeversion() is called.
         */
-       if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb))
+       if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb)) {
+               RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
                iszonesecure(db, rbtdb->current_version, rbtdb->origin_node);
+               RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
+       }
 
        return (result);
 }
@@ -6933,8 +6934,11 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
         * Update the zone's secure status.  If version is non-NULL
         * this is deferred until closeversion() is called.
         */
-       if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb))
+       if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb)) {
+               RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
                iszonesecure(db, rbtdb->current_version, rbtdb->origin_node);
+               RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
+       }
 
        return (result);
 }
@@ -7354,14 +7358,14 @@ endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
        rbtdb->attributes &= ~RBTDB_ATTR_LOADING;
        rbtdb->attributes |= RBTDB_ATTR_LOADED;
 
-       RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
-
        /*
         * If there's a KEY rdataset at the zone origin containing a
         * zone key, we consider the zone secure.
         */
-       if (! IS_CACHE(rbtdb) && rbtdb->origin_node != NULL)
+       if (! IS_CACHE(rbtdb) && rbtdb->origin_node != NULL) {
                iszonesecure(db, rbtdb->current_version, rbtdb->origin_node);
+       }
+       RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
 
        callbacks->add = NULL;
        callbacks->add_private = NULL;
@@ -7627,9 +7631,9 @@ issecure(dns_db_t *db) {
 
        REQUIRE(VALID_RBTDB(rbtdb));
 
-       RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+       RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
        secure = (rbtdb->current_version->secure == dns_db_secure);
-       RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+       RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
 
        return (secure);
 }
@@ -7643,9 +7647,9 @@ isdnssec(dns_db_t *db) {
 
        REQUIRE(VALID_RBTDB(rbtdb));
 
-       RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+       RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
        dnssec = (rbtdb->current_version->secure != dns_db_insecure);
-       RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+       RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
 
        return (dnssec);
 }
@@ -7741,10 +7745,10 @@ getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash,
        REQUIRE(VALID_RBTDB(rbtdb));
        INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
 
-       RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
-
-       if (rbtversion == NULL)
+       RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
+       if (rbtversion == NULL) {
                rbtversion = rbtdb->current_version;
+       }
 
        if (rbtversion->havensec3) {
                if (hash != NULL)
@@ -7762,7 +7766,7 @@ getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash,
                        *flags = rbtversion->flags;
                result = ISC_R_SUCCESS;
        }
-       RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+       RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
 
        return (result);
 }
@@ -7780,16 +7784,21 @@ getsize(dns_db_t *db, dns_dbversion_t *version, uint64_t *records,
        REQUIRE(VALID_RBTDB(rbtdb));
        INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
 
-       if (rbtversion == NULL)
+       RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
+       if (rbtversion == NULL) {
                rbtversion = rbtdb->current_version;
+       }
 
        RWLOCK(&rbtversion->rwlock, isc_rwlocktype_read);
-       if (records != NULL)
+       if (records != NULL) {
                *records = rbtversion->records;
+       }
 
-       if (bytes != NULL)
+       if (bytes != NULL) {
                *bytes = rbtversion->bytes;
+       }
        RWUNLOCK(&rbtversion->rwlock, isc_rwlocktype_read);
+       RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
 
        return (result);
 }