]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3298. [bug] Named could dereference a NULL pointer in
authorMark Andrews <marka@isc.org>
Thu, 22 Mar 2012 01:47:37 +0000 (12:47 +1100)
committerMark Andrews <marka@isc.org>
Thu, 22 Mar 2012 01:47:37 +0000 (12:47 +1100)
                        zmgr_start_xfrin_ifquota if the zone was being removed.
                        [RT #28419]

CHANGES
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index 78d5ec18f7c8b21543af8ede56ffc3dd23c9d52d..d223efd1e2736180d81977db7ab368f7c76fb095 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+3298.  [bug]           Named could dereference a NULL pointer in
+                       zmgr_start_xfrin_ifquota if the zone was being removed.
+                       [RT #28419]
+
 3297.  [bug]           Named could die on a malformed master file. [RT #28467]
 
 3295.  [bug]           Adjust isc_time_secondsastimet range check to be more
index 361577d45747e80bb37e9f1ec4c4cf8f45444147..11b7cc336ec6c7b4cf145d58e625618b4bb62d1c 100644 (file)
@@ -9985,11 +9985,13 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
         * This transfer finishing freed up a transfer quota slot.
         * Let any other zones waiting for quota have it.
         */
+       UNLOCK_ZONE(zone);
        RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
        ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
        zone->statelist = NULL;
        zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
        RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
+       LOCK_ZONE(zone);
 
        /*
         * Retry with a different server if necessary.
@@ -10927,13 +10929,23 @@ zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
        isc_uint32_t maxtransfersin, maxtransfersperns;
        isc_event_t *e;
 
+       /*
+        * If we are exiting just pretend we got quota so the zone will
+        * be cleaned up in the zone's task context.
+        */
+       LOCK_ZONE(zone);
+       if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
+               UNLOCK_ZONE(zone);
+               goto gotquota;
+       }
+
        /*
         * Find any configured information about the server we'd
         * like to transfer this zone from.
         */
        isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
-       (void)dns_peerlist_peerbyaddr(zone->view->peers,
-                                     &masterip, &peer);
+       (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
+       UNLOCK_ZONE(zone);
 
        /*
         * Determine the total maximum number of simultaneous
@@ -10957,7 +10969,11 @@ zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
             x = ISC_LIST_NEXT(x, statelink))
        {
                isc_netaddr_t xip;
+
+               LOCK_ZONE(x);
                isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
+               UNLOCK_ZONE(x);
+
                nxfrsin++;
                if (isc_netaddr_equal(&xip, &masterip))
                        nxfrsperns++;
@@ -10970,15 +10986,14 @@ zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
        if (nxfrsperns >= maxtransfersperns)
                return (ISC_R_QUOTA);
 
+ gotquota:
        /*
         * We have sufficient quota.  Move the zone to the "xfrin_in_progress"
         * list and send it an event to let it start the actual transfer in the
         * context of its own task.
         */
-       e = isc_event_allocate(zmgr->mctx, zmgr,
-                              DNS_EVENT_ZONESTARTXFRIN,
-                              got_transfer_quota, zone,
-                              sizeof(isc_event_t));
+       e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
+                              got_transfer_quota, zone, sizeof(isc_event_t));
        if (e == NULL)
                return (ISC_R_NOMEMORY);