From: Mark Andrews Date: Fri, 18 Dec 2020 02:31:07 +0000 (+1100) Subject: Inactive incorrectly incremented X-Git-Tag: v9.17.9~13^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=859d2fdad6d1c6ff20083a4c463a929cbeb26438;p=thirdparty%2Fbind9.git Inactive incorrectly incremented It is possible to have two threads destroying an rbtdb at the same time when detachnode() executes and removes the last reference to a node between exiting being set to true for the node and testing if the references are zero in maybe_free_rbtdb(). Move NODE_UNLOCK() to after checking if references is zero to prevent detachnode() changing the reference count too early. --- diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 6aa4bc1f388..b9a46cea403 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -1256,11 +1256,11 @@ maybe_free_rbtdb(dns_rbtdb_t *rbtdb) { for (i = 0; i < rbtdb->node_lock_count; i++) { NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write); rbtdb->node_locks[i].exiting = true; - NODE_UNLOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write); if (isc_refcount_current(&rbtdb->node_locks[i].references) == 0) { inactive++; } + NODE_UNLOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write); } if (inactive != 0) {