]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix RPZ locks. Do not unlock zones lock if requested and rpz find
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 25 Aug 2021 12:18:29 +0000 (14:18 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 25 Aug 2021 12:18:29 +0000 (14:18 +0200)
  zone does not find the zone. Readlock the clientip that is found
  for ipbased triggers. Unlock the nsdname zone lock when done.
  Unlock zone and ip in rpz nsip and nsdname callback. Unlock
  authzone and localzone if clientip found in rpz worker call.

doc/Changelog
services/rpz.c

index ed7da6ace17da125e5101c39e820f017d1a5f6f7..4a476a853a6453877d77ee4a57d5ff60f689aa88 100644 (file)
@@ -7,6 +7,11 @@
          to insert into RPZ.
        - Fix the stream wait stream_wait_count_lock and http2 buffer locks
          setup and desetup from race condition.
+       - Fix RPZ locks. Do not unlock zones lock if requested and rpz find
+         zone does not find the zone. Readlock the clientip that is found
+         for ipbased triggers. Unlock the nsdname zone lock when done.
+         Unlock zone and ip in rpz nsip and nsdname callback. Unlock
+         authzone and localzone if clientip found in rpz worker call.
 
 20 August 2021: Wouter
        - Fix #529: Fix: log_assert does nothing if UNBOUND_DEBUG is
index 085353b3fdcfbe1530e219075099028ad8d184a2..57b22d312445d5ac916117801c9e5e3a2c9a6565 100644 (file)
@@ -1121,7 +1121,9 @@ rpz_find_zone(struct local_zones* zones, uint8_t* qname, size_t qname_len, uint1
                dname_count_labels(qname),
                LDNS_RR_CLASS_IN, &exact);
        if(!z || (only_exact && !exact)) {
-               lock_rw_unlock(&zones->lock);
+               if(!zones_keep_lock) {
+                       lock_rw_unlock(&zones->lock);
+               }
                return NULL;
        }
        if(wr) {
@@ -1420,6 +1422,7 @@ rpz_ipbased_trigger_lookup(struct clientip_synthesized_rrset* set,
        raddr = (struct clientip_synthesized_rr*)addr_tree_lookup(&set->entries,
                        addr, addrlen);
        if(raddr != NULL) {
+               lock_rw_rdlock(&raddr->lock);
                action = raddr->action;
                if(verbosity >= VERB_ALGO) {
                        char ip[256], net[256];
@@ -1429,7 +1432,6 @@ rpz_ipbased_trigger_lookup(struct clientip_synthesized_rrset* set,
                        verbose(VERB_ALGO, "rpz: trigger %s %s/%d on %s action=%s",
                                triggername, net, raddr->node.net, ip, rpz_action_to_string(action));
                }
-               lock_rw_unlock(&raddr->lock);
        }
        lock_rw_unlock(&set->lock);
 
@@ -2056,6 +2058,7 @@ rpz_apply_nsdname_trigger(struct module_qstate* ms, struct rpz* r,
                        action, &ms->qinfo, NULL, ms, r->log_name);
        if(ms->env->worker)
                ms->env->worker->stats.rpz_action[action]++;
+       lock_rw_unlock(&z->lock);
        return ret;
 }
 
@@ -2148,9 +2151,17 @@ rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate*
        lock_rw_unlock(&az->rpz_lock);
 
        if(raddr == NULL && z == NULL) { return NULL; }
-       else if(raddr != NULL) { return rpz_apply_nsip_trigger(ms, r, raddr, a); }
-       else if(z != NULL) { return rpz_apply_nsdname_trigger(ms, r, z, &match, a); }
-       else { return NULL; }
+       else if(raddr != NULL) {
+               if(z) {
+                       lock_rw_unlock(&z->lock);
+               }
+               return rpz_apply_nsip_trigger(ms, r, raddr, a);
+       } else if(z != NULL) {
+               if(raddr) {
+                       lock_rw_unlock(&raddr->lock);
+               }
+               return rpz_apply_nsdname_trigger(ms, r, z, &match, a);
+       } else { return NULL; }
 }
 
 struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
@@ -2313,9 +2324,20 @@ rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env,
 
        int clientip_trigger = rpz_apply_maybe_clientip_trigger(az, env, qinfo,
                edns, repinfo, taglist, taglen, stats, buf, temp, &z, &a, &r);
-       if(clientip_trigger >= 0) { return clientip_trigger; }
+       if(clientip_trigger >= 0) {
+               if(a) {
+                       lock_rw_unlock(&a->lock);
+               }
+               if(z) {
+                       lock_rw_unlock(&z->lock);
+               }
+               return clientip_trigger;
+       }
 
        if(z == NULL) {
+               if(a) {
+                       lock_rw_unlock(&a->lock);
+               }
                return 0;
        }