From 4508b0a1e260b4ebd9f9ae6866d1d7a7c3c6562f Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 18 Jan 2023 15:54:42 +1100 Subject: [PATCH] Add missing node lock when setting node->wild in rbtdb.c The write node lock needs to be held when setting node->wild in add_wildcard_magic except when being called from loading_addrdataset which is used to load the zone without locking during its initial load. (cherry picked from commit 81c24b8da270fb06f0d3b9fb5eb92e64d6343ade) --- lib/dns/rbtdb.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index d1aee54160..bebef1006a 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -2682,7 +2682,7 @@ end: * tree_lock(write) must be held. */ static isc_result_t -add_wildcard_magic(dns_rbtdb_t *rbtdb, const dns_name_t *name) { +add_wildcard_magic(dns_rbtdb_t *rbtdb, const dns_name_t *name, bool lock) { isc_result_t result; dns_name_t foundname; dns_offsets_t offsets; @@ -2702,7 +2702,15 @@ add_wildcard_magic(dns_rbtdb_t *rbtdb, const dns_name_t *name) { node->nsec = DNS_RBT_NSEC_NORMAL; } node->find_callback = 1; + if (lock) { + NODE_LOCK(&rbtdb->node_locks[node->locknum].lock, + isc_rwlocktype_write); + } node->wild = 1; + if (lock) { + NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock, + isc_rwlocktype_write); + } return (ISC_R_SUCCESS); } @@ -2710,7 +2718,7 @@ add_wildcard_magic(dns_rbtdb_t *rbtdb, const dns_name_t *name) { * tree_lock(write) must be held. */ static isc_result_t -add_empty_wildcards(dns_rbtdb_t *rbtdb, const dns_name_t *name) { +add_empty_wildcards(dns_rbtdb_t *rbtdb, const dns_name_t *name, bool lock) { isc_result_t result; dns_name_t foundname; dns_offsets_t offsets; @@ -2724,7 +2732,7 @@ add_empty_wildcards(dns_rbtdb_t *rbtdb, const dns_name_t *name) { dns_rbtnode_t *node = NULL; /* dummy */ dns_name_getlabelsequence(name, n - i, i, &foundname); if (dns_name_iswildcard(&foundname)) { - result = add_wildcard_magic(rbtdb, &foundname); + result = add_wildcard_magic(rbtdb, &foundname, lock); if (result != ISC_R_SUCCESS) { return (result); } @@ -2776,11 +2784,11 @@ findnodeintree(dns_rbtdb_t *rbtdb, dns_rbt_t *tree, const dns_name_t *name, dns_rbt_namefromnode(node, &nodename); node->locknum = node->hashval % rbtdb->node_lock_count; if (tree == rbtdb->tree) { - add_empty_wildcards(rbtdb, name); + add_empty_wildcards(rbtdb, name, true); if (dns_name_iswildcard(name)) { - result = add_wildcard_magic(rbtdb, - name); + result = add_wildcard_magic(rbtdb, name, + true); if (result != ISC_R_SUCCESS) { RWUNLOCK(&rbtdb->tree_lock, locktype); @@ -7422,7 +7430,7 @@ loading_addrdataset(void *arg, const dns_name_t *name, if (rdataset->type != dns_rdatatype_nsec3 && rdataset->covers != dns_rdatatype_nsec3) { - add_empty_wildcards(rbtdb, name); + add_empty_wildcards(rbtdb, name, false); } if (dns_name_iswildcard(name)) { @@ -7438,7 +7446,7 @@ loading_addrdataset(void *arg, const dns_name_t *name, if (rdataset->type == dns_rdatatype_nsec3) { return (DNS_R_INVALIDNSEC3); } - result = add_wildcard_magic(rbtdb, name); + result = add_wildcard_magic(rbtdb, name, false); if (result != ISC_R_SUCCESS) { return (result); }