Fix CVE-2026-13204: prevent accepting unsigned NSEC/NSEC3 records
Backport upstream commit 204fde85 to fix CVE-2026-13204.
The dns_rdataset_addnoqname() function could accept unsigned
NSEC/NSEC3 records, causing an assertion failure. The fix
restructures the NSEC/NSEC3 search to require a matching RRSIG
signature and replaces RUNTIME_CHECK assertions with graceful
error handling in query.c, rbtdb.c, rdatalist.c, and
resolver.c.
CVE: CVE-2026-13204
Upstream patches:
- 204fde8595.patch
Resolves: RHEL-213489
This commit was backported by Ymir, a Red Hat Enterprise Linux software maintenance AI agent.
Assisted-by: Ymir
This commit is contained in:
parent
0f28e7dd60
commit
cbdd087dd3
154
bind-9.11-CVE-2026-13204.patch
Normal file
154
bind-9.11-CVE-2026-13204.patch
Normal file
@ -0,0 +1,154 @@
|
||||
From 0be245b5c7641533fff2f808d19730e9766a9a36 Mon Sep 17 00:00:00 2001
|
||||
From: Evan Hunt <each@isc.org>
|
||||
Date: Wed, 13 May 2026 20:45:57 -0700
|
||||
Subject: [PATCH] dns_rdataset_addnoqname() could find unsigned NSEC/NSEC3
|
||||
|
||||
The dns_rdatalist addnoqname() implementation searches for the first
|
||||
NSEC or NSEC3 record in a message, then for the first RRSIG covering
|
||||
that type in the same message. Previously, if no RRSIG for the type was
|
||||
found, the function accepted the unsigned record. Now, it will instead
|
||||
continue searching until an NSEC or NSEC3 that does have a matching
|
||||
signature is found.
|
||||
|
||||
When this function is called from validated() in resolver.c, a
|
||||
non-success return code is now treated as an error instead of triggering
|
||||
an assertion failure.
|
||||
|
||||
Fixes: isc-projects/bind9#5985
|
||||
(cherry picked from commit 57cba571ee31311e54d8a11cb38094d439f04e09)
|
||||
---
|
||||
bin/named/query.c | 4 +++-
|
||||
lib/dns/rbtdb.c | 8 +++++---
|
||||
lib/dns/rdatalist.c | 36 +++++++++++++++++++++---------------
|
||||
lib/dns/resolver.c | 4 +++-
|
||||
4 files changed, 32 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/bin/named/query.c b/bin/named/query.c
|
||||
index e023d74..083ce83 100644
|
||||
--- a/bin/named/query.c
|
||||
+++ b/bin/named/query.c
|
||||
@@ -6198,7 +6198,9 @@ query_addnoqnameproof(ns_client_t *client, dns_rdataset_t *rdataset) {
|
||||
goto cleanup;
|
||||
|
||||
result = dns_rdataset_getnoqname(rdataset, fname, neg, negsig);
|
||||
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
+ if (result != ISC_R_SUCCESS) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
|
||||
query_addrrset(client, &fname, &neg, &negsig, dbuf,
|
||||
DNS_SECTION_AUTHORITY);
|
||||
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
|
||||
index 388ffdf..b7f21ac 100644
|
||||
--- a/lib/dns/rbtdb.c
|
||||
+++ b/lib/dns/rbtdb.c
|
||||
@@ -6977,7 +6977,7 @@ static inline isc_result_t
|
||||
addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
|
||||
dns_rdataset_t *rdataset)
|
||||
{
|
||||
- struct noqname *noqname;
|
||||
+ struct noqname *noqname = NULL;
|
||||
isc_mem_t *mctx = rbtdb->common.mctx;
|
||||
dns_name_t name;
|
||||
dns_rdataset_t neg, negsig;
|
||||
@@ -6989,7 +6989,9 @@ addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
|
||||
dns_rdataset_init(&negsig);
|
||||
|
||||
result = dns_rdataset_getnoqname(rdataset, &name, &neg, &negsig);
|
||||
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
+ if (result != ISC_R_SUCCESS) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
|
||||
noqname = isc_mem_get(mctx, sizeof(*noqname));
|
||||
if (noqname == NULL) {
|
||||
@@ -7021,7 +7023,7 @@ cleanup:
|
||||
dns_rdataset_disassociate(&negsig);
|
||||
if (noqname != NULL)
|
||||
free_noqname(mctx, &noqname);
|
||||
- return(result);
|
||||
+ return (result);
|
||||
}
|
||||
|
||||
static inline isc_result_t
|
||||
diff --git a/lib/dns/rdatalist.c b/lib/dns/rdatalist.c
|
||||
index cc2619c..687953c 100644
|
||||
--- a/lib/dns/rdatalist.c
|
||||
+++ b/lib/dns/rdatalist.c
|
||||
@@ -196,6 +196,7 @@ isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
|
||||
dns_rdataset_t *neg = NULL;
|
||||
dns_rdataset_t *negsig = NULL;
|
||||
dns_rdataset_t *rdset;
|
||||
+ dns_rdataset_t *sigset;
|
||||
dns_ttl_t ttl;
|
||||
|
||||
REQUIRE(rdataset != NULL);
|
||||
@@ -204,26 +205,30 @@ isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
|
||||
rdset != NULL;
|
||||
rdset = ISC_LIST_NEXT(rdset, link))
|
||||
{
|
||||
- if (rdset->rdclass != rdataset->rdclass)
|
||||
+ if (rdset->rdclass != rdataset->rdclass ||
|
||||
+ (rdset->type != dns_rdatatype_nsec &&
|
||||
+ rdset->type != dns_rdatatype_nsec3))
|
||||
+ {
|
||||
continue;
|
||||
- if (rdset->type == dns_rdatatype_nsec ||
|
||||
- rdset->type == dns_rdatatype_nsec3)
|
||||
- neg = rdset;
|
||||
+ }
|
||||
+
|
||||
+ for (sigset = ISC_LIST_HEAD(name->list); sigset != NULL;
|
||||
+ sigset = ISC_LIST_NEXT(sigset, link))
|
||||
+ {
|
||||
+ if (sigset->type == dns_rdatatype_rrsig &&
|
||||
+ sigset->covers == rdset->type)
|
||||
+ {
|
||||
+ neg = rdset;
|
||||
+ negsig = sigset;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
- if (neg == NULL)
|
||||
- return (ISC_R_NOTFOUND);
|
||||
|
||||
- for (rdset = ISC_LIST_HEAD(name->list);
|
||||
- rdset != NULL;
|
||||
- rdset = ISC_LIST_NEXT(rdset, link))
|
||||
- {
|
||||
- if (rdset->type == dns_rdatatype_rrsig &&
|
||||
- rdset->covers == neg->type)
|
||||
- negsig = rdset;
|
||||
+ if (neg == NULL || negsig == NULL) {
|
||||
+ return (ISC_R_NOTFOUND);
|
||||
}
|
||||
|
||||
- if (negsig == NULL)
|
||||
- return (ISC_R_NOTFOUND);
|
||||
/*
|
||||
* Minimise ttl.
|
||||
*/
|
||||
@@ -235,6 +240,7 @@ isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
|
||||
rdataset->ttl = neg->ttl = negsig->ttl = ttl;
|
||||
rdataset->attributes |= DNS_RDATASETATTR_NOQNAME;
|
||||
rdataset->private6 = name;
|
||||
+
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
|
||||
index 5331ea9..78553f6 100644
|
||||
--- a/lib/dns/resolver.c
|
||||
+++ b/lib/dns/resolver.c
|
||||
@@ -5153,7 +5153,9 @@ validated(isc_task_t *task, isc_event_t *event) {
|
||||
if (vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) {
|
||||
result = dns_rdataset_addnoqname(vevent->rdataset,
|
||||
vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF]);
|
||||
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
+ if (result != ISC_R_SUCCESS) {
|
||||
+ goto noanswer_response;
|
||||
+ }
|
||||
INSIST(vevent->sigrdataset != NULL);
|
||||
vevent->sigrdataset->ttl = vevent->rdataset->ttl;
|
||||
if (vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER] != NULL) {
|
||||
@ -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}.11
|
||||
Release: 16%{?PATCHVER:.%{PATCHVER}}%{?PREVER:.%{PREVER}}%{?dist}.12
|
||||
Epoch: 32
|
||||
Url: https://www.isc.org/downloads/bind/
|
||||
#
|
||||
@ -220,6 +220,8 @@ Patch219: bind-9.11-CVE-2026-11721.patch
|
||||
# https://github.com/isc-projects/bind9/commit/058023c66f11d78590d4aa8c4f98946c4c965e21
|
||||
# https://github.com/isc-projects/bind9/commit/f751e19a30d107f04c2f644aff9f8dab8fed03ab
|
||||
Patch220: bind-9.11-CVE-2026-13321.patch
|
||||
# https://github.com/isc-projects/bind9/commit/204fde85953d78475334694a7b9507dca47e73ba
|
||||
Patch221: bind-9.11-CVE-2026-13204.patch
|
||||
|
||||
# SDB patches
|
||||
Patch11: bind-9.3.2b2-sdbsrc.patch
|
||||
@ -655,6 +657,7 @@ are used for building ISC DHCP.
|
||||
%patch -P 218 -p1 -b .CVE-2026-11622
|
||||
%patch -P 219 -p1 -b .CVE-2026-11721
|
||||
%patch -P 220 -p1 -b .CVE-2026-13321
|
||||
%patch -P 221 -p1 -b .CVE-2026-13204
|
||||
|
||||
mkdir lib/dns/tests/testdata/dstrandom
|
||||
cp -a %{SOURCE50} lib/dns/tests/testdata/dstrandom/random.data
|
||||
@ -1707,6 +1710,9 @@ rm -rf ${RPM_BUILD_ROOT}
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Mon Jul 27 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 32:9.11.36-16.12
|
||||
- Prevent accepting unsigned NSEC/NSEC3 records (CVE-2026-13204)
|
||||
|
||||
* Mon Jul 27 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 32:9.11.36-16.11
|
||||
- Reject out-of-zone NSEC entries in DNSSEC validation
|
||||
(CVE-2026-13321)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user