]> 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:07 +0000 (21:46 +0000)
committerEvan Hunt <each@isc.org>
Tue, 15 Nov 2011 21:46:07 +0000 (21:46 +0000)
CHANGES
lib/dns/resolver.c

diff --git a/CHANGES b/CHANGES
index 8717ff1ff9f74fad1e24b56105b33ab93934c8fc..a7a2f873b36a5874acc51221817e8045e1492aaa 100644 (file)
--- 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]
index 71240890de44417ac069fe0212498f7c9a71842a..80713925accbcf7e2a6c61fbac1374d66f96307c 100644 (file)
@@ -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: