From: Mark Andrews Date: Thu, 11 Jan 2007 05:05:10 +0000 (+0000) Subject: 2124. [bug] It was possible to dereference a freed fetch X-Git-Tag: v9.3.4^5~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0c4e6afde72b137f653a2fac69c77edb8c343d09;p=thirdparty%2Fbind9.git 2124. [bug] It was possible to dereference a freed fetch context. [RT #16584] --- diff --git a/CHANGES b/CHANGES index 56fd95a5e01..6d73e04c2c6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ 2126. [bug] Serialise validation of type ANY responses. [RT #16555] +2124. [bug] It was possible to dereference a freed fetch + context. [RT #16584] + --- 9.3.3 released --- 2107. [bug] dighost.c: more cleanup of buffers. [RT #16499] diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index d583f5349cc..a56fecfd3ce 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.64.4.1 2007/01/11 04:51:39 marka Exp $ */ +/* $Id: resolver.c,v 1.218.2.18.4.64.4.2 2007/01/11 05:05:10 marka Exp $ */ #include @@ -218,6 +218,11 @@ struct fetchctx { dns_name_t nsname; dns_fetch_t * nsfetch; dns_rdataset_t nsrrset; + + /*% + * Number of queries that reference this context. + */ + unsigned int nqueries; }; #define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!') @@ -351,6 +356,7 @@ static isc_result_t ncache_adderesult(dns_message_t *message, dns_rdataset_t *ardataset, isc_result_t *eresultp); static void validated(isc_task_t *task, isc_event_t *event); +static void maybe_destroy(fetchctx_t *fctx); static isc_result_t valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name, @@ -518,6 +524,9 @@ resquery_destroy(resquery_t **queryp) { INSIST(query->tcpsocket == NULL); + query->fctx->nqueries--; + if (SHUTTINGDOWN(query->fctx)) + maybe_destroy(query->fctx); /* Locks bucket. */ query->magic = 0; isc_mem_put(query->mctx, query, sizeof(*query)); *queryp = NULL; @@ -1093,6 +1102,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, } ISC_LIST_APPEND(fctx->queries, query, link); + query->fctx->nqueries++; return (ISC_R_SUCCESS); @@ -1545,7 +1555,7 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) { want_done = ISC_TRUE; } } else if (SHUTTINGDOWN(fctx) && fctx->pending == 0 && - ISC_LIST_EMPTY(fctx->validators)) { + fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) { bucketnum = fctx->bucketnum; LOCK(&res->buckets[bucketnum].lock); /* @@ -2399,8 +2409,8 @@ fctx_destroy(fetchctx_t *fctx) { REQUIRE(ISC_LIST_EMPTY(fctx->finds)); REQUIRE(ISC_LIST_EMPTY(fctx->altfinds)); REQUIRE(fctx->pending == 0); - REQUIRE(ISC_LIST_EMPTY(fctx->validators)); REQUIRE(fctx->references == 0); + REQUIRE(ISC_LIST_EMPTY(fctx->validators)); FCTXTRACE("destroy"); @@ -2574,7 +2584,7 @@ fctx_doshutdown(isc_task_t *task, isc_event_t *event) { } if (fctx->references == 0 && fctx->pending == 0 && - ISC_LIST_EMPTY(fctx->validators)) + fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) bucket_empty = fctx_destroy(fctx); UNLOCK(&res->buckets[bucketnum].lock); @@ -2615,6 +2625,7 @@ fctx_start(isc_task_t *task, isc_event_t *event) { * pending ADB finds and no pending validations. */ INSIST(fctx->pending == 0); + INSIST(fctx->nqueries == 0); INSIST(ISC_LIST_EMPTY(fctx->validators)); if (fctx->references == 0) { /* @@ -2776,6 +2787,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, fctx->restarts = 0; fctx->timeouts = 0; fctx->attributes = 0; + fctx->nqueries = 0; dns_name_init(&fctx->nsname, NULL); fctx->nsfetch = NULL; @@ -3102,7 +3114,7 @@ maybe_destroy(fetchctx_t *fctx) { REQUIRE(SHUTTINGDOWN(fctx)); - if (fctx->pending != 0) + if (fctx->pending != 0 || fctx->nqueries != 0) return; for (validator = ISC_LIST_HEAD(fctx->validators); @@ -6395,7 +6407,8 @@ dns_resolver_destroyfetch(dns_fetch_t **fetchp) { /* * No one cares about the result of this fetch anymore. */ - if (fctx->pending == 0 && ISC_LIST_EMPTY(fctx->validators) && + if (fctx->pending == 0 && fctx->nqueries == 0 && + ISC_LIST_EMPTY(fctx->validators) && SHUTTINGDOWN(fctx)) { /* * This fctx is already shutdown; we were just