From: Mark Andrews Date: Tue, 6 Mar 2007 00:51:29 +0000 (+0000) Subject: 2156. [bug] Fix node reference leaks in lookup.c:lookup_find(), X-Git-Tag: v9.3.0^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d40085857415dc38d3bfb9cd9ef35eb7277699c;p=thirdparty%2Fbind9.git 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] --- diff --git a/CHANGES b/CHANGES index ef5c326673c..41aab369cb6 100644 --- 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] diff --git a/bin/tests/system/lwresd/tests.sh b/bin/tests/system/lwresd/tests.sh index 2c265302410..4e9e80e7b09 100644 --- a/bin/tests/system/lwresd/tests.sh +++ b/bin/tests/system/lwresd/tests.sh @@ -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 diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h index 8e088823ac2..8dacbefe3e1 100644 --- a/lib/dns/include/dns/db.h +++ b/lib/dns/include/dns/db.h @@ -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: * diff --git a/lib/dns/lookup.c b/lib/dns/lookup.c index 1cf572145db..5c6c5190e30 100644 --- a/lib/dns/lookup.c +++ b/lib/dns/lookup.c @@ -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 @@ -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, diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 1b405848074..e223005f4b5 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -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)); diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 21df96cd64f..7db1898b96a 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -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 @@ -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; diff --git a/lib/dns/view.c b/lib/dns/view.c index ac7af61639d..9a42794f507 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -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 @@ -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.