]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
address deadlock introduced in cd2469d3cdbc211ecf8a82c76c1a0a1c4a545fec
authorMark Andrews <marka@isc.org>
Tue, 10 Dec 2019 02:16:58 +0000 (13:16 +1100)
committerMark Andrews <marka@isc.org>
Tue, 10 Dec 2019 12:08:57 +0000 (12:08 +0000)
lib/dns/rbtdb.c

index d1814270134ab407ebd7eba345389c31c583f3bd..97084c7af33657eda5ea36a5a7ac7e96187c5c5e 100644 (file)
@@ -164,7 +164,7 @@ typedef isc_rwlock_t nodelock_t;
 #define NODE_LOCK(l, t)         RWLOCK((l), (t))
 #define NODE_UNLOCK(l, t)       RWUNLOCK((l), (t))
 #define NODE_TRYUPGRADE(l)      isc_rwlock_tryupgrade(l)
-#define NODE_DOWNGRADE(l)   isc_rwlock_downgrade(l)
+#define NODE_DOWNGRADE(l)       isc_rwlock_downgrade(l)
 
 /*%
  * Whether to rate-limit updating the LRU to avoid possible thread contention.
@@ -6837,9 +6837,10 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
         * this is deferred until closeversion() is called.
         */
        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);
+               RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
+               version = rbtdb->current_version;
+               RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
+               iszonesecure(db, version, rbtdb->origin_node);
        }
 
        return (result);
@@ -6895,9 +6896,10 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
         * this is deferred until closeversion() is called.
         */
        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);
+               RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
+               version = rbtdb->current_version;
+               RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
+               iszonesecure(db, version, rbtdb->origin_node);
        }
 
        return (result);
@@ -7329,9 +7331,12 @@ endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
         * zone key, we consider the zone secure.
         */
        if (! IS_CACHE(rbtdb) && rbtdb->origin_node != NULL) {
-               iszonesecure(db, rbtdb->current_version, rbtdb->origin_node);
+               dns_dbversion_t *version = rbtdb->current_version;
+               RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
+               iszonesecure(db, version, rbtdb->origin_node);
+       } else {
+               RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
        }
-       RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
 
        callbacks->add = NULL;
        callbacks->add_private = NULL;