diff --git a/SPECS/bind/CVE-2026-1519.patch b/SPECS/bind/CVE-2026-1519.patch new file mode 100644 index 00000000000..f92e322578e --- /dev/null +++ b/SPECS/bind/CVE-2026-1519.patch @@ -0,0 +1,279 @@ +From cc92db37659144dccc482cb88533a741929712a7 Mon Sep 17 00:00:00 2001 +From: Matthijs Mekking +Date: Tue, 3 Mar 2026 10:40:36 +0100 +Subject: [PATCH 1/3] Check iterations in isdelegation() + +When looking up an NSEC3 as part of an insecurity proof, check the +number of iterations. If this is too high, treat the answer as insecure +by marking the answer with trust level "answer", indicating that they +did not validate, but could be cached as insecure. + +(cherry picked from commit 988040a5e02f86f4a8cdb0704e8d501f9082a89c) + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/94ece263832ebd4777d4a227e3752c92305c109e.patch + +--- + lib/dns/validator.c | 65 ++++++++++++++++++++++++++++++++++----------- + 1 file changed, 49 insertions(+), 16 deletions(-) + +diff --git a/lib/dns/validator.c b/lib/dns/validator.c +index 4e856e5..082db33 100644 +--- a/lib/dns/validator.c ++++ b/lib/dns/validator.c +@@ -251,12 +251,25 @@ exit_check(dns_validator_t *val) { + } + + /*% +- * Look in the NSEC record returned from a DS query to see if there is +- * a NS RRset at this name. If it is found we are at a delegation point. ++ * The isdelegation() function is called as part of seeking the DS record. ++ * Look in the NSEC or NSEC3 record returned from a DS query to see if the ++ * record has the NS bitmap set. If so, we are at a delegation point. ++ * ++ * If the response contains NSEC3 records with too high iterations, we cannot ++ * (or rather we are not going to) validate the insecurity proof. Instead we ++ * are going to treat the message as insecure and just assume the DS was at ++ * the delegation. ++ * ++ * Returns: ++ *\li #ISC_R_SUCCESS the NS bitmap was set in the NSEC or NSEC3 record, or ++ * the NSEC3 covers the name (in case of opt-out), or ++ * we cannot validate the insecurity proof and are going ++ * to treat the message as isnecure. ++ *\li #ISC_R_NOTFOUND the NS bitmap was not set, + */ +-static bool +-isdelegation(dns_name_t *name, dns_rdataset_t *rdataset, +- isc_result_t dbresult) { ++static isc_result_t ++isdelegation(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset, ++ isc_result_t dbresult, const char *caller) { + dns_fixedname_t fixed; + dns_label_t hashlabel; + dns_name_t nsec3name; +@@ -284,7 +297,7 @@ isdelegation(dns_name_t *name, dns_rdataset_t *rdataset, + goto trynsec3; + } + if (result != ISC_R_SUCCESS) { +- return (false); ++ return (ISC_R_NOTFOUND); + } + } + +@@ -298,7 +311,7 @@ isdelegation(dns_name_t *name, dns_rdataset_t *rdataset, + dns_rdata_reset(&rdata); + } + dns_rdataset_disassociate(&set); +- return (found); ++ return (found ? ISC_R_SUCCESS : ISC_R_NOTFOUND); + + trynsec3: + /* +@@ -334,6 +347,18 @@ trynsec3: + if (nsec3.hash != 1) { + continue; + } ++ /* ++ * If there are too many iterations assume bad things ++ * are happening and bail out early. Treat as if the ++ * DS was at the delegation. ++ */ ++ if (nsec3.iterations > DNS_NSEC3_MAXITERATIONS) { ++ validator_log(val, ISC_LOG_DEBUG(3), ++ "%s: too many iterations", ++ caller); ++ dns_rdataset_disassociate(&set); ++ return (ISC_R_SUCCESS); ++ } + length = isc_iterated_hash( + hash, nsec3.hash, nsec3.iterations, nsec3.salt, + nsec3.salt_length, name->ndata, name->length); +@@ -345,7 +370,7 @@ trynsec3: + found = dns_nsec3_typepresent(&rdata, + dns_rdatatype_ns); + dns_rdataset_disassociate(&set); +- return (found); ++ return (found ? ISC_R_SUCCESS : ISC_R_NOTFOUND); + } + if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) == 0) { + continue; +@@ -361,12 +386,12 @@ trynsec3: + memcmp(hash, nsec3.next, length) < 0))) + { + dns_rdataset_disassociate(&set); +- return (true); ++ return (ISC_R_SUCCESS); + } + } + dns_rdataset_disassociate(&set); + } +- return (found); ++ return (found ? ISC_R_SUCCESS : ISC_R_NOTFOUND); + } + + /*% +@@ -582,8 +607,10 @@ fetch_callback_ds(isc_task_t *task, isc_event_t *event) { + } else if (eresult == DNS_R_SERVFAIL) { + goto unexpected; + } else if (eresult != DNS_R_CNAME && +- isdelegation(dns_fixedname_name(&devent->foundname), +- &val->frdataset, eresult)) ++ isdelegation(val, ++ dns_fixedname_name(&devent->foundname), ++ &val->frdataset, eresult, ++ "fetch_callback_ds") == ISC_R_SUCCESS) + { + /* + * Failed to find a DS while trying to prove +@@ -743,10 +770,13 @@ validator_callback_ds(isc_task_t *task, isc_event_t *event) { + dns_trust_totext(val->frdataset.trust)); + have_dsset = (val->frdataset.type == dns_rdatatype_ds); + name = dns_fixedname_name(&val->fname); ++ + if ((val->attributes & VALATTR_INSECURITY) != 0 && + val->frdataset.covers == dns_rdatatype_ds && + NEGATIVE(&val->frdataset) && +- isdelegation(name, &val->frdataset, DNS_R_NCACHENXRRSET)) ++ isdelegation(val, name, &val->frdataset, ++ DNS_R_NCACHENXRRSET, ++ "validator_callback_ds") == ISC_R_SUCCESS) + { + result = markanswer(val, "validator_callback_ds", + "no DS and this is a delegation"); +@@ -2565,7 +2595,8 @@ validate_nx(dns_validator_t *val, bool resume) { + result = findnsec3proofs(val); + if (result == DNS_R_NSEC3ITERRANGE) { + validator_log(val, ISC_LOG_DEBUG(3), +- "too many iterations"); ++ "%s: too many iterations", ++ __func__); + markanswer(val, "validate_nx (3)", NULL); + return (ISC_R_SUCCESS); + } +@@ -2601,7 +2632,7 @@ validate_nx(dns_validator_t *val, bool resume) { + result = findnsec3proofs(val); + if (result == DNS_R_NSEC3ITERRANGE) { + validator_log(val, ISC_LOG_DEBUG(3), +- "too many iterations"); ++ "%s: too many iterations", __func__); + markanswer(val, "validate_nx (4)", NULL); + return (ISC_R_SUCCESS); + } +@@ -2818,7 +2849,9 @@ seek_ds(dns_validator_t *val, isc_result_t *resp) { + return (ISC_R_COMPLETE); + } + +- if (isdelegation(tname, &val->frdataset, result)) { ++ result = isdelegation(val, tname, &val->frdataset, result, ++ "seek_ds"); ++ if (result == ISC_R_SUCCESS) { + *resp = markanswer(val, "proveunsecure (4)", + "this is a delegation"); + return (ISC_R_COMPLETE); +-- +2.45.4 + + +From 76a45317d9806512c7f1365e6893267ce681df00 Mon Sep 17 00:00:00 2001 +From: Matthijs Mekking +Date: Tue, 3 Mar 2026 11:17:25 +0100 +Subject: [PATCH 2/3] Don't verify already trusted rdatasets + +If we already marked an rdataset as secure (or it has even stronger +trust), there is no need to cryptographically verify it again. + +(cherry picked from commit 0ec08c212022d08c9717f2bc6bd3e8ebd6f034ce) +--- + lib/dns/include/dns/types.h | 1 + + lib/dns/validator.c | 7 +++++++ + 2 files changed, 8 insertions(+) + +diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h +index 641d81f..6f40629 100644 +--- a/lib/dns/include/dns/types.h ++++ b/lib/dns/include/dns/types.h +@@ -356,6 +356,7 @@ enum { + ((x) == dns_trust_additional || (x) == dns_trust_pending_additional) + #define DNS_TRUST_GLUE(x) ((x) == dns_trust_glue) + #define DNS_TRUST_ANSWER(x) ((x) == dns_trust_answer) ++#define DNS_TRUST_SECURE(x) ((x) >= dns_trust_secure) + + /*% + * Name checking severities. +diff --git a/lib/dns/validator.c b/lib/dns/validator.c +index 082db33..29585aa 100644 +--- a/lib/dns/validator.c ++++ b/lib/dns/validator.c +@@ -1508,6 +1508,13 @@ verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata, + bool ignore = false; + dns_name_t *wild; + ++ if (DNS_TRUST_SECURE(val->event->rdataset->trust)) { ++ /* ++ * This RRset was already verified before. ++ */ ++ return ISC_R_SUCCESS; ++ } ++ + val->attributes |= VALATTR_TRIEDVERIFY; + wild = dns_fixedname_initname(&fixed); + again: +-- +2.45.4 + + +From 447417e1964cfe78e6889b314a1507643c7fc326 Mon Sep 17 00:00:00 2001 +From: Matthijs Mekking +Date: Tue, 3 Mar 2026 11:43:23 +0100 +Subject: [PATCH 3/3] Check RRset trust in validate_neg_rrset() + +In many places we only create a validator if the RRset has too low +trust (the RRset is pending validation, or could not be validated +before). This check was missing prior to validating negative response +data. + +(cherry picked from commit 6ca67f65cd685cf8699540a852c1e3775bd48d64) +--- + lib/dns/validator.c | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +diff --git a/lib/dns/validator.c b/lib/dns/validator.c +index 29585aa..c758384 100644 +--- a/lib/dns/validator.c ++++ b/lib/dns/validator.c +@@ -2439,6 +2439,17 @@ validate_neg_rrset(dns_validator_t *val, dns_name_t *name, + } + } + ++ if (rdataset->type != dns_rdatatype_nsec && ++ DNS_TRUST_SECURE(rdataset->trust)) ++ { ++ /* ++ * The negative response data is already verified. ++ * We skip NSEC records, because they require special ++ * processing in validator_callback_nsec(). ++ */ ++ return DNS_R_CONTINUE; ++ } ++ + val->currentset = rdataset; + result = create_validator(val, name, rdataset->type, rdataset, + sigrdataset, validator_callback_nsec, +@@ -2549,11 +2560,9 @@ validate_ncache(dns_validator_t *val, bool resume) { + } + + result = validate_neg_rrset(val, name, rdataset, sigrdataset); +- if (result == DNS_R_CONTINUE) { +- continue; ++ if (result != DNS_R_CONTINUE) { ++ return (result); + } +- +- return (result); + } + if (result == ISC_R_NOMORE) { + result = ISC_R_SUCCESS; +-- +2.45.4 + diff --git a/SPECS/bind/bind.spec b/SPECS/bind/bind.spec index 185369c862f..b56ad32af43 100644 --- a/SPECS/bind/bind.spec +++ b/SPECS/bind/bind.spec @@ -10,7 +10,7 @@ Summary: Domain Name System software Name: bind Version: 9.16.50 -Release: 3%{?dist} +Release: 4%{?dist} License: ISC Vendor: Microsoft Corporation Distribution: Mariner @@ -40,6 +40,7 @@ Patch14: CVE-2024-11187.patch Patch15: CVE-2025-8677.patch Patch16: CVE-2025-40778.patch Patch17: CVE-2025-40780.patch +Patch18: CVE-2026-1519.patch BuildRequires: gcc BuildRequires: json-c-devel @@ -621,6 +622,9 @@ fi; %{_mandir}/man8/named-nzd2nzf.8* %changelog +* Thu Apr 02 2026 Azure Linux Security Servicing Account - 9.16.50-4 +- Patch for CVE-2026-1519 + * Tue Oct 28 2025 Akhila Guruju - 9.16.50-3 - Patch CVE-2025-8677, CVE-2025-40778 & CVE-2025-40780