]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix CVE-2026-42955, Extra fix for CVE-2026-40622 to also clamp
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 22 Jul 2026 08:11:04 +0000 (10:11 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 22 Jul 2026 08:11:04 +0000 (10:11 +0200)
  the TTL of A/AAAA records disallowing a one-time 'ghost domain'
  delegation renewal via glue records. Thanks to Qifan Zhang, Palo
  Alto Networks, for the report.

services/cache/rrset.c
testdata/iter_prefetch_fail.rpl

index ab4f4c8e0afc547d0fadb9bd6862124ea96f963e..a5d320a3058703e21188bfca0b1d0c08d1b4de0e 100644 (file)
@@ -126,7 +126,8 @@ rrset_cache_touch(struct rrset_cache* r, struct ub_packed_rrset_key* key,
 
 /** see if rrset needs to be updated in the cache */
 static int
-need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
+need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns,
+       int a_aaaa)
 {
        struct packed_rrset_data* newd = (struct packed_rrset_data*)nd;
        struct packed_rrset_data* cached = (struct packed_rrset_data*)cd;
@@ -151,9 +152,13 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
                        return 0;
                /* ghost-domain: never let an NS overwrite extend lifetime
                 * past the entry it replaces, regardless of trust. */
-               if(ns && !TTL_IS_EXPIRED(cached->ttl, timenow) &&
+               /* Also for A/AAAA and it is glue. */
+               if((ns ||
+                       (a_aaaa && cached->trust==rrset_trust_add_noAA))
+                       && !TTL_IS_EXPIRED(cached->ttl, timenow) &&
                        newd->ttl > cached->ttl) {
                        size_t i;
+                       if(a_aaaa) newd->trust=rrset_trust_add_noAA;
                        newd->ttl = cached->ttl;
                        for(i=0; i<(newd->count+newd->rrsig_count); i++)
                                if(newd->rr_ttl[i] > newd->ttl)
@@ -223,7 +228,8 @@ rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
                equal = rrsetdata_equal((struct packed_rrset_data*)k->entry.
                        data, (struct packed_rrset_data*)e->data);
                if(!need_to_update_rrset(k->entry.data, e->data, timenow,
-                       equal, (rrset_type==LDNS_RR_TYPE_NS))) {
+                       equal, (rrset_type==LDNS_RR_TYPE_NS),
+                       (rrset_type==LDNS_RR_TYPE_A || rrset_type==LDNS_RR_TYPE_AAAA))) {
                        /* cache is superior, return that value */
                        lock_rw_unlock(&e->lock);
                        ub_packed_rrset_parsedelete(k, alloc);
index d1e308305b8b1a8ac0ef0f946441d07a479aea5f..aa94d0fe5826fd9147f13b34ecb066a293147fdc 100644 (file)
@@ -319,7 +319,7 @@ example.com.        360 IN NS       ns.example.com.
 SECTION ADDITIONAL
 ; this is picked up from the parent (because this simulation has the
 ; parent respond with servfail, not actually timeout)
-ns.example.com.        3600    IN      A       1.2.3.4
+ns.example.com.        360     IN      A       1.2.3.4
 ENTRY_END
 
 ; another query to see if there is another lookup towards the authority
@@ -342,7 +342,7 @@ www.example.com. 360 IN A   10.20.30.40
 SECTION AUTHORITY
 example.com.   360 IN NS       ns.example.com.
 SECTION ADDITIONAL
-ns.example.com.        3600    IN      A       1.2.3.4
+ns.example.com.        360     IN      A       1.2.3.4
 ENTRY_END
 
 ; some time later another query, and now it is fine to bother the authority
@@ -367,7 +367,7 @@ www.example.com. 330 IN A   10.20.30.40
 SECTION AUTHORITY
 example.com.   330 IN NS       ns.example.com.
 SECTION ADDITIONAL
-ns.example.com.        3570    IN      A       1.2.3.4
+ns.example.com.        330     IN      A       1.2.3.4
 ENTRY_END
 ; now the just-looked-up entry
 STEP 190 QUERY
@@ -388,7 +388,7 @@ www.example.com. 3600 IN A  10.20.30.40
 SECTION AUTHORITY
 example.com.   3600 IN NS      ns.example.com.
 SECTION ADDITIONAL
-ns.example.com.        3570    IN      A       1.2.3.4
+ns.example.com.        3600    IN      A       1.2.3.4
 ENTRY_END