]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3216. [bug] resolver.c:validated() was not thread-safe. [RT #26478]
authorEvan Hunt <each@isc.org>
Tue, 15 Nov 2011 21:46:42 +0000 (21:46 +0000)
committerEvan Hunt <each@isc.org>
Tue, 15 Nov 2011 21:46:42 +0000 (21:46 +0000)
CHANGES
lib/dns/resolver.c

diff --git a/CHANGES b/CHANGES
index 188920a77f45c47d5dde9f85a59fb563c6f8e1a4..3a2a96affaaeb51dee5b6199682705a58ae2ff76 100644 (file)
--- 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]
index 46f2503ebd665e83e60988765ea265eeb6b70756..c41a444ad4f4c4c46e303201abbdd72d264c90dc 100644 (file)
@@ -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: