]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add missing node lock when setting node->wild in rbtdb.c
authorMark Andrews <marka@isc.org>
Wed, 18 Jan 2023 04:54:42 +0000 (15:54 +1100)
committerMark Andrews <marka@isc.org>
Thu, 19 Jan 2023 12:52:08 +0000 (23:52 +1100)
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.

lib/dns/rbtdb.c

index eea89880d455b04949c9f6df341fbbf50b0dff8d..4aa3c7b400297ed80f7354dbfa706df4f158cb09 100644 (file)
@@ -2714,12 +2714,13 @@ 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;
        unsigned int n;
        dns_rbtnode_t *node = NULL;
+       isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
 
        dns_name_init(&foundname, offsets);
        n = dns_name_countlabels(name);
@@ -2734,7 +2735,13 @@ 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_WRLOCK(&rbtdb->node_locks[node->locknum].lock, &nlocktype);
+       }
        node->wild = 1;
+       if (lock) {
+               NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock, &nlocktype);
+       }
        return (ISC_R_SUCCESS);
 }
 
@@ -2742,7 +2749,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;
@@ -2756,7 +2763,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);
                        }
@@ -2805,11 +2812,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) {
                                                goto unlock;
                                        }
@@ -7444,7 +7451,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)) {
@@ -7460,7 +7467,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);
                }