From: Evan Hunt Date: Tue, 15 Nov 2011 21:46:42 +0000 (+0000) Subject: 3216. [bug] resolver.c:validated() was not thread-safe. [RT #26478] X-Git-Tag: v9.6-ESV-R6b1~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=118da7753963b44686af0b873d16b54d370d6469;p=thirdparty%2Fbind9.git 3216. [bug] resolver.c:validated() was not thread-safe. [RT #26478] --- diff --git a/CHANGES b/CHANGES index 188920a77f4..3a2a96affaa 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +3216. [bug] resolver.c:validated() was not thread-safe. [RT #26478] + --- 9.6-ESV-R6b1 released --- 3213. [doc] Clarify ixfr-from-differences behavior. [RT #25188] diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 46f2503ebd6..c41a444ad4f 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.384.14.35 2011/11/02 23:48:41 marka Exp $ */ +/* $Id: resolver.c,v 1.384.14.36 2011/11/15 21:46:42 each Exp $ */ /*! \file */ @@ -443,7 +443,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); @@ -737,7 +737,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; @@ -3912,7 +3912,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; @@ -3930,10 +3930,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); @@ -3977,6 +3979,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; @@ -3998,12 +4002,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); /* @@ -4216,7 +4219,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; } @@ -4307,7 +4310,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: