]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
make resolver->zspill atomic to prevent potential deadlock
authorMark Andrews <marka@isc.org>
Wed, 11 Dec 2019 23:33:23 +0000 (10:33 +1100)
committerMark Andrews <marka@isc.org>
Thu, 12 Dec 2019 08:26:59 +0000 (08:26 +0000)
lib/dns/resolver.c

index d901465848c8a5e61288e06ba9e52f02096400fe..6fce5cd6c9b0eeb377da422736598dc6c458d134 100644 (file)
@@ -512,18 +512,19 @@ struct dns_resolver {
        unsigned int                    spillatmax;
        unsigned int                    spillatmin;
        isc_timer_t *                   spillattimer;
-       bool                    zero_no_soa_ttl;
+       bool                            zero_no_soa_ttl;
        unsigned int                    query_timeout;
        unsigned int                    maxdepth;
        unsigned int                    maxqueries;
        isc_result_t                    quotaresp[2];
 
        /* Additions for serve-stale feature. */
-       unsigned int                    retryinterval; /* in milliseconds */
+       unsigned int                    retryinterval;  /* in milliseconds */
        unsigned int                    nonbackofftries;
 
        /* Atomic */
        isc_refcount_t                  references;
+       atomic_uint_fast32_t            zspill;         /* fetches-per-zone */
        atomic_bool                     exiting;
 
        /* Locked by lock. */
@@ -531,9 +532,8 @@ struct dns_resolver {
        unsigned int                    activebuckets;
        bool                            priming;
        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;
@@ -1512,7 +1512,7 @@ fcount_incr(fetchctx_t *fctx, bool force) {
        isc_result_t result = ISC_R_SUCCESS;
        zonebucket_t *dbucket;
        fctxcount_t *counter;
-       unsigned int bucketnum, spill;
+       unsigned int bucketnum;
 
        REQUIRE(fctx != NULL);
        REQUIRE(fctx->res != NULL);
@@ -1521,10 +1521,6 @@ fcount_incr(fetchctx_t *fctx, bool force) {
        bucketnum = dns_name_fullhash(&fctx->domain, false)
                        % RES_DOMAIN_BUCKETS;
 
-       LOCK(&fctx->res->lock);
-       spill = fctx->res->zspill;
-       UNLOCK(&fctx->res->lock);
-
        dbucket = &fctx->res->dbuckets[bucketnum];
 
        LOCK(&dbucket->lock);
@@ -1549,6 +1545,7 @@ fcount_incr(fetchctx_t *fctx, bool force) {
                        ISC_LIST_APPEND(dbucket->list, counter, link);
                }
        } else {
+               uint_fast32_t spill = atomic_load_acquire(&fctx->res->zspill);
                if (!force && spill != 0 && counter->count >= spill) {
                        counter->dropped++;
                        fcount_logspill(fctx, counter);
@@ -9969,7 +9966,7 @@ dns_resolver_create(dns_view_t *view,
        res->spillatmin = res->spillat = 10;
        res->spillatmax = 100;
        res->spillattimer = NULL;
-       res->zspill = 0;
+       atomic_init(&res->zspill, 0);
        res->zero_no_soa_ttl = false;
        res->retryinterval = 30000;
        res->nonbackofftries = 3;
@@ -11249,9 +11246,7 @@ dns_resolver_setfetchesperzone(dns_resolver_t *resolver, uint32_t clients)
 {
        REQUIRE(VALID_RESOLVER(resolver));
 
-       LOCK(&resolver->lock);
-       resolver->zspill = clients;
-       UNLOCK(&resolver->lock);
+       atomic_store_release(&resolver->zspill, clients);
 }