Merge branch '3468-statistics-xml-rendering-does-not-seem-to-protect-against-concurrent-changes-v9_18' into 'v9_18'

Resolve "Statistics XML rendering does not seem to protect against concurrent changes" [v9_18]

See merge request isc-projects/bind9!7076
This commit is contained in:
Mark Andrews 2022-11-11 19:08:16 +00:00
commit d4b064bd65
7 changed files with 38 additions and 24 deletions

View file

@ -1,3 +1,8 @@
6017. [bug] The view's zone table was not locked when it should
have been leading to race conditions when external
extensions that manipulate the zone table where in
use. [GL #3468]
6015. [bug] Some browsers (Firefox) send more than 10 HTTP
headers. Bump the number of allowed HTTP headers
to 100. [GL #3670]

View file

@ -9816,8 +9816,8 @@ cleanup:
if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") != 0)
{
dns_view_setviewrevert(view);
(void)dns_zt_apply(view->zonetable, false, NULL,
removed, view);
(void)dns_zt_apply(view->zonetable, isc_rwlocktype_read,
false, NULL, removed, view);
}
dns_view_detach(&view);
}
@ -11467,8 +11467,8 @@ add_view_tolist(struct dumpcontext *dctx, dns_view_t *view) {
ISC_LIST_INIT(vle->zonelist);
ISC_LIST_APPEND(dctx->viewlist, vle, link);
if (dctx->dumpzones) {
result = dns_zt_apply(view->zonetable, true, NULL,
add_zone_tolist, dctx);
result = dns_zt_apply(view->zonetable, isc_rwlocktype_read,
true, NULL, add_zone_tolist, dctx);
}
return (result);
}
@ -12813,7 +12813,8 @@ named_server_sync(named_server_t *server, isc_lex_t *lex, isc_buffer_t **text) {
for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
view = ISC_LIST_NEXT(view, link))
{
result = dns_zt_apply(view->zonetable, false, NULL,
result = dns_zt_apply(view->zonetable,
isc_rwlocktype_none, false, NULL,
synczone, &cleanup);
if (result != ISC_R_SUCCESS && tresult == ISC_R_SUCCESS)
{

View file

@ -2246,8 +2246,8 @@ generatexml(named_server_t *server, uint32_t flags, int *buflen,
if ((flags & STATS_XML_ZONES) != 0) {
TRY0(xmlTextWriterStartElement(writer,
ISC_XMLCHAR "zones"));
CHECK(dns_zt_apply(view->zonetable, true, NULL,
zone_xmlrender, writer));
CHECK(dns_zt_apply(view->zonetable, isc_rwlocktype_read,
true, NULL, zone_xmlrender, writer));
TRY0(xmlTextWriterEndElement(writer)); /* /zones */
}
@ -2976,8 +2976,9 @@ generatejson(named_server_t *server, size_t *msglen, const char **msg,
CHECKMEM(za);
if ((flags & STATS_JSON_ZONES) != 0) {
CHECK(dns_zt_apply(view->zonetable, true, NULL,
zone_jsonrender, za));
CHECK(dns_zt_apply(view->zonetable,
isc_rwlocktype_read, true,
NULL, zone_jsonrender, za));
}
if (json_object_array_length(za) != 0) {

View file

@ -168,7 +168,7 @@ dns_zt_freezezones(dns_zt_t *zt, dns_view_t *view, bool freeze);
*/
isc_result_t
dns_zt_apply(dns_zt_t *zt, bool stop, isc_result_t *sub,
dns_zt_apply(dns_zt_t *zt, isc_rwlocktype_t lock, bool stop, isc_result_t *sub,
isc_result_t (*action)(dns_zone_t *, void *), void *uap);
/*%<
* Apply a given 'action' to all zone zones in the table.

View file

@ -725,7 +725,8 @@ dns_view_dialup(dns_view_t *view) {
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(view->zonetable != NULL);
(void)dns_zt_apply(view->zonetable, false, NULL, dialup, NULL);
(void)dns_zt_apply(view->zonetable, isc_rwlocktype_read, false, NULL,
dialup, NULL);
}
void

View file

@ -228,7 +228,8 @@ zt_destroy(dns_zt_t *zt) {
isc_refcount_destroy(&zt->loads_pending);
if (atomic_load_acquire(&zt->flush)) {
(void)dns_zt_apply(zt, false, NULL, flush, NULL);
(void)dns_zt_apply(zt, isc_rwlocktype_none, false, NULL, flush,
NULL);
}
dns_rbt_destroy(&zt->table);
@ -263,9 +264,8 @@ dns_zt_load(dns_zt_t *zt, bool stop, bool newonly) {
struct zt_load_params params;
REQUIRE(VALID_ZT(zt));
params.newonly = newonly;
RWLOCK(&zt->rwlock, isc_rwlocktype_read);
result = dns_zt_apply(zt, stop, NULL, load, &params);
RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
result = dns_zt_apply(zt, isc_rwlocktype_read, stop, NULL, load,
&params);
return (result);
}
@ -336,9 +336,8 @@ dns_zt_asyncload(dns_zt_t *zt, bool newonly, dns_zt_allloaded_t alldone,
zt->loaddone = alldone;
zt->loaddone_arg = arg;
RWLOCK(&zt->rwlock, isc_rwlocktype_read);
result = dns_zt_apply(zt, false, NULL, asyncload, zt);
RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
result = dns_zt_apply(zt, isc_rwlocktype_read, false, NULL, asyncload,
zt);
/*
* Have all the loads completed?
@ -384,9 +383,8 @@ dns_zt_freezezones(dns_zt_t *zt, dns_view_t *view, bool freeze) {
REQUIRE(VALID_ZT(zt));
RWLOCK(&zt->rwlock, isc_rwlocktype_read);
result = dns_zt_apply(zt, false, &tresult, freezezones, &params);
RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
result = dns_zt_apply(zt, isc_rwlocktype_read, false, &tresult,
freezezones, &params);
if (tresult == ISC_R_NOTFOUND) {
tresult = ISC_R_SUCCESS;
}
@ -522,7 +520,7 @@ dns_zt_setviewrevert(dns_zt_t *zt) {
}
isc_result_t
dns_zt_apply(dns_zt_t *zt, bool stop, isc_result_t *sub,
dns_zt_apply(dns_zt_t *zt, isc_rwlocktype_t lock, bool stop, isc_result_t *sub,
isc_result_t (*action)(dns_zone_t *, void *), void *uap) {
dns_rbtnode_t *node;
dns_rbtnodechain_t chain;
@ -532,6 +530,10 @@ dns_zt_apply(dns_zt_t *zt, bool stop, isc_result_t *sub,
REQUIRE(VALID_ZT(zt));
REQUIRE(action != NULL);
if (lock != isc_rwlocktype_none) {
RWLOCK(&zt->rwlock, lock);
}
dns_rbtnodechain_init(&chain);
result = dns_rbtnodechain_first(&chain, zt->table, NULL, NULL);
if (result == ISC_R_NOTFOUND) {
@ -568,6 +570,10 @@ cleanup:
*sub = tresult;
}
if (lock != isc_rwlocktype_none) {
RWUNLOCK(&zt->rwlock, lock);
}
return (result);
}

View file

@ -130,8 +130,8 @@ ISC_RUN_TEST_IMPL(dns_zt_apply) {
assert_non_null(view->zonetable);
assert_int_equal(nzones, 0);
result = dns_zt_apply(view->zonetable, false, NULL, count_zone,
&nzones);
result = dns_zt_apply(view->zonetable, isc_rwlocktype_read, false, NULL,
count_zone, &nzones);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(nzones, 1);