2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 22:45:39 +00:00

rbtversion->glue_table_size must be read when holding a lock

This commit is contained in:
Mark Andrews
2020-08-19 14:59:02 +10:00
parent 0ede73b9f1
commit 33d0e8d168

View File

@@ -10048,7 +10048,10 @@ free_gluetable(rbtdb_version_t *version) {
RWUNLOCK(&version->glue_rwlock, isc_rwlocktype_write); RWUNLOCK(&version->glue_rwlock, isc_rwlocktype_write);
} }
static bool /*%
* Write lock (version->glue_rwlock) must be held.
*/
static void
rehash_gluetable(rbtdb_version_t *version) { rehash_gluetable(rbtdb_version_t *version) {
size_t oldsize, i; size_t oldsize, i;
rbtdb_glue_table_node_t **oldtable; rbtdb_glue_table_node_t **oldtable;
@@ -10058,7 +10061,7 @@ rehash_gluetable(rbtdb_version_t *version) {
if (ISC_LIKELY(version->glue_table_nodecount < if (ISC_LIKELY(version->glue_table_nodecount <
(version->glue_table_size * 3U))) { (version->glue_table_size * 3U))) {
return (false); return;
} }
oldsize = version->glue_table_size; oldsize = version->glue_table_size;
@@ -10076,7 +10079,7 @@ rehash_gluetable(rbtdb_version_t *version) {
if (ISC_UNLIKELY(version->glue_table == NULL)) { if (ISC_UNLIKELY(version->glue_table == NULL)) {
version->glue_table = oldtable; version->glue_table = oldtable;
version->glue_table_size = oldsize; version->glue_table_size = oldsize;
return (false); return;
} }
for (i = 0; i < version->glue_table_size; i++) { for (i = 0; i < version->glue_table_size; i++) {
@@ -10104,8 +10107,6 @@ rehash_gluetable(rbtdb_version_t *version) {
"resized glue table from %" PRIu64 " to " "resized glue table from %" PRIu64 " to "
"%" PRIu64, "%" PRIu64,
(uint64_t)oldsize, (uint64_t)version->glue_table_size); (uint64_t)oldsize, (uint64_t)version->glue_table_size);
return (true);
} }
static isc_result_t static isc_result_t
@@ -10232,6 +10233,7 @@ rdataset_addglue(dns_rdataset_t *rdataset, dns_dbversion_t *version,
rbtdb_glue_t *ge; rbtdb_glue_t *ge;
rbtdb_glue_additionaldata_ctx_t ctx; rbtdb_glue_additionaldata_ctx_t ctx;
isc_result_t result; isc_result_t result;
uint64_t hash;
REQUIRE(rdataset->type == dns_rdatatype_ns); REQUIRE(rdataset->type == dns_rdatatype_ns);
REQUIRE(rbtdb == rbtversion->rbtdb); REQUIRE(rbtdb == rbtversion->rbtdb);
@@ -10249,8 +10251,7 @@ rdataset_addglue(dns_rdataset_t *rdataset, dns_dbversion_t *version,
* the node pointer is a fixed value that won't change for a DB * the node pointer is a fixed value that won't change for a DB
* version and can be compared directly. * version and can be compared directly.
*/ */
idx = isc_hash_function(&node, sizeof(node), true) % hash = isc_hash_function(&node, sizeof(node), true);
rbtversion->glue_table_size;
restart: restart:
/* /*
@@ -10259,6 +10260,8 @@ restart:
*/ */
RWLOCK(&rbtversion->glue_rwlock, isc_rwlocktype_read); RWLOCK(&rbtversion->glue_rwlock, isc_rwlocktype_read);
idx = hash % rbtversion->glue_table_size;
for (cur = rbtversion->glue_table[idx]; cur != NULL; cur = cur->next) { for (cur = rbtversion->glue_table[idx]; cur != NULL; cur = cur->next) {
if (cur->node == node) { if (cur->node == node) {
break; break;
@@ -10422,10 +10425,8 @@ no_glue:
RWLOCK(&rbtversion->glue_rwlock, isc_rwlocktype_write); RWLOCK(&rbtversion->glue_rwlock, isc_rwlocktype_write);
if (ISC_UNLIKELY(rehash_gluetable(rbtversion))) { rehash_gluetable(rbtversion);
idx = isc_hash_function(&node, sizeof(node), true) % idx = hash % rbtversion->glue_table_size;
rbtversion->glue_table_size;
}
(void)dns_rdataset_additionaldata(rdataset, glue_nsdname_cb, &ctx); (void)dns_rdataset_additionaldata(rdataset, glue_nsdname_cb, &ctx);