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,
®ion, sizeof(rdatasetheader_t));
--
2.21.0