From 80a43c9241d7a58e0d6c68107dfb5891a01c05ad Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Mon, 12 May 2025 13:58:38 +0000 Subject: [PATCH] Prepare a zone for shutting down when deleting it from a view After b171cacf4f0123ba96bef6eedfc92dfb608db6b7, a zone object can remain in the memory for a while, until garbage collection is run. Setting the DNS_ZONEFLG_EXITING flag should prevent the zone maintenance function from running while it's in that state. Otherwise, a secondary zone could initiate a zone transfer after it had been deleted. (cherry picked from commit 874ca5ca2f1f381e434304e262ea08e77e3bdf65) --- lib/dns/include/dns/zone.h | 14 ++++++++++++++ lib/dns/view.c | 2 ++ lib/dns/zone.c | 9 +++++++++ 3 files changed, 25 insertions(+) diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 57ff194c2b..8573c1dce5 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -1757,6 +1757,20 @@ dns_zone_findkeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, *\li Error */ +void +dns_zone_prepare_shutdown(dns_zone_t *zone); +/*%< + * Prepare a zone for shutdown by setting the DNS_ZONEFLG_EXITING flag even + * before the final reference is detached. Useful, because the zone object can + * be kept around with a valid reference from the zonetable until qp garbage + * collector runs, and we don't want, for example, zone maintenance to happen + * while waiting for it. Note that the zone can not be used normally again after + * this function is called. + * + * Requires: + *\li 'zone' to be a valid initialised zone. + */ + void dns_zonemgr_create(isc_mem_t *mctx, isc_nm_t *netmgr, dns_zonemgr_t **zmgrp); /*%< diff --git a/lib/dns/view.c b/lib/dns/view.c index a82c078a70..b5d751ad54 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -785,6 +785,8 @@ dns_view_delzone(dns_view_t *view, dns_zone_t *zone) { REQUIRE(DNS_VIEW_VALID(view)); + dns_zone_prepare_shutdown(zone); + rcu_read_lock(); zonetable = rcu_dereference(view->zonetable); if (zonetable != NULL) { diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 845902b160..c070b38810 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -6401,6 +6401,15 @@ failure: return result; } +void +dns_zone_prepare_shutdown(dns_zone_t *zone) { + REQUIRE(DNS_ZONE_VALID(zone)); + + LOCK_ZONE(zone); + DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING); + UNLOCK_ZONE(zone); +} + /*% * Find DNSSEC keys used for signing zone with dnssec-policy. Load these keys * into 'keys'. Requires KASP to be locked.