]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Restore locking in dns_resolver_shutdown and dns_resolver_attach
authorOndřej Surý <ondrej@sury.org>
Fri, 19 Jul 2019 10:54:23 +0000 (12:54 +0200)
committerOndřej Surý <ondrej@sury.org>
Mon, 22 Jul 2019 12:17:36 +0000 (08:17 -0400)
Although the struct dns_resolver.exiting member is protected by stdatomics, we
actually need to wait for whole dns_resolver_shutdown() to finish before
destroying the resolver object.  Otherwise, there would be a data race and some
fctx objects might not be destroyed yet at the time we tear down the
dns_resolver object.

lib/dns/resolver.c

index 878b959f8054e3a13588bbc4628db20c0a80f909..5ef6f65bc28eca1dc054c7f07c6c46d3de5cc87a 100644 (file)
@@ -476,15 +476,15 @@ struct dns_resolver {
        isc_timermgr_t *                timermgr;
        isc_taskmgr_t *                 taskmgr;
        dns_view_t *                    view;
-       bool                    frozen;
+       bool                            frozen;
        unsigned int                    options;
        dns_dispatchmgr_t *             dispatchmgr;
        dns_dispatchset_t *             dispatches4;
-       bool                    exclusivev4;
+       bool                            exclusivev4;
        dns_dispatchset_t *             dispatches6;
        isc_dscp_t                      querydscp4;
        isc_dscp_t                      querydscp6;
-       bool                    exclusivev6;
+       bool                            exclusivev6;
        unsigned int                    nbuckets;
        fctxbucket_t *                  buckets;
        zonebucket_t *                  dbuckets;
@@ -524,7 +524,7 @@ struct dns_resolver {
        unsigned int                    spillat;        /* clients-per-query */
        unsigned int                    zspill;         /* fetches-per-zone */
 
-       dns_badcache_t  *               badcache;        /* Bad cache. */
+       dns_badcache_t  *               badcache;        /* Bad cache. */
 
        /* Locked by primelock. */
        dns_fetch_t *                   primefetch;
@@ -10326,6 +10326,7 @@ dns_resolver_shutdown(dns_resolver_t *res) {
 
        RTRACE("shutdown");
 
+       LOCK(&res->lock);
        if (atomic_compare_exchange_strong(&res->exiting, &is_false, true)) {
                RTRACE("exiting");
 
@@ -10357,6 +10358,7 @@ dns_resolver_shutdown(dns_resolver_t *res) {
                                         NULL, true);
                RUNTIME_CHECK(result == ISC_R_SUCCESS);
        }
+       UNLOCK(&res->lock);
 }
 
 void
@@ -10372,8 +10374,10 @@ dns_resolver_detach(dns_resolver_t **resp) {
        *resp = NULL;
 
        if (isc_refcount_decrement(&res->references) == 1) {
+               LOCK(&res->lock);
                INSIST(atomic_load_acquire(&res->exiting));
                INSIST(res->activebuckets == 0);
+               UNLOCK(&res->lock);
                destroy(res);
        }
 }