]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2157. [func] dns_db_transfernode() created. [RT #16685]
authorMark Andrews <marka@isc.org>
Tue, 6 Mar 2007 00:38:58 +0000 (00:38 +0000)
committerMark Andrews <marka@isc.org>
Tue, 6 Mar 2007 00:38:58 +0000 (00:38 +0000)
2156.   [bug]           Fix node reference leaks in lookup.c:lookup_find(),
                        resolver.c:validated() and resolver.c:cache_name().
                        Fix a memory leak in rbtdb.c:free_noqname().
                        Make lookup.c:lookup_find() robust against
                        event leaks. [RT #16685]

CHANGES
bin/tests/system/lwresd/tests.sh
lib/dns/db.c
lib/dns/include/dns/db.h
lib/dns/lookup.c
lib/dns/rbtdb.c
lib/dns/resolver.c
lib/dns/sdb.c
lib/dns/sdlz.c
lib/dns/view.c
lib/isc/mem.c

diff --git a/CHANGES b/CHANGES
index 0ccc9b679cd0ca873a066c57aaef1696eeca64c1..b448842d01188396bccb00303e6f6d867902fd34 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,11 @@
+2157.  [func]          dns_db_transfernode() created. [RT #16685]
+
+2156.  [bug]           Fix node reference leaks in lookup.c:lookup_find(),
+                       resolver.c:validated() and resolver.c:cache_name().
+                       Fix a memory leak in rbtdb.c:free_noqname().
+                       Make lookup.c:lookup_find() robust against
+                       event leaks. [RT #16685]
+
 2155.  [contrib]       SQLite sdb module from jaboydjr@netwalk.com.
                        [RT #16694]
 
index ceb8ca8bf518cd0405b30e3c70b8168cadbaaa3f..859d74ee928a5a51f12cdcb2c6c3ad65e4bf3c46 100644 (file)
@@ -15,7 +15,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: tests.sh,v 1.15 2004/03/05 05:01:20 marka Exp $
+# $Id: tests.sh,v 1.16 2007/03/06 00:38:57 marka Exp $
 
 SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
@@ -32,7 +32,7 @@ status=`expr $status + $ret`
 
 $PERL $SYSTEMTESTTOP/stop.pl . lwresd1
 
-$PERL $SYSTEMTESTTOP/start.pl . lwresd1 -- "-c lwresd.conf -d 99 -g"
+$PERL $SYSTEMTESTTOP/start.pl . lwresd1 -- "-m record,size,mctx -c lwresd.conf -d 99 -g"
 
 echo "I:using lwresd.conf"
 ret=0
index 52639b2a49952ee6ea28bc1ebdf0f7ecd3f8e11a..44e6ca36568526e1c22c5b22238eb9b2d8d9a13c 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: db.c,v 1.80 2005/10/13 01:58:31 marka Exp $ */
+/* $Id: db.c,v 1.81 2007/03/06 00:38:57 marka Exp $ */
 
 /*! \file */
 
@@ -527,6 +527,30 @@ dns_db_detachnode(dns_db_t *db, dns_dbnode_t **nodep) {
        ENSURE(*nodep == NULL);
 }
 
+void
+dns_db_transfernode(dns_db_t *db, dns_dbnode_t **sourcep,
+                   dns_dbnode_t **targetp)
+{
+       REQUIRE(DNS_DB_VALID(db));
+       REQUIRE(targetp != NULL && *targetp == NULL);
+       /*
+        * This doesn't check the implementation magic.  If we find that
+        * we need such checks in future then this will be done in the
+        * method.
+        */
+       REQUIRE(sourcep != NULL && *sourcep != NULL);
+
+       UNUSED(db);
+
+       if (db->methods->transfernode == NULL) {
+               *targetp = *sourcep;
+               *sourcep = NULL;
+       } else
+               (db->methods->transfernode)(db, sourcep, targetp);
+
+       ENSURE(*sourcep == NULL);
+}
+
 isc_result_t
 dns_db_expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
 
index 1d62ca0de79e3a5366cf7b2ddf7a3454de51c130..53f3d2c2f2bfa0e6ed1f667bb15db937752b8c14 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: db.h,v 1.86 2006/12/22 01:59:43 marka Exp $ */
+/* $Id: db.h,v 1.87 2007/03/06 00:38:57 marka Exp $ */
 
 #ifndef DNS_DB_H
 #define DNS_DB_H 1
@@ -146,6 +146,8 @@ typedef struct dns_dbmethods {
        void            (*overmem)(dns_db_t *db, isc_boolean_t overmem);
        void            (*settask)(dns_db_t *db, isc_task_t *);
        isc_result_t    (*getoriginnode)(dns_db_t *db, dns_dbnode_t **nodep);
+       void            (*transfernode)(dns_db_t *db, dns_dbnode_t **sourcep,
+                                       dns_dbnode_t **targetp);
 } dns_dbmethods_t;
 
 typedef isc_result_t
@@ -860,7 +862,7 @@ dns_db_attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp);
  *
  * \li 'source' is a valid node.
  *
- * \li 'targetp' points to a NULL dns_node_t *.
+ * \li 'targetp' points to a NULL dns_dbnode_t *.
  *
  * Ensures:
  *
@@ -883,6 +885,27 @@ dns_db_detachnode(dns_db_t *db, dns_dbnode_t **nodep);
  * \li *nodep is NULL.
  */
 
+void
+dns_db_transfernode(dns_db_t *db, dns_dbnode_t **sourcep, 
+                    dns_dbnode_t **targetp);
+/*%<
+ * Transfer a node between pointer.
+ *
+ * This is equivalent to calling dns_db_attachnode() then dns_db_detachnode().
+ *
+ * Requires:
+ *
+ * \li 'db' is a valid database.
+ *
+ * \li '*sourcep' is a valid node.
+ *
+ * \li 'targetp' points to a NULL dns_dbnode_t *.
+ *
+ * Ensures:
+ *
+ * \li '*sourcep' is NULL.
+ */
+
 isc_result_t
 dns_db_expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now);
 /*%<
index ee1582349f5b5649ce4490952c881d15d57ca7ee..1a810a1e3b0ac1f21f7b12ab42f84a9cf00590d0 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: lookup.c,v 1.18 2005/11/30 03:33:49 marka Exp $ */
+/* $Id: lookup.c,v 1.19 2007/03/06 00:38:57 marka Exp $ */
 
 /*! \file */
 
@@ -181,7 +181,7 @@ static void
 lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event) {
        isc_result_t result;
        isc_boolean_t want_restart;
-       isc_boolean_t send_event = ISC_FALSE;
+       isc_boolean_t send_event;
        dns_name_t *name, *fname, *prefix;
        dns_fixedname_t foundname, fixed;
        dns_rdata_t rdata = DNS_RDATA_INIT;
@@ -201,6 +201,7 @@ lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event) {
        do {
                lookup->restarts++;
                want_restart = ISC_FALSE;
+               send_event = ISC_TRUE;
 
                if (event == NULL && !lookup->canceled) {
                        dns_fixedname_init(&foundname);
@@ -208,6 +209,15 @@ lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event) {
                        INSIST(!dns_rdataset_isassociated(&lookup->rdataset));
                        INSIST(!dns_rdataset_isassociated
                                                (&lookup->sigrdataset));
+                       /*
+                        * If we have restarted then clear the old node.                                 */
+                       if  (lookup->event->node != NULL) {
+                               INSIST(lookup->event->db != NULL);
+                               dns_db_detachnode(lookup->event->db,
+                                                &lookup->event->node);
+                       }
+                       if (lookup->event->db != NULL)
+                               dns_db_detach(&lookup->event->db);
                        result = view_find(lookup, fname);
                        if (result == ISC_R_NOTFOUND) {
                                /*
@@ -222,8 +232,8 @@ lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event) {
                                if (lookup->event->db != NULL)
                                        dns_db_detach(&lookup->event->db);
                                result = start_fetch(lookup);
-                               if (result != ISC_R_SUCCESS)
-                                       send_event = ISC_TRUE;
+                               if (result == ISC_R_SUCCESS)
+                                       send_event = ISC_FALSE;
                                goto done;
                        }
                } else if (event != NULL) {
@@ -244,7 +254,6 @@ lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event) {
                switch (result) {
                case ISC_R_SUCCESS:
                        result = build_event(lookup);
-                       send_event = ISC_TRUE;
                        if (event == NULL)
                                break;
                        if (event->db != NULL)
@@ -269,8 +278,10 @@ lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event) {
                                break;
                        result = dns_name_copy(&cname.cname, name, NULL);
                        dns_rdata_freestruct(&cname);
-                       if (result == ISC_R_SUCCESS)
+                       if (result == ISC_R_SUCCESS) {
                                want_restart = ISC_TRUE;
+                               send_event = ISC_FALSE;
+                       }
                        break;
                case DNS_R_DNAME:
                        namereln = dns_name_fullcompare(name, fname, &order,
@@ -296,8 +307,10 @@ lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event) {
                        result = dns_name_concatenate(prefix, &dname.dname,
                                                      name, NULL);
                        dns_rdata_freestruct(&dname);
-                       if (result == ISC_R_SUCCESS)
+                       if (result == ISC_R_SUCCESS) {
                                want_restart = ISC_TRUE;
+                               send_event = ISC_FALSE;
+                       }
                        break;
                default:
                        send_event = ISC_TRUE;
@@ -368,7 +381,6 @@ levent_destroy(isc_event_t *event) {
        isc_mem_put(mctx, event, event->ev_size);
 }
 
-
 isc_result_t
 dns_lookup_create(isc_mem_t *mctx, dns_name_t *name, dns_rdatatype_t type,
                  dns_view_t *view, unsigned int options, isc_task_t *task,
index 2d075f576bf6407aeaa89fc70a5fcdb6e82619d6..7367d05628b6b6e3a5871f1ea08c0b35bfa32370 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rbtdb.c,v 1.241 2007/02/26 23:46:54 tbox Exp $ */
+/* $Id: rbtdb.c,v 1.242 2007/03/06 00:38:57 marka Exp $ */
 
 /*! \file */
 
@@ -902,7 +902,7 @@ free_noqname(isc_mem_t *mctx, struct noqname **noqname) {
        if ((*noqname)->nsec != NULL)
                isc_mem_put(mctx, (*noqname)->nsec,
                            dns_rdataslab_size((*noqname)->nsec, 0));
-       if ((*noqname)->nsec != NULL)
+       if ((*noqname)->nsecsig != NULL)
                isc_mem_put(mctx, (*noqname)->nsecsig,
                            dns_rdataslab_size((*noqname)->nsecsig, 0));
        isc_mem_put(mctx, *noqname, sizeof(**noqname));
@@ -5388,7 +5388,8 @@ static dns_dbmethods_t zone_methods = {
        ispersistent,
        overmem,
        settask,
-       getoriginnode
+       getoriginnode,
+       NULL,
 };
 
 static dns_dbmethods_t cache_methods = {
@@ -5419,7 +5420,8 @@ static dns_dbmethods_t cache_methods = {
        ispersistent,
        overmem,
        settask,
-       getoriginnode
+       getoriginnode,
+       NULL
 };
 
 isc_result_t
index 1a0b40c9165dea648aee314b4da665e7d07910d0..52a44b5108edca4827e9ad2c82ae33c86f1b021d 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: resolver.c,v 1.344 2007/02/26 01:07:49 marka Exp $ */
+/* $Id: resolver.c,v 1.345 2007/03/06 00:38:57 marka Exp $ */
 
 /*! \file */
 
@@ -3589,6 +3589,7 @@ validated(isc_task_t *task, isc_event_t *event) {
                 * If we only deferred the destroy because we wanted to cache
                 * the data, destroy now.
                 */
+               dns_db_detachnode(fctx->cache, &node);
                UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
                if (SHUTTINGDOWN(fctx))
                        maybe_destroy(fctx);    /* Locks bucket. */
@@ -3605,6 +3606,7 @@ validated(isc_task_t *task, isc_event_t *event) {
                 * more rdatasets that still need to
                 * be validated.
                 */
+               dns_db_detachnode(fctx->cache, &node);
                UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
                dns_validator_send(ISC_LIST_HEAD(fctx->validators));
                goto cleanup_event;
@@ -3670,8 +3672,7 @@ validated(isc_task_t *task, isc_event_t *event) {
                              dns_fixedname_name(&hevent->foundname), NULL)
                              == ISC_R_SUCCESS);
                dns_db_attach(fctx->cache, &hevent->db);
-               hevent->node = node;
-               node = NULL;
+               dns_db_transfernode(fctx->cache, &node, &hevent->node);
                clone_results(fctx);
        }
 
@@ -3684,6 +3685,7 @@ validated(isc_task_t *task, isc_event_t *event) {
        fctx_done(fctx, result);        /* Locks bucket. */
 
  cleanup_event:
+       INSIST(node == NULL);
        isc_event_free(&event);
 }
 
@@ -3803,8 +3805,10 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
                                      fail ? "failure" : "warning",
                                      namebuf, typebuf, classbuf);
                        if (fail) {
-                               if (ANSWER(rdataset))
+                               if (ANSWER(rdataset)) {
+                                       dns_db_detachnode(fctx->cache, &node);
                                        return (DNS_R_BADNAME);
+                               }
                                continue;
                        }
                }
@@ -4010,8 +4014,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
                if (event != NULL) {
                        event->result = eresult;
                        dns_db_attach(fctx->cache, adbp);
-                       *anodep = node;
-                       node = NULL;
+                       dns_db_transfernode(fctx->cache, &node, anodep);
                        clone_results(fctx);
                }
        }
@@ -4251,8 +4254,7 @@ ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
                if (event != NULL) {
                        event->result = eresult;
                        dns_db_attach(fctx->cache, adbp);
-                       *anodep = node;
-                       node = NULL;
+                       dns_db_transfernode(fctx->cache, &node, anodep);
                        clone_results(fctx);
                }
        }
index 618d7a38fbe8b06303dc424fe1bb605f74dae16a..468df3adec16c82427f79255713b17767c50d99e 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: sdb.c,v 1.55 2006/12/07 23:57:59 marka Exp $ */
+/* $Id: sdb.c,v 1.56 2007/03/06 00:38:57 marka Exp $ */
 
 /*! \file */
 
@@ -1241,6 +1241,7 @@ static dns_dbmethods_t sdb_methods = {
        ispersistent,
        overmem,
        settask,
+       NULL,
        NULL
 };
 
index 6344b640e1fc61e8c6cc5f5f70d3e38dc87dda7f..5a0686044511262dd3cdd5715bc1071d25d4b0c0 100644 (file)
@@ -50,7 +50,7 @@
  * USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: sdlz.c,v 1.11 2007/02/14 23:45:44 marka Exp $ */
+/* $Id: sdlz.c,v 1.12 2007/03/06 00:38:57 marka Exp $ */
 
 /*! \file */
 
@@ -1046,6 +1046,7 @@ static dns_dbmethods_t sdlzdb_methods = {
        overmem,
        settask,
        NULL,
+       NULL
 };
 
 /*
index 41cd8f131f46fbede097c2a2dd4a0522c179acfa..c741f3e855de8d00438230004bf2ce62e77e315c 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: view.c,v 1.138 2006/12/21 06:02:30 marka Exp $ */
+/* $Id: view.c,v 1.139 2007/03/06 00:38:57 marka Exp $ */
 
 /*! \file */
 
@@ -704,6 +704,7 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
        REQUIRE(view->frozen);
        REQUIRE(type != dns_rdatatype_rrsig);
        REQUIRE(rdataset != NULL);  /* XXXBEW - remove this */
+       REQUIRE(nodep == NULL || *nodep == NULL);
 
        /*
         * Initialize.
index 21e1f28087d39a5bb5ed333bf6f368eb7a5823be..e2c7b006991ef32a02e9ada4630a8127a7034f48 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: mem.c,v 1.133 2007/02/27 03:31:04 marka Exp $ */
+/* $Id: mem.c,v 1.134 2007/03/06 00:38:58 marka Exp $ */
 
 /*! \file */
 
@@ -1948,7 +1948,7 @@ isc_mem_checkdestroyed(FILE *file) {
                }
                fflush(file);
 #endif
-               /* INSIST(0); XXXMPA temorarially comment out. */
+               INSIST(0);
        }
        UNLOCK(&lock);
 }