2124. [bug] It was possible to dereference a freed fetch

context. [RT #16584]
This commit is contained in:
Mark Andrews
2007-01-04 05:44:20 +00:00
parent 9f59aa57cb
commit 774e2ffe70
2 changed files with 22 additions and 6 deletions
+2
View File
@@ -1,3 +1,5 @@
2124. [bug] It was possible to dereference a freed fetch
context. [RT #16584]
--- 9.3.2-WFB-4 released ---
+20 -6
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: resolver.c,v 1.218.2.18.4.56.2.2 2006/08/03 23:07:37 marka Exp $ */
/* $Id: resolver.c,v 1.218.2.18.4.56.2.3 2007/01/04 05:44:20 marka Exp $ */
#include <config.h>
@@ -215,6 +215,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', '!', '!', '!')
@@ -348,6 +353,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,
@@ -513,6 +519,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;
@@ -1084,6 +1093,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
}
ISC_LIST_APPEND(fctx->queries, query, link);
query->fctx->nqueries++;
return (ISC_R_SUCCESS);
@@ -1530,7 +1540,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);
/*
@@ -2384,8 +2394,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");
@@ -2559,7 +2569,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);
@@ -2600,6 +2610,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) {
/*
@@ -2761,6 +2772,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;
@@ -3086,7 +3098,8 @@ maybe_destroy(fetchctx_t *fctx) {
REQUIRE(SHUTTINGDOWN(fctx));
if (fctx->pending != 0 || !ISC_LIST_EMPTY(fctx->validators))
if (fctx->pending != 0 || fctx->nqueries != 0 ||
!ISC_LIST_EMPTY(fctx->validators))
return;
bucketnum = fctx->bucketnum;
@@ -6346,7 +6359,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