From fc3b3e1f7e4ec1cf3bcc08f7ecc3ed8ebd29b034 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 7 Feb 2012 00:47:21 +0000 Subject: [PATCH] 3278. [bug] Hold a internal reference to the zone while performing a asynchronous load. Address potential memory leak if the asynchronous is cancelled. [RT #27750] --- CHANGES | 6 +++++- lib/dns/zone.c | 9 ++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 483d8db322..8922806565 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +3278. [bug] Hold a internal reference to the zone while performing + a asynchronous load. Address potential memory leak + if the asynchronous is cancelled. [RT #27750] + 3277. [bug] Make sure automatic key maintenance is started when "auto-dnssec maintain" is turned on during "rndc reconfig". [RT #26805] @@ -8,7 +12,7 @@ safe_open failure. [RT #27696] 3275. [bug] Corrected rndc -h output; the 'rndc sync -clean' - option had been missplled as '-clear'. (To avoid + option had been misspelled as '-clear'. (To avoid future confusion, both options now work.) [RT #27173] 3274. [placeholder] diff --git a/lib/dns/zone.c b/lib/dns/zone.c index c9f6f8d73c..3e8b1ef212 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.671 2012/02/03 12:59:03 marka Exp $ */ +/* $Id: zone.c,v 1.672 2012/02/07 00:47:21 marka Exp $ */ /*! \file */ @@ -1711,7 +1711,7 @@ zone_asyncload(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); if (result == ISC_R_CANCELED || !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) - return; + goto cleanup; zone_load(zone, 0); @@ -1723,7 +1723,9 @@ zone_asyncload(isc_task_t *task, isc_event_t *event) { if (asl->loaded != NULL) (asl->loaded)(asl->loaded_arg, zone, task); + cleanup: isc_mem_put(zone->mctx, asl, sizeof (*asl)); + dns_zone_idetach(&zone); } isc_result_t @@ -1741,7 +1743,7 @@ dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) { if (asl == NULL) CHECK(ISC_R_NOMEMORY); - asl->zone = zone; + asl->zone = NULL; asl->loaded = done; asl->loaded_arg = arg; @@ -1753,6 +1755,7 @@ dns_zone_asyncload(dns_zone_t *zone, dns_zt_zoneloaded_t done, void *arg) { CHECK(ISC_R_NOMEMORY); LOCK_ZONE(zone); + zone_iattach(zone, &asl->zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING); isc_task_send(zone->loadtask, &e); UNLOCK_ZONE(zone);