bind9.16/bind-9.16-CVE-2026-13321.patch
RHEL Packaging Agent 69fc1b29c6 Fix CVE-2026-13321: reject out-of-zone NSEC next owner names
Backport upstream commit af84538a2ce6 to fix CVE-2026-13321.
The patch adds validation in dns_dnssec_verify() to reject
out-of-zone NSEC next owner names by checking that the NSEC
next name is a subdomain of the signer field, as required by
RFC 4034 section 4.1.1.

CVE: CVE-2026-13321
Upstream patches:
 - af84538a2c.patch
Resolves: RHEL-213313

This commit was backported by Ymir, a Red Hat Enterprise Linux software maintenance AI agent.

Assisted-by: Ymir
2026-08-04 18:09:29 +02:00

86 lines
3.0 KiB
Diff

From db08a828d3a2fae9bdcc901645d63adcd9d090eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ayd=C4=B1n=20Mercan?= <aydin@isc.org>
Date: Thu, 7 May 2026 18:59:20 +0300
Subject: [PATCH] Reject out-of-zone NSEC next owner names
When verifying DNSSEC records, make sure that a next owner name of
an NSEC record is a subdomain of the signer field.
This follows the specification RFC 4034, section 4.1.1:
Owner names of RRsets for which the given zone is not authoritative
(such as glue records) MUST NOT be listed in the Next Domain Name
unless at least one authoritative RRset exists at the same owner
name.
While the above paragraph is intended for glue records, it also
applies to out-of-zone data.
(cherry picked from commit 4065512d25b71605b9502bb69dfb903776d35aa9)
---
lib/dns/dnssec.c | 17 +++++++++++++++++
lib/dns/include/dns/dnssec.h | 6 ++++++
2 files changed, 23 insertions(+)
diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c
index c168fed..2ab9c02 100644
--- a/lib/dns/dnssec.c
+++ b/lib/dns/dnssec.c
@@ -376,8 +376,10 @@ isc_result_t
dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
bool ignoretime, unsigned int maxbits, isc_mem_t *mctx,
dns_rdata_t *sigrdata, dns_name_t *wild) {
+ dns_rdata_nsec_t nsec;
dns_rdata_rrsig_t sig;
dns_fixedname_t fnewname;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
isc_region_t r;
isc_buffer_t envbuf;
dns_rdata_t *rdatas;
@@ -451,6 +453,21 @@ dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
}
break;
}
+ /*
+ * Check for out of zone NSEC entries.
+ */
+ if (set->type == dns_rdatatype_nsec) {
+ if (dns_rdataset_first(set) != ISC_R_SUCCESS) {
+ return (DNS_R_NOVALIDNSEC);
+ }
+ dns_rdataset_current(set, &rdata);
+ if (dns_rdata_tostruct(&rdata, &nsec, NULL) != ISC_R_SUCCESS) {
+ return (DNS_R_NOVALIDNSEC);
+ }
+ if (!dns_name_issubdomain(&nsec.next, &sig.signer)) {
+ return (DNS_R_NOVALIDNSEC);
+ }
+ }
/*
* Is the key allowed to sign data?
diff --git a/lib/dns/include/dns/dnssec.h b/lib/dns/include/dns/dnssec.h
index e74ec47..c811e25 100644
--- a/lib/dns/include/dns/dnssec.h
+++ b/lib/dns/include/dns/dnssec.h
@@ -133,6 +133,9 @@ dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
* this record, as this requires a resolver or database.
* If 'ignoretime' is true, temporal validity will not be checked.
*
+ * If 'set' is of type NSEC, this function also verifies that the
+ * Next Name is a subdomain of the Signer's Name from 'sigrdata'.
+ *
* 'maxbits' specifies the maximum number of rsa exponent bits accepted.
*
* Requires:
@@ -155,6 +158,9 @@ dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
*\li #DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either
* it is not a zone key or its flags prevent
* authentication)
+ *
+ *\li #DNS_R_NOVALIDNSEC - the NSEC rdata is not valid
+ *\li #DNS_R_KEYUNAUTHORIZED - the key cannot sign this data
*\li DST_R_*
*/