]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix for allocation-failure hardening of rrset cache wildcard
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 15 May 2026 14:00:58 +0000 (16:00 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 15 May 2026 14:00:58 +0000 (16:00 +0200)
  storage and canonical NSEC owner replacement. Thanks to Xin
  Wang and Jiajia Liu, Northwestern Polytechnical University,
  for the report.

doc/Changelog
services/cache/rrset.c
validator/val_sigcrypt.c

index 383268ee6ead5bbb9f388805e72a1f1b50de191b..8743f3452b8b0d83f6622bb717d9103976c596f5 100644 (file)
          and Jiajia Liu, Northwestern Polytechnical University, for
          the report. In addition, thanks to Qifan Zhang, Palo Alto
          Networks, for reporting it.
+       - Fix for allocation-failure hardening of rrset cache wildcard
+         storage and canonical NSEC owner replacement. Thanks to Xin
+         Wang and Jiajia Liu, Northwestern Polytechnical University,
+         for the report.
 
 11 May 2026: Yorgos
        - Fix comment and verbose logging for EDNS fallback buffer size.
index c1716a565783576809402f56eef592b237da7ede..402864a31388cc3630545b5830addb08368f0b8e 100644 (file)
@@ -251,6 +251,8 @@ void rrset_cache_update_wildcard(struct rrset_cache* rrset_cache,
 {
        struct rrset_ref ref;
        uint8_t wc_dname[LDNS_MAX_DOMAINLEN+3];
+       uint8_t* new_dname;
+       size_t new_dname_len;
        rrset = packed_rrset_copy_alloc(rrset, alloc, timenow);
        if(!rrset) {
                log_err("malloc failure in rrset_cache_update_wildcard");
@@ -262,14 +264,16 @@ void rrset_cache_update_wildcard(struct rrset_cache* rrset_cache,
        wc_dname[1] = (uint8_t)'*';
        memmove(wc_dname+2, ce, ce_len);
 
-       free(rrset->rk.dname);
-       rrset->rk.dname_len = ce_len + 2;
-       rrset->rk.dname = (uint8_t*)memdup(wc_dname, rrset->rk.dname_len);
-       if(!rrset->rk.dname) {
-               alloc_special_release(alloc, rrset);
+       new_dname_len = ce_len + 2;
+       new_dname = (uint8_t*)memdup(wc_dname, new_dname_len);
+       if(!new_dname) {
+               ub_packed_rrset_parsedelete(rrset, alloc);
                log_err("memdup failure in rrset_cache_update_wildcard");
                return;
        }
+       free(rrset->rk.dname);
+       rrset->rk.dname = new_dname;
+       rrset->rk.dname_len = new_dname_len;
 
        rrset->entry.hash = rrset_key_hash(&rrset->rk);
        ref.key = rrset;
index 9f27f9cc9bb7338d4d97140a605e8cf3132aff82..83c11858c2780ab1596936b19af9fb5ccd538c49 100644 (file)
@@ -1322,10 +1322,11 @@ rrset_canonical(struct regional* region, sldns_buffer* buf,
         * the non-existence proves. */
        if(ntohs(k->rk.type) == LDNS_RR_TYPE_NSEC &&
                section == LDNS_SECTION_AUTHORITY && qstate) {
-               k->rk.dname = regional_alloc_init(qstate->region, can_owner,
+               uint8_t* new_dname = regional_alloc_init(qstate->region, can_owner,
                        can_owner_len);
-               if(!k->rk.dname)
+               if(!new_dname)
                        return 0;
+               k->rk.dname = new_dname;
                k->rk.dname_len = can_owner_len;
        }