From: Ondřej Surý Date: Tue, 17 Jan 2023 06:18:16 +0000 (+0100) Subject: Detach the views in zone_shutdown(), not in zone_free() X-Git-Tag: v9.19.10~39^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=13bb8212804ce385010387d681a6623481921023;p=thirdparty%2Fbind9.git Detach the views in zone_shutdown(), not in zone_free() The .view (and possibly .prev_view) would be kept attached to the removed zone until the zone is fully removed from the memory in zone_free(). If this process is delayed because server is busy something else like doing constant `rndc reconfig`, it could take seconds to detach the view, possibly keeping multiple dead views in the memory. This could quickly lead to a massive memory bloat. Release the views early in the zone_shutdown() call, and don't wait until the zone is freed. --- diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 28aeb00e047..411756d9cbe 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -1246,6 +1246,8 @@ zone_free(dns_zone_t *zone) { INSIST(zone->readio == NULL); INSIST(zone->statelist == NULL); INSIST(zone->writeio == NULL); + INSIST(zone->view == NULL); + INSIST(zone->prev_view == NULL); if (zone->task != NULL) { isc_task_detach(&zone->task); @@ -1253,12 +1255,6 @@ zone_free(dns_zone_t *zone) { if (zone->loadtask != NULL) { isc_task_detach(&zone->loadtask); } - if (zone->view != NULL) { - dns_view_weakdetach(&zone->view); - } - if (zone->prev_view != NULL) { - dns_view_weakdetach(&zone->prev_view); - } /* Unmanaged objects */ while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) { @@ -14737,6 +14733,15 @@ zone_shutdown(void *arg) { LOCK_ZONE(zone); INSIST(zone != zone->raw); + + /* Detach the views early, we don't need them anymore */ + if (zone->view != NULL) { + dns_view_weakdetach(&zone->view); + } + if (zone->prev_view != NULL) { + dns_view_weakdetach(&zone->prev_view); + } + if (linked) { isc_refcount_decrement(&zone->irefs); }