2156. [bug] Fix node reference leaks in lookup.c:lookup_find(),

resolver.c:validated() and resolver.c:cache_name().
                        Make lookup.c:lookup_find() robust against
                        event leaks. [RT #16685]
This commit is contained in:
Mark Andrews
2007-03-06 01:00:55 +00:00
parent b9dcad9a3c
commit af3849840c
5 changed files with 42 additions and 22 deletions

View File

@@ -1,3 +1,8 @@
2156. [bug] Fix node reference leaks in lookup.c:lookup_find(),
resolver.c:validated() and resolver.c:cache_name().
Make lookup.c:lookup_find() robust against
event leaks. [RT #16685]
2155. [contrib] SQLite sdb module from jaboydjr@netwalk.com.
[RT #16694]

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: db.h,v 1.67.2.4 2004/03/09 06:11:14 marka Exp $ */
/* $Id: db.h,v 1.67.2.5 2007/03/06 01:00:55 marka Exp $ */
#ifndef DNS_DB_H
#define DNS_DB_H 1
@@ -825,7 +825,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:
*

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: lookup.c,v 1.9.2.5 2006/01/04 23:50:17 marka Exp $ */
/* $Id: lookup.c,v 1.9.2.6 2007/03/06 01:00:54 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,
@@ -299,8 +310,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;
@@ -371,7 +384,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,

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: resolver.c,v 1.218.2.48 2007/01/08 02:45:02 marka Exp $ */
/* $Id: resolver.c,v 1.218.2.49 2007/03/06 01:00:54 marka Exp $ */
#include <config.h>
@@ -218,7 +218,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)
@@ -283,6 +283,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);
@@ -495,7 +497,7 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
dns_adbaddrinfo_t *addrinfo;
factor = DNS_ADB_RTTADJAGE;
for (find = ISC_LIST_HEAD(fctx->finds);
for (find = ISC_LIST_HEAD(fctx->finds);
find != NULL;
find = ISC_LIST_NEXT(find, publink))
for (addrinfo = ISC_LIST_HEAD(find->list);
@@ -2498,7 +2500,7 @@ is_lame(fetchctx_t *fctx) {
if (rdataset->type != dns_rdatatype_ns)
continue;
namereln = dns_name_fullcompare(name, &fctx->domain,
&order, &labels, &bits);
&order, &labels, &bits);
if (namereln == dns_namereln_equal &&
(message->flags & DNS_MESSAGEFLAG_AA) != 0)
return (ISC_FALSE);
@@ -2828,6 +2830,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);
if (SHUTTINGDOWN(fctx))
maybe_destroy(fctx);
@@ -2843,6 +2846,7 @@ validated(isc_task_t *task, isc_event_t *event) {
* more rdatasets that still need to
* be validated.
*/
dns_db_detachnode(fctx->cache, &node);
dns_validator_send(ISC_LIST_HEAD(fctx->validators));
goto cleanup_event;
}
@@ -2862,8 +2866,7 @@ validated(isc_task_t *task, isc_event_t *event) {
dns_name_copy(vevent->name,
dns_fixedname_name(&hevent->foundname), NULL);
dns_db_attach(fctx->cache, &hevent->db);
hevent->node = node;
node = NULL;
dns_db_transfernode(fctx->cache, &node, &hevent->node);
clone_results(fctx);
}
@@ -2874,6 +2877,7 @@ validated(isc_task_t *task, isc_event_t *event) {
fctx_done(fctx, result);
cleanup_event:
INSIST(node == NULL);
isc_event_free(&event);
}
@@ -3115,7 +3119,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
}
if (rdataset->trust == dns_trust_glue &&
(rdataset->type == dns_rdatatype_ns ||
(rdataset->type == dns_rdatatype_sig &&
(rdataset->type == dns_rdatatype_sig &&
rdataset->covers == dns_rdatatype_ns))) {
/*
* If the trust level is 'dns_trust_glue'
@@ -3180,8 +3184,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
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);
}
}
@@ -3412,8 +3415,7 @@ ncache_message(fetchctx_t *fctx, dns_rdatatype_t covers, isc_stdtime_t now) {
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);
}
}

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: view.c,v 1.103.2.10 2004/03/09 06:11:10 marka Exp $ */
/* $Id: view.c,v 1.103.2.11 2007/03/06 01:00:54 marka Exp $ */
#include <config.h>
@@ -660,6 +660,7 @@ dns_view_find(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
REQUIRE(view->frozen);
REQUIRE(type != dns_rdatatype_sig);
REQUIRE(rdataset != NULL); /* XXXBEW - remove this */
REQUIRE(nodep == NULL || *nodep == NULL);
/*
* Initialize.