From: Evan Hunt Date: Tue, 15 Nov 2011 21:46:07 +0000 (+0000) Subject: 3216. [bug] resolver.c:validated() was not thread-safe. [RT #26478] X-Git-Tag: v9.7.5b1~43 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=fcd518304ae74df66c181a77486ee970d6a8d2e9;p=thirdparty%2Fbind9.git 3216. [bug] resolver.c:validated() was not thread-safe. [RT #26478] --- diff --git a/CHANGES b/CHANGES index 8717ff1ff9f..a7a2f873b36 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +3216. [bug] resolver.c:validated() was not thread-safe. [RT #26478] + --- 9.7.5b1 released --- 3213. [doc] Clarify ixfr-from-differences behavior. [RT #25188] diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 71240890de4..80713925acc 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.413.14.21 2011/11/02 23:46:17 marka Exp $ */ +/* $Id: resolver.c,v 1.413.14.22 2011/11/15 21:46:07 each Exp $ */ /*! \file */ @@ -444,7 +444,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 void maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked); static void add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason, badnstype_t badtype); @@ -738,7 +738,7 @@ resquery_destroy(resquery_t **queryp) { query->fctx->nqueries--; if (SHUTTINGDOWN(query->fctx)) - maybe_destroy(query->fctx); /* Locks bucket. */ + maybe_destroy(query->fctx, ISC_FALSE); /* Locks bucket. */ query->magic = 0; isc_mem_put(query->mctx, query, sizeof(*query)); *queryp = NULL; @@ -3975,7 +3975,7 @@ clone_results(fetchctx_t *fctx) { * '*fctx' is shutting down. */ static void -maybe_destroy(fetchctx_t *fctx) { +maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) { unsigned int bucketnum; isc_boolean_t bucket_empty = ISC_FALSE; dns_resolver_t *res = fctx->res; @@ -3993,10 +3993,12 @@ maybe_destroy(fetchctx_t *fctx) { } bucketnum = fctx->bucketnum; - LOCK(&res->buckets[bucketnum].lock); + if (!locked) + LOCK(&res->buckets[bucketnum].lock); if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators)) bucket_empty = fctx_destroy(fctx); - UNLOCK(&res->buckets[bucketnum].lock); + if (!locked) + UNLOCK(&res->buckets[bucketnum].lock); if (bucket_empty) empty_bucket(res); @@ -4041,6 +4043,8 @@ validated(isc_task_t *task, isc_event_t *event) { FCTXTRACE("received validation completion event"); + LOCK(&fctx->res->buckets[fctx->bucketnum].lock); + ISC_LIST_UNLINK(fctx->validators, vevent->validator, link); fctx->validator = NULL; @@ -4062,12 +4066,11 @@ validated(isc_task_t *task, isc_event_t *event) { * so, destroy the fctx. */ if (SHUTTINGDOWN(fctx) && !sentresponse) { - maybe_destroy(fctx); /* Locks bucket. */ + maybe_destroy(fctx, ISC_TRUE); + UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); goto cleanup_event; } - LOCK(&fctx->res->buckets[fctx->bucketnum].lock); - isc_stdtime_get(&now); /* @@ -4280,7 +4283,7 @@ validated(isc_task_t *task, isc_event_t *event) { dns_db_detachnode(fctx->cache, &node); UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); if (SHUTTINGDOWN(fctx)) - maybe_destroy(fctx); /* Locks bucket. */ + maybe_destroy(fctx, ISC_FALSE); /* Locks bucket. */ goto cleanup_event; } @@ -4371,7 +4374,6 @@ validated(isc_task_t *task, isc_event_t *event) { dns_db_detachnode(fctx->cache, &node); UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); - fctx_done(fctx, result, __LINE__); /* Locks bucket. */ cleanup_event: