From: W.C.A. Wijngaards Date: Fri, 15 May 2026 14:00:58 +0000 (+0200) Subject: - Fix for allocation-failure hardening of rrset cache wildcard X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=53c261cb337073aebd3cf1dae4341ed3e44bd2bb;p=thirdparty%2Funbound.git - 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. --- diff --git a/doc/Changelog b/doc/Changelog index 383268ee6..8743f3452 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -10,6 +10,10 @@ 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. diff --git a/services/cache/rrset.c b/services/cache/rrset.c index c1716a565..402864a31 100644 --- a/services/cache/rrset.c +++ b/services/cache/rrset.c @@ -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; diff --git a/validator/val_sigcrypt.c b/validator/val_sigcrypt.c index 9f27f9cc9..83c11858c 100644 --- a/validator/val_sigcrypt.c +++ b/validator/val_sigcrypt.c @@ -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; }