]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3077. [bug] zone.c:zone_refreshkeys() incorrectly called
authorMark Andrews <marka@isc.org>
Thu, 17 Mar 2011 05:21:50 +0000 (05:21 +0000)
committerMark Andrews <marka@isc.org>
Thu, 17 Mar 2011 05:21:50 +0000 (05:21 +0000)
                       dns_zone_attach(), use zone->irefs instead. [RT #23303]

CHANGES
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index b18a627f69d34a4d15cda4b24504b1786fa54ebd..006f08e9316ff7b23c65c7ea087ba1eed63d5d17 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+3077.  [bug]           zone.c:zone_refreshkeys() incorrectly called
+                       dns_zone_attach(), use zone->irefs instead. [RT #23303]
+
 3076.  [func]          New '-L' option in dnssec-keygen, dnsset-settime, and
                        dnssec-keyfromlabel sets the default TTL of the
                        key.  When possible, automatic signing will use that
index 834cbe3fe84cc416cd7c3c6357b2d779515baa0a..651adf707cf9dc02539d5bdd84822de215c38a47 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.596 2011/03/11 13:20:43 marka Exp $ */
+/* $Id: zone.c,v 1.597 2011/03/17 05:21:50 marka Exp $ */
 
 /*! \file */
 
@@ -7216,6 +7216,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
        isc_stdtime_t now;
        int pending = 0;
        isc_boolean_t secure;
+       isc_boolean_t free_needed;
 
        UNUSED(task);
        INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
@@ -7237,16 +7238,20 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
        isc_event_free(&event);
        dns_resolver_destroyfetch(&kfetch->fetch);
 
+       LOCK_ZONE(zone);
+       if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL)
+               goto cleanup;
+
        isc_stdtime_get(&now);
        dns_name_format(keyname, namebuf, sizeof(namebuf));
 
        result = dns_view_getsecroots(zone->view, &secroots);
        INSIST(result == ISC_R_SUCCESS);
 
-       LOCK_ZONE(zone);
-       dns_db_newversion(kfetch->db, &ver);
        dns_diff_init(mctx, &diff);
 
+       CHECK(dns_db_newversion(kfetch->db, &ver));
+
        zone->refreshkeycount--;
        alldone = ISC_TF(zone->refreshkeycount == 0);
 
@@ -7607,12 +7612,17 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
        }
 
   failure:
-       UNLOCK_ZONE(zone);
 
        dns_diff_clear(&diff);
-       dns_db_closeversion(kfetch->db, &ver, commit);
+       if (ver != NULL)
+               dns_db_closeversion(kfetch->db, &ver, commit);
+
+ cleanup:
        dns_db_detach(&kfetch->db);
-       dns_zone_detach(&kfetch->zone);
+
+       INSIST(zone->irefs > 0);
+       zone->irefs--;
+       kfetch->zone = NULL;
 
        if (dns_rdataset_isassociated(&kfetch->keydataset))
                dns_rdataset_disassociate(&kfetch->keydataset);
@@ -7627,6 +7637,11 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
 
        if (secroots != NULL)
                dns_keytable_detach(&secroots);
+
+       free_needed = exit_check(zone);
+       UNLOCK_ZONE(zone);
+       if (free_needed)
+               zone_free(zone);
 }
 
 /*
@@ -7651,14 +7666,21 @@ zone_refreshkeys(dns_zone_t *zone) {
 
        isc_stdtime_get(&now);
 
+       LOCK_ZONE(zone);
+       if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
+               isc_time_settoepoch(&zone->refreshkeytime);
+               UNLOCK_ZONE(zone);
+               return;
+       }
+
        ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
        dns_db_attach(zone->db, &db);
        ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
 
-       LOCK_ZONE(zone);
-       dns_db_newversion(db, &ver);
        dns_diff_init(zone->mctx, &diff);
 
+       CHECK(dns_db_newversion(db, &ver));
+
        DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
 
        dns_rriterator_init(&rrit, db, ver, 0);
@@ -7713,8 +7735,9 @@ zone_refreshkeys(dns_zone_t *zone) {
                zone->refreshkeycount++;
 
                kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
-               kfetch->zone = NULL;
-               dns_zone_attach(zone, &kfetch->zone);
+               kfetch->zone = zone;
+               zone->irefs++;
+               INSIST(zone->irefs != 0);
                dns_fixedname_init(&kfetch->name);
                dns_name_dup(name, zone->mctx,
                             dns_fixedname_name(&kfetch->name));
@@ -7743,12 +7766,15 @@ zone_refreshkeys(dns_zone_t *zone) {
                DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
                zone_needdump(zone, 30);
        }
+
   failure:
        UNLOCK_ZONE(zone);
 
-       dns_rriterator_destroy(&rrit);
        dns_diff_clear(&diff);
-       dns_db_closeversion(db, &ver, commit);
+       if (ver != NULL) {
+               dns_rriterator_destroy(&rrit);
+               dns_db_closeversion(db, &ver, commit);
+       }
        dns_db_detach(&db);
 }
 
@@ -10054,7 +10080,13 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
                        dns_db_settask(stub->db, zone->task);
                }
 
-               dns_db_newversion(stub->db, &stub->version);
+               result = dns_db_newversion(stub->db, &stub->version);
+               if (result != ISC_R_SUCCESS) {
+                       dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
+                                    "dns_db_newversion() failed: %s",
+                                    dns_result_totext(result));
+                       goto cleanup;
+               }
 
                /*
                 * Update SOA record.
@@ -10062,8 +10094,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
                result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
                                         &node);
                if (result != ISC_R_SUCCESS) {
-                       dns_zone_log(zone, ISC_LOG_INFO,
-                                    "refreshing stub: "
+                       dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
                                     "dns_db_findnode() failed: %s",
                                     dns_result_totext(result));
                        goto cleanup;