]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix lock dependency cycle in rpz zone config setup.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 17 Jul 2020 15:15:55 +0000 (17:15 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 17 Jul 2020 15:15:55 +0000 (17:15 +0200)
doc/Changelog
services/authzone.c

index a551a59d4f037fc6d7ae7016ce837d2297f7779f..8d820ca924296ef42354e72c66c7e0bf8501745e 100644 (file)
@@ -1,6 +1,7 @@
 17 July 2020: Wouter
        - Fix libnettle compile for session ticket key callback function
          changes.
+       - Fix lock dependency cycle in rpz zone config setup.
 
 17 July 2020: Ralph
        - Merge PR #234 - Ensure proper alignment of cmsg buffers by Jérémie
index 9b0568c8c8291f5664d64f11da86157a37b37d52..a26d1003abe2b5974543dc36cd154e1dd7d6ccf3 100644 (file)
@@ -1866,15 +1866,26 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
        struct auth_xfer* x = NULL;
 
        /* create zone */
+       if(c->isrpz) {
+               /* if the rpz lock is needed, grab it before the other
+                * locks to avoid a lock dependency cycle */
+               lock_rw_wrlock(&az->rpz_lock);
+       }
        lock_rw_wrlock(&az->lock);
        if(!(z=auth_zones_find_or_add_zone(az, c->name))) {
                lock_rw_unlock(&az->lock);
+               if(c->isrpz) {
+                       lock_rw_unlock(&az->rpz_lock);
+               }
                return 0;
        }
        if(c->masters || c->urls) {
                if(!(x=auth_zones_find_or_add_xfer(az, z))) {
                        lock_rw_unlock(&az->lock);
                        lock_rw_unlock(&z->lock);
+                       if(c->isrpz) {
+                               lock_rw_unlock(&az->rpz_lock);
+                       }
                        return 0;
                }
        }
@@ -1889,6 +1900,9 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
                        lock_basic_unlock(&x->lock);
                }
                lock_rw_unlock(&z->lock);
+               if(c->isrpz) {
+                       lock_rw_unlock(&az->rpz_lock);
+               }
                return 0;
        }
        z->for_downstream = c->for_downstream;
@@ -1900,11 +1914,13 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
                        return 0;
                }
                lock_protect(&z->lock, &z->rpz->local_zones, sizeof(*z->rpz));
-               lock_rw_wrlock(&az->rpz_lock);
+               /* the az->rpz_lock is locked above */
                z->rpz_az_next = az->rpz_first;
                if(az->rpz_first)
                        az->rpz_first->rpz_az_prev = z;
                az->rpz_first = z;
+       }
+       if(c->isrpz) {
                lock_rw_unlock(&az->rpz_lock);
        }