From 8bd8ed26ed0c67ab8368cf7242a99c1d1ae49c1f Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 10 Dec 2019 13:16:58 +1100 Subject: [PATCH] address deadlock introduced in cd2469d3cdbc211ecf8a82c76c1a0a1c4a545fec (cherry picked from commit fd52417f712dedc6caec64c43969450fdd41b352) --- lib/dns/rbtdb.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index f3d181808f..e07b456b0f 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -165,7 +165,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. @@ -6877,9 +6877,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); @@ -6935,9 +6936,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); @@ -7363,9 +7365,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;