From: W.C.A. Wijngaards Date: Fri, 17 Jul 2020 15:15:55 +0000 (+0200) Subject: - Fix lock dependency cycle in rpz zone config setup. X-Git-Tag: release-1.11.0~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b7b5952c3aaa22c89e69c8ef994cab1e0dc0076a;p=thirdparty%2Funbound.git - Fix lock dependency cycle in rpz zone config setup. --- diff --git a/doc/Changelog b/doc/Changelog index a551a59d4..8d820ca92 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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 diff --git a/services/authzone.c b/services/authzone.c index 9b0568c8c..a26d1003a 100644 --- a/services/authzone.c +++ b/services/authzone.c @@ -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); }