From: Mark Andrews Date: Tue, 10 Dec 2019 02:16:58 +0000 (+1100) Subject: address deadlock introduced in cd2469d3cdbc211ecf8a82c76c1a0a1c4a545fec X-Git-Tag: v9.15.7~16^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fd52417f712dedc6caec64c43969450fdd41b352;p=thirdparty%2Fbind9.git address deadlock introduced in cd2469d3cdbc211ecf8a82c76c1a0a1c4a545fec --- diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index d1814270134..97084c7af33 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -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;