import CS git bind-9.11.36-16.el8_10.7

This commit is contained in:
AlmaLinux RelEng Bot 2026-04-15 19:30:55 -04:00
parent 89066dd857
commit 5e15a3310c
2 changed files with 269 additions and 1 deletions

View File

@ -0,0 +1,261 @@
From 19b300cadcc265af7f6cdee16a32b5a5d9139b38 Mon Sep 17 00:00:00 2001
From: Matthijs Mekking <matthijs@isc.org>
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

View File

@ -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 <pemensik@redhat.com> - 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 <pemensik@redhat.com> - 32:9.11.36-16.6
- Address various spoofing attacks (CVE-2025-40778)