]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2156. [bug] Fix node reference leaks in lookup.c:lookup_find(),
authorMark Andrews <marka@isc.org>
Tue, 6 Mar 2007 00:51:29 +0000 (00:51 +0000)
committerMark Andrews <marka@isc.org>
Tue, 6 Mar 2007 00:51:29 +0000 (00:51 +0000)
                        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/include/dns/db.h
lib/dns/lookup.c
lib/dns/rbtdb.c
lib/dns/resolver.c
lib/dns/view.c

diff --git a/CHANGES b/CHANGES
index ef5c326673cae3e95e406dbd64444124ba12ed6b..41aab369cb630aef859979fa4b058142ea1ec6b2 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,9 @@
+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 2c26530241002311189e6416b42fce235e0d4fff..4e9e80e7b09582a4ee7d139d6e68945dfc40fb08 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.14.206.1 2004/03/06 10:22:10 marka Exp $
+# $Id: tests.sh,v 1.14.206.2 2007/03/06 00:51:29 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 8e088823ac2ee81dfc13aa82ebe167f2605d5971..8dacbefe3e1be87dc6bfc380ce8716eed4aec820 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: db.h,v 1.67.12.8 2004/05/14 05:06:41 marka Exp $ */
+/* $Id: db.h,v 1.67.12.9 2007/03/06 00:51:29 marka Exp $ */
 
 #ifndef DNS_DB_H
 #define DNS_DB_H 1
@@ -852,7 +852,7 @@ dns_db_attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp);
  *
  *     'source' is a valid node.
  *
- *     'targetp' points to a NULL dns_node_t *.
+ *     'targetp' points to a NULL dns_dbnode_t *.
  *
  * Ensures:
  *
index 1cf572145dbb5802df59d6f7ebd9651e36b7dc17..5c6c5190e304245ab7cb4fe96f1e06d6c41c1d93 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: lookup.c,v 1.9.12.7 2006/01/04 23:50:20 marka Exp $ */
+/* $Id: lookup.c,v 1.9.12.8 2007/03/06 00:51:29 marka Exp $ */
 
 #include <config.h>
 
@@ -179,7 +179,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;
@@ -199,6 +199,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);
@@ -206,6 +207,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) {
                                /*
@@ -220,8 +230,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) {
@@ -242,7 +252,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)
@@ -267,8 +276,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,
@@ -294,8 +305,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;
@@ -366,7 +379,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 1b405848074a783e45097288e282b316cbc0fceb..e223005f4b52ce66de5474f40d0160a19ee95dba 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rbtdb.c,v 1.168.2.11.2.28 2007/02/26 23:45:55 tbox Exp $ */
+/* $Id: rbtdb.c,v 1.168.2.11.2.29 2007/03/06 00:51:29 marka Exp $ */
 
 /*
  * Principal Author: Bob Halley
@@ -658,7 +658,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));
index 21df96cd64fd728f19793ca33ec6796423ea2ddc..7db1898b96a25379ce19e2e4e1d6c24c515d8642 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: resolver.c,v 1.218.2.18.4.69 2007/02/26 01:14:05 marka Exp $ */
+/* $Id: resolver.c,v 1.218.2.18.4.70 2007/03/06 00:51:29 marka Exp $ */
 
 #include <config.h>
 
@@ -245,7 +245,7 @@ struct fetchctx {
 #define ADDRWAIT(f)            (((f)->attributes & FCTX_ATTR_ADDRWAIT) != \
                                 0)
 #define SHUTTINGDOWN(f)                (((f)->attributes & FCTX_ATTR_SHUTTINGDOWN) \
-                                != 0)
+                                != 0)
 #define WANTCACHE(f)           (((f)->attributes & FCTX_ATTR_WANTCACHE) != 0)
 #define WANTNCACHE(f)          (((f)->attributes & FCTX_ATTR_WANTNCACHE) != 0)
 #define NEEDEDNS0(f)           (((f)->attributes & FCTX_ATTR_NEEDEDNS0) != 0)
@@ -342,6 +342,8 @@ struct dns_resolver {
 
 #define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
 
+#define dns_db_transfernode(a,b,c) do { (*c) = (*b); (*b) = NULL; } while (0)
+
 static void destroy(dns_resolver_t *res);
 static void empty_bucket(dns_resolver_t *res);
 static isc_result_t resquery_send(resquery_t *query);
@@ -2987,7 +2989,7 @@ is_lame(fetchctx_t *fctx) {
                        if (rdataset->type != dns_rdatatype_ns)
                                continue;
                        namereln = dns_name_fullcompare(name, &fctx->domain,
-                                                       &order, &labels);
+                                                       &order, &labels);
                        if (namereln == dns_namereln_equal &&
                            (message->flags & DNS_MESSAGEFLAG_AA) != 0)
                                return (ISC_FALSE);
@@ -3347,6 +3349,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. */
@@ -3363,6 +3366,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;
@@ -3428,8 +3432,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);
        }
 
@@ -3442,6 +3445,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);
 }
 
@@ -3559,8 +3563,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;
                        }
                }
@@ -3766,8 +3772,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);
                }
        }
@@ -4005,8 +4010,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);
                }
        }
@@ -6679,7 +6683,7 @@ static isc_boolean_t yes = ISC_TRUE, no = ISC_FALSE;
 
 isc_result_t
 dns_resolver_setmustbesecure(dns_resolver_t *resolver, dns_name_t *name,
-                             isc_boolean_t value)
+                            isc_boolean_t value)
 {
        isc_result_t result;
 
index ac7af61639de06b4e5cd9325574e174f7514ac04..9a42794f5071468baf1aafd769c2390323c60107 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: view.c,v 1.103.2.5.2.14 2004/03/10 02:55:58 marka Exp $ */
+/* $Id: view.c,v 1.103.2.5.2.15 2007/03/06 00:51:29 marka Exp $ */
 
 #include <config.h>
 
@@ -679,6 +679,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.