c21dae
From c0134bbea5573b1911d204b28eb8c71351a0173f Mon Sep 17 00:00:00 2001
c21dae
From: Mark Andrews <marka@isc.org>
c21dae
Date: Fri, 18 Dec 2020 13:31:07 +1100
c21dae
Subject: [PATCH] Inactive incorrectly incremented
c21dae
c21dae
It is possible to have two threads destroying an rbtdb at the same
c21dae
time when detachnode() executes and removes the last reference to
c21dae
a node between exiting being set to true for the node and testing
c21dae
if the references are zero in maybe_free_rbtdb().  Move NODE_UNLOCK()
c21dae
to after checking if references is zero to prevent detachnode()
c21dae
changing the reference count too early.
c21dae
c21dae
(cherry picked from commit 859d2fdad6d1c6ff20083a4c463a929cbeb26438)
c21dae
(cherry picked from commit 25150c15e7cfa73289f04470e2e699ebb7c28fef)
c21dae
---
c21dae
 lib/dns/rbtdb.c | 2 +-
c21dae
 1 file changed, 1 insertion(+), 1 deletion(-)
c21dae
c21dae
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
c21dae
index 29778d79a5..b01b44c4c7 100644
c21dae
--- a/lib/dns/rbtdb.c
c21dae
+++ b/lib/dns/rbtdb.c
c21dae
@@ -1399,11 +1399,11 @@ maybe_free_rbtdb(dns_rbtdb_t *rbtdb) {
c21dae
 	for (i = 0; i < rbtdb->node_lock_count; i++) {
c21dae
 		NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write);
c21dae
 		rbtdb->node_locks[i].exiting = ISC_TRUE;
c21dae
-		NODE_UNLOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write);
c21dae
 		if (isc_refcount_current(&rbtdb->node_locks[i].references)
c21dae
 		    == 0) {
c21dae
 			inactive++;
c21dae
 		}
c21dae
+		NODE_UNLOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_write);
c21dae
 	}
c21dae
 
c21dae
 	if (inactive != 0) {
c21dae
-- 
c21dae
2.26.3
c21dae