Blob Blame History Raw
From 651fc773a6e154466998424e975bce3fdb8566d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Wed, 27 Nov 2019 17:06:28 +0000
Subject: [PATCH 3/4] Merge branch
 '1350-threadsanitizer-data-race-rbt-c-1312-in-dns_rbt_addnode-v9_11' into
 'v9_11'

Resolve "ThreadSanitizer: data race rbt.c:1312 in dns_rbt_addnode"

See merge request isc-projects/bind9!2651

(cherry picked from commit a5fb8c812728cb5fc923f60d6707d953d704719f)
---
 lib/dns/rbtdb.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index 738aa203ec..d3bb8d7fe7 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -1972,6 +1972,9 @@ clean_zone_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
 		node->dirty = 0;
 }
 
+/*
+ * tree_lock(write) must be held.
+ */
 static void
 delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) {
 	dns_rbtnode_t *nsecnode;
@@ -2955,6 +2958,8 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, bool commit) {
  * E.g. if the wildcard name is "*.sub.example." then we
  * must ensure that "sub.example." exists and is marked as
  * a wildcard level.
+ *
+ * tree_lock(write) must be held.
  */
 static isc_result_t
 add_wildcard_magic(dns_rbtdb_t *rbtdb, dns_name_t *name) {
@@ -2979,6 +2984,9 @@ add_wildcard_magic(dns_rbtdb_t *rbtdb, dns_name_t *name) {
 	return (ISC_R_SUCCESS);
 }
 
+/*
+ * tree_lock(write) must be held.
+ */
 static isc_result_t
 add_empty_wildcards(dns_rbtdb_t *rbtdb, dns_name_t *name) {
 	isc_result_t result;
@@ -6756,13 +6764,16 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
 	REQUIRE(VALID_RBTDB(rbtdb));
 	INSIST(rbtversion == NULL || rbtversion->rbtdb == rbtdb);
 
-	if (rbtdb->common.methods == &zone_methods)
+	if (rbtdb->common.methods == &zone_methods) {
+		RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
 		REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 &&
 			  (rdataset->type == dns_rdatatype_nsec3 ||
 			   rdataset->covers == dns_rdatatype_nsec3)) ||
 			 (rbtnode->nsec != DNS_RBT_NSEC_NSEC3 &&
 			   rdataset->type != dns_rdatatype_nsec3 &&
 			   rdataset->covers != dns_rdatatype_nsec3)));
+		RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+	}
 
 	if (rbtversion == NULL) {
 		if (now == 0)
@@ -6854,11 +6865,15 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
 	/*
 	 * Add to the auxiliary NSEC tree if we're adding an NSEC record.
 	 */
+	RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
 	if (rbtnode->nsec != DNS_RBT_NSEC_HAS_NSEC &&
 	    rdataset->type == dns_rdatatype_nsec)
+	{
 		newnsec = true;
-	else
+	} else {
 		newnsec = false;
+	}
+	RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
 
 	/*
 	 * If we're adding a delegation type, adding to the auxiliary NSEC tree,
@@ -6959,13 +6974,16 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
 	REQUIRE(VALID_RBTDB(rbtdb));
 	REQUIRE(rbtversion != NULL && rbtversion->rbtdb == rbtdb);
 
-	if (rbtdb->common.methods == &zone_methods)
+	if (rbtdb->common.methods == &zone_methods) {
+		RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
 		REQUIRE(((rbtnode->nsec == DNS_RBT_NSEC_NSEC3 &&
 			  (rdataset->type == dns_rdatatype_nsec3 ||
 			   rdataset->covers == dns_rdatatype_nsec3)) ||
 			 (rbtnode->nsec != DNS_RBT_NSEC_NSEC3 &&
 			   rdataset->type != dns_rdatatype_nsec3 &&
 			   rdataset->covers != dns_rdatatype_nsec3)));
+		RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+	}
 
 	result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
 					    &region, sizeof(rdatasetheader_t));
-- 
2.21.0