From 5e15a3310c61bceab7432f8bd50aff9c84ad1278 Mon Sep 17 00:00:00 2001 From: AlmaLinux RelEng Bot Date: Wed, 15 Apr 2026 19:30:55 -0400 Subject: [PATCH] import CS git bind-9.11.36-16.el8_10.7 --- SOURCES/bind-9.11-CVE-2026-1519.patch | 261 ++++++++++++++++++++++++++ SPECS/bind.spec | 9 +- 2 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 SOURCES/bind-9.11-CVE-2026-1519.patch diff --git a/SOURCES/bind-9.11-CVE-2026-1519.patch b/SOURCES/bind-9.11-CVE-2026-1519.patch new file mode 100644 index 0000000..e5b1b04 --- /dev/null +++ b/SOURCES/bind-9.11-CVE-2026-1519.patch @@ -0,0 +1,261 @@ +From 19b300cadcc265af7f6cdee16a32b5a5d9139b38 Mon Sep 17 00:00:00 2001 +From: Matthijs Mekking +Date: Tue, 3 Mar 2026 10:40:36 +0100 +Subject: [PATCH] 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) +(cherry picked from commit 0d8f3d0b22fb23c5a9138cc48e72ef8ab3d603df) + +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) +(cherry picked from commit e1d47d57e4cb496a8b64ea292467cd05a769d1e6) + +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) +(cherry picked from commit fe40620f47ce7cc10aca33b3d4f0a840f53f708d) +--- + lib/dns/include/dns/types.h | 2 +- + lib/dns/validator.c | 96 +++++++++++++++++++++++++++++++------ + 2 files changed, 82 insertions(+), 16 deletions(-) + +diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h +index 934a641118..1b0f2b71a0 100644 +--- a/lib/dns/include/dns/types.h ++++ b/lib/dns/include/dns/types.h +@@ -357,7 +357,7 @@ enum { + (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 0b257fe874..5bc7bec951 100644 +--- a/lib/dns/validator.c ++++ b/lib/dns/validator.c +@@ -262,12 +262,25 @@ dlv_algorithm_supported(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; +@@ -295,7 +308,7 @@ isdelegation(dns_name_t *name, dns_rdataset_t *rdataset, + if (result == ISC_R_NOTFOUND) + goto trynsec3; + if (result != ISC_R_SUCCESS) +- return (false); ++ return (ISC_R_NOTFOUND); + } + + INSIST(set.type == dns_rdatatype_nsec); +@@ -308,7 +321,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: + /* +@@ -345,18 +358,33 @@ isdelegation(dns_name_t *name, dns_rdataset_t *rdataset, + (void)dns_rdata_tostruct(&rdata, &nsec3, NULL); + 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); + if (length != isc_buffer_usedlength(&buffer)) + continue; ++ + order = memcmp(hash, owner, length); + if (order == 0) { + 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; +@@ -370,12 +398,12 @@ isdelegation(dns_name_t *name, dns_rdataset_t *rdataset, + 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); + } + + /*% +@@ -597,7 +625,8 @@ dsfetched2(isc_task_t *task, isc_event_t *event) { + */ + tname = dns_fixedname_name(&devent->foundname); + if (eresult != DNS_R_CNAME && +- isdelegation(tname, &val->frdataset, eresult)) { ++ isdelegation(val, tname, &val->frdataset, eresult, ++ "dsfetched2") == ISC_R_SUCCESS) { + if (val->mustbesecure) { + validator_log(val, ISC_LOG_WARNING, + "must be secure failure, no DS" +@@ -754,10 +783,13 @@ dsvalidated(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, ++ "dsvalidated") == ISC_R_SUCCESS) { + if (val->mustbesecure) { + validator_log(val, ISC_LOG_WARNING, + "must be secure failure, no DS " +@@ -1524,6 +1556,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: +@@ -2714,6 +2753,19 @@ validate_authority(dns_validator_t *val, bool resume) { + dns_rdatatype_soa)) + continue; + } ++ ++ 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 ++ * authvalidated(). ++ */ ++ continue; ++ } ++ + val->currentset = rdataset; + result = create_validator(val, name, rdataset->type, + rdataset, sigrdataset, +@@ -2791,6 +2843,18 @@ validate_ncache(dns_validator_t *val, bool resume) { + dns_rdatatype_soa)) + continue; + } ++ ++ 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 authvalidated(). ++ */ ++ continue; ++ } ++ + val->currentset = rdataset; + result = create_validator(val, name, rdataset->type, + rdataset, sigrdataset, +@@ -2842,7 +2906,8 @@ nsecvalidate(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)"); + return (ISC_R_SUCCESS); + } +@@ -2877,7 +2942,7 @@ nsecvalidate(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)"); + return (ISC_R_SUCCESS); + } +@@ -3463,7 +3528,8 @@ proveunsecure(dns_validator_t *val, bool have_ds, bool resume) + result = DNS_R_NOVALIDSIG; + goto out; + } +- if (isdelegation(tname, &val->frdataset, result)) { ++ if (isdelegation(val, tname, &val->frdataset, result, ++ "proveunsecure") == ISC_R_SUCCESS) { + if (val->mustbesecure) { + validator_log(val, ISC_LOG_WARNING, + "must be secure failure, " +-- +2.53.0 + diff --git a/SPECS/bind.spec b/SPECS/bind.spec index f8c1a1b..8b9bcf6 100644 --- a/SPECS/bind.spec +++ b/SPECS/bind.spec @@ -68,7 +68,7 @@ Summary: The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) serv Name: bind License: MPLv2.0 Version: 9.11.36 -Release: 16%{?PATCHVER:.%{PATCHVER}}%{?PREVER:.%{PREVER}}%{?dist}.6 +Release: 16%{?PATCHVER:.%{PATCHVER}}%{?PREVER:.%{PREVER}}%{?dist}.7 Epoch: 32 Url: https://www.isc.org/downloads/bind/ # @@ -205,6 +205,8 @@ Patch211: bind-9.11-d-max-records-per-type.patch Patch212: bind-9.11-d-max-types-per-name.patch Patch213: bind-9.11-d-max-records-checkconf.patch Patch214: bind-9.11-CVE-2025-40778.patch +# https://gitlab.isc.org/isc-projects/bind9/commit/e5357c1623da3842227d2c76468b76bc983584d6 +Patch215: bind-9.11-CVE-2026-1519.patch # SDB patches Patch11: bind-9.3.2b2-sdbsrc.patch @@ -634,6 +636,7 @@ are used for building ISC DHCP. %patch -P 212 -p1 -b .types-per-name %patch -P 213 -p1 -b .records-checkconf %patch -P 214 -p1 -b .CVE-2025-40778 +%patch -P 215 -p1 -b .CVE-2026-1519 mkdir lib/dns/tests/testdata/dstrandom cp -a %{SOURCE50} lib/dns/tests/testdata/dstrandom/random.data @@ -1686,6 +1689,10 @@ rm -rf ${RPM_BUILD_ROOT} %endif %changelog +* Fri Mar 27 2026 Petr Menšík - 32:9.11.36-16.7 +- Denial of Service via maliciously crafted DNSSEC-validated zone + (CVE-2026-1519) + * Thu Oct 30 2025 Petr Menšík - 32:9.11.36-16.6 - Address various spoofing attacks (CVE-2025-40778)