Fix a race issue in dns_view_addzone()

Views use two types of reference counting - regular and weak, and
when there are no more regular references, the view_flushanddetach()
function destroys or detaches some parts of the view, including
'view->zonetable', while other parts are freed by destroy() when
the last weak reference is detached. Since catalog zones use weak
references to attach a view, it's currently possible that during
shutdown catalog zone processing will try to add a new zone into
an otherwise unused view (because it's shutting down) which doesn't
have an attached zonetable any more. This could cause an assertion
failure. Fix this issue by modifying the dns_view_addzone() function
to expect that 'view->zonetable' can be NULL, and in that case just
return ISC_R_SHUTTINGDOWN.
This commit is contained in:
Aram Sargsyan 2025-02-11 10:22:35 +00:00 committed by Arаm Sаrgsyаn
parent 853a966fe7
commit fc24cfd71d
2 changed files with 18 additions and 3 deletions

View file

@ -524,6 +524,12 @@ dns_view_addzone(dns_view_t *view, dns_zone_t *zone);
*\li 'view' is a valid, unfrozen view.
*
*\li 'zone' is a valid zone.
*
* Returns:
*
*\li #ISC_R_SUCCESS Success
*\li #ISC_R_SHUTTINGDOWN Shutting down
*\li Other values returned by dns_zt_mount()
*/
void

View file

@ -1010,13 +1010,22 @@ dns_view_thaw(dns_view_t *view) {
isc_result_t
dns_view_addzone(dns_view_t *view, dns_zone_t *zone) {
isc_result_t result;
isc_result_t result = ISC_R_SHUTTINGDOWN;
dns_zt_t *zt = NULL;
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(!view->frozen);
REQUIRE(view->zonetable != NULL);
result = dns_zt_mount(view->zonetable, zone);
LOCK(&view->lock);
if (view->zonetable != NULL) {
dns_zt_attach(view->zonetable, &zt);
}
UNLOCK(&view->lock);
if (zt != NULL) {
result = dns_zt_mount(zt, zone);
dns_zt_detach(&zt);
}
return result;
}