]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix CVE-2026-55717, 'serve-expired-client-timeout' and 'response-ip'
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 22 Jul 2026 08:17:32 +0000 (10:17 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 22 Jul 2026 08:17:32 +0000 (10:17 +0200)
  CNAME redirect could lead to a crash. Thanks to Qifan Zhang, Palo
  Alto Networks, for the report. In addition, thanks to Xin Wang,
  Jiapeng Li, and Jiajia Liu, Northwestern Polytechnical University,
  for also reporting this issue.

services/localzone.h
services/mesh.c
util/data/packed_rrset.c

index 76c011836030afbb6bc5b4773a588970ae56987f..e3fb0afe3e4a247abfd952d62ac77608d14e74c6 100644 (file)
@@ -573,7 +573,7 @@ enum respip_action {
        respip_always_nxdomain = local_zone_always_nxdomain,
         /** answer with nodata response */
        respip_always_nodata = local_zone_always_nodata,
-        /** answer with nodata response */
+        /** drop query */
        respip_always_deny = local_zone_always_deny,
        /** RPZ: truncate answer in order to force switch to tcp */
        respip_truncate = local_zone_truncate,
index cd78d1c2913bdcd67214914e679a1287e6c0e33b..8ce3dcee73a83dd41bb183102e2835e54cfab1cf 100644 (file)
@@ -2454,9 +2454,10 @@ apply_respip_action(struct module_qstate* qstate,
 
        /* xxx_deny actions mean dropping the reply, unless the original reply
         * was redirected to response-ip data. */
-       if((actinfo->action == respip_deny ||
+       if(actinfo->action == respip_always_deny ||
+               ((actinfo->action == respip_deny ||
                actinfo->action == respip_inform_deny) &&
-               *encode_repp == rep)
+               *encode_repp == rep))
                *encode_repp = NULL;
 
        return 1;
@@ -2521,12 +2522,15 @@ mesh_serve_expired_callback(void* arg)
                        qstate->client_info, &actinfo, msg->rep, &alias_rrset, &encode_rep,
                        qstate->env->auth_zones)) {
                        return;
-               } else if(partial_rep &&
-                       !respip_merge_cname(partial_rep, &qstate->qinfo, msg->rep,
+               } else if(partial_rep) {
+                       if(!respip_merge_cname(partial_rep, &qstate->qinfo, msg->rep,
                        qstate->client_info, must_validate, &encode_rep, qstate->region,
                        qstate->env->auth_zones, qstate->env->views,
                        qstate->env->respip_set)) {
-                       return;
+                               return;
+                       }
+                       /* merge succeeded; final reply, no further alias pass */
+                       partial_rep = NULL;
                }
                if(!encode_rep || alias_rrset) {
                        if(!encode_rep) {
@@ -2537,6 +2541,7 @@ mesh_serve_expired_callback(void* arg)
                                partial_rep = encode_rep;
                        }
                }
+               msg->rep = encode_rep;
                /* We've found a partial reply ending with an
                * alias.  Replace the lookup qinfo for the
                * alias target and lookup the cache again to
index 89ece3c031f565c4e4c666d2c79afd06c7603bc1..b695c1b7162d62109d9dda60da6994c93c96ab90 100644 (file)
@@ -198,6 +198,7 @@ get_cname_target(struct ub_packed_rrset_key* rrset, uint8_t** dname,
 {
        struct packed_rrset_data* d;
        size_t len;
+       if(!rrset) return;
        if(ntohs(rrset->rk.type) != LDNS_RR_TYPE_CNAME && 
                ntohs(rrset->rk.type) != LDNS_RR_TYPE_DNAME)
                return;