Backport a few upstream thread safety fixes

It might not fix all issues, but was detected by upstream using
automated tool. Should not break anything new, but might fix issue
triggered usually on ppc64le platform.
This commit is contained in:
Petr Menšík 2019-12-02 20:34:08 +01:00
parent 6f27f8e4a7
commit 1a4de8b956
5 changed files with 318 additions and 0 deletions

View File

@ -0,0 +1,56 @@
From 312bd133f75c54d51196060c573e29aabbb0b842 Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Tue, 26 Nov 2019 02:30:14 +0000
Subject: [PATCH 1/4] Merge branch
'1367-threadsanitizer-data-race-dispatch-c-901-in-free_buffer-v9_11' into
'v9_11'
Resolve "ThreadSanitizer: data race dispatch.c:901 in free_buffer"
See merge request isc-projects/bind9!2628
(cherry picked from commit 0455351802cb915e7961dad9cf14977a19162d38)
---
lib/dns/dispatch.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c
index 3278db4a07..ea5cf102f2 100644
--- a/lib/dns/dispatch.c
+++ b/lib/dns/dispatch.c
@@ -927,6 +927,10 @@ allocate_udp_buffer(dns_dispatch_t *disp) {
void *temp;
LOCK(&disp->mgr->buffer_lock);
+ if (disp->mgr->buffers >= disp->mgr->maxbuffers) {
+ UNLOCK(&disp->mgr->buffer_lock);
+ return (NULL);
+ }
bpool = disp->mgr->bpool;
disp->mgr->buffers++;
UNLOCK(&disp->mgr->buffer_lock);
@@ -1058,9 +1062,11 @@ udp_recv(isc_event_t *ev_in, dns_dispatch_t *disp, dispsocket_t *dispsock) {
mgr = disp->mgr;
qid = mgr->qid;
+ LOCK(&disp->mgr->buffer_lock);
dispatch_log(disp, LVL(90),
"got packet: requests %d, buffers %d, recvs %d",
disp->requests, disp->mgr->buffers, disp->recv_pending);
+ UNLOCK(&disp->mgr->buffer_lock);
if (dispsock == NULL && ev->ev_type == ISC_SOCKEVENT_RECVDONE) {
/*
@@ -1511,9 +1517,6 @@ startrecv(dns_dispatch_t *disp, dispsocket_t *dispsock) {
if (disp->recv_pending != 0 && dispsock == NULL)
return (ISC_R_SUCCESS);
- if (disp->mgr->buffers >= disp->mgr->maxbuffers)
- return (ISC_R_NOMEMORY);
-
if ((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) != 0 &&
dispsock == NULL)
return (ISC_R_SUCCESS);
--
2.21.0

View File

@ -0,0 +1,38 @@
From 8e1900b79d854e22ec6b5cea152ff363ce9a461c Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Fri, 22 Nov 2019 21:48:12 +0000
Subject: [PATCH 2/4] Merge branch
'1334-threadsanitizer-data-race-dispatch-c-1339-in-tcp_recv-v9_11' into
'v9_11'
lock dispatch before reporting state
See merge request isc-projects/bind9!2619
(cherry picked from commit e36730076af3190fe5930a6406dd414b87e1e178)
---
lib/dns/dispatch.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c
index ea5cf102f2..94df6bab9a 100644
--- a/lib/dns/dispatch.c
+++ b/lib/dns/dispatch.c
@@ -1353,12 +1353,12 @@ tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
qid = disp->qid;
+ LOCK(&disp->lock);
+
dispatch_log(disp, LVL(90),
"got TCP packet: requests %d, buffers %d, recvs %d",
disp->requests, disp->tcpbuffers, disp->recv_pending);
- LOCK(&disp->lock);
-
INSIST(disp->recv_pending != 0);
disp->recv_pending = 0;
--
2.21.0

105
bind-9.11-rh1736762-3.patch Normal file
View File

@ -0,0 +1,105 @@
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

110
bind-9.11-rh1736762-4.patch Normal file
View File

@ -0,0 +1,110 @@
From 9c1f74400c04267dea4f1bd7f62de8ba5e8d2b0e Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Thu, 28 Nov 2019 10:24:12 +1100
Subject: [PATCH 4/4] rdataset_setownercase and rdataset_getownercase need to
obtain a node lock
(cherry picked from commit 637b2c4e517b466900a8c00b52f7a15727e12ae9)
(cherry picked from commit 1c61f129c3b12071723a2154d33f74628bf80998)
---
lib/dns/rbtdb.c | 35 ++++++++++++++++++++++++++++-------
1 file changed, 28 insertions(+), 7 deletions(-)
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index d3bb8d7fe7..199ff08011 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -10109,11 +10109,18 @@ setownercase(rdatasetheader_t *header, const dns_name_t *name) {
static void
rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name) {
+ dns_rbtdb_t *rbtdb = rdataset->private1;
+ dns_rbtnode_t *rbtnode = rdataset->private2;
unsigned char *raw = rdataset->private3; /* RDATASLAB */
rdatasetheader_t *header;
header = (struct rdatasetheader *)(raw - sizeof(*header));
+
+ NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
+ isc_rwlocktype_write);
setownercase(header, name);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
+ isc_rwlocktype_write);
}
static const unsigned char charmask[] = {
@@ -10188,6 +10195,8 @@ static unsigned char maptolower[] = {
static void
rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
+ dns_rbtdb_t *rbtdb = rdataset->private1;
+ dns_rbtnode_t *rbtnode = rdataset->private2;
const unsigned char *raw = rdataset->private3; /* RDATASLAB */
const rdatasetheader_t *header;
unsigned int i, j;
@@ -10196,8 +10205,12 @@ rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
header = (const struct rdatasetheader *)(raw - sizeof(*header));
- if (!CASESET(header))
- return;
+ NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
+ isc_rwlocktype_read);
+
+ if (!CASESET(header)) {
+ goto unlock;
+ }
#if 0
/*
@@ -10210,10 +10223,13 @@ rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
*/
if (name->ndata[i] >= 0x61 && name->ndata[i] <= 0x7a &&
(header->upper[i/8] & (1 << (i%8))) != 0)
+ {
name->ndata[i] &= ~0x20; /* clear the lower case bit */
- else if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a &&
- (header->upper[i/8] & (1 << (i%8))) == 0)
+ } else if (name->ndata[i] >= 0x41 && name->ndata[i] <= 0x5a &&
+ (header->upper[i/8] & (1 << (i%8))) == 0)
+ {
name->ndata[i] |= 0x20; /* set the lower case bit */
+ }
}
#else
if (ISC_LIKELY(CASEFULLYLOWER(header))) {
@@ -10236,7 +10252,7 @@ rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
c = *bp;
*bp++ = maptolower[c];
}
- return;
+ goto unlock;
}
i = 0;
@@ -10257,8 +10273,9 @@ rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
}
}
- if (ISC_UNLIKELY(i == name->length))
- return;
+ if (ISC_UNLIKELY(i == name->length)) {
+ goto unlock;
+ }
bits = ~(header->upper[j]);
@@ -10272,6 +10289,10 @@ rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name) {
bits >>= 1;
}
#endif
+
+ unlock:
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
+ isc_rwlocktype_read);
}
/*%
--
2.21.0

View File

@ -161,6 +161,11 @@ Patch174:bind-9.11-json-c.patch
Patch175:bind-9.11-fips-disable.patch
Patch177: bind-9.11-serve-stale.patch
Patch178: bind-9.11-serve-stale-dbfix.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1736762
Patch179: bind-9.11-rh1736762-1.patch
Patch180: bind-9.11-rh1736762-2.patch
Patch181: bind-9.11-rh1736762-3.patch
Patch182: bind-9.11-rh1736762-4.patch
# SDB patches
Patch11: bind-9.3.2b2-sdbsrc.patch
@ -556,6 +561,10 @@ are used for building ISC DHCP.
%patch175 -p1 -b .rh1709553
%patch177 -p1 -b .serve-stale
%patch178 -p1 -b .rh1770492
%patch179 -p1 -b .rh1736762-1
%patch180 -p1 -b .rh1736762-2
%patch181 -p1 -b .rh1736762-3
%patch182 -p1 -b .rh1736762-4
mkdir lib/dns/tests/testdata/dstrandom
cp -a %{SOURCE50} lib/dns/tests/testdata/dstrandom/random.data