Patches were taken from the z-stream build. Resolves: RHEL-215712 Resolves: RHEL-213781 Resolves: RHEL-213493 Resolves: RHEL-213416 Resolves: RHEL-213371 Resolves: RHEL-213332
159 lines
4.9 KiB
Diff
159 lines
4.9 KiB
Diff
From 5b53a4c2c99bbe76523c73b3f6fe153d7904d2c0 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)
|
|
---
|
|
lib/dns/rbtdb.c | 10 +++++++---
|
|
lib/dns/rdatalist.c | 33 ++++++++++++++++-----------------
|
|
lib/dns/resolver.c | 4 +++-
|
|
lib/ns/query.c | 4 +++-
|
|
4 files changed, 29 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
|
|
index 1b108da..68f7284 100644
|
|
--- a/lib/dns/rbtdb.c
|
|
+++ b/lib/dns/rbtdb.c
|
|
@@ -6914,7 +6914,7 @@ delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
|
static isc_result_t
|
|
addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
|
|
uint32_t maxrrperset, 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;
|
|
@@ -6926,7 +6926,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));
|
|
dns_name_init(&noqname->name, NULL);
|
|
@@ -6952,7 +6954,9 @@ addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
|
|
cleanup:
|
|
dns_rdataset_disassociate(&neg);
|
|
dns_rdataset_disassociate(&negsig);
|
|
- free_noqname(mctx, &noqname);
|
|
+ if (noqname != NULL) {
|
|
+ free_noqname(mctx, &noqname);
|
|
+ }
|
|
return (result);
|
|
}
|
|
|
|
diff --git a/lib/dns/rdatalist.c b/lib/dns/rdatalist.c
|
|
index a2643c7..858bfa8 100644
|
|
--- a/lib/dns/rdatalist.c
|
|
+++ b/lib/dns/rdatalist.c
|
|
@@ -192,6 +192,7 @@ isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, const 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);
|
|
@@ -199,30 +200,27 @@ isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, const dns_name_t *name) {
|
|
for (rdset = ISC_LIST_HEAD(name->list); rdset != NULL;
|
|
rdset = ISC_LIST_NEXT(rdset, link))
|
|
{
|
|
- if (rdset->rdclass != rdataset->rdclass) {
|
|
- continue;
|
|
- }
|
|
- if (rdset->type == dns_rdatatype_nsec ||
|
|
- rdset->type == dns_rdatatype_nsec3)
|
|
+ if (rdset->rdclass != rdataset->rdclass ||
|
|
+ (rdset->type != dns_rdatatype_nsec &&
|
|
+ rdset->type != dns_rdatatype_nsec3))
|
|
{
|
|
- neg = rdset;
|
|
+ continue;
|
|
}
|
|
- }
|
|
- 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)
|
|
+ for (sigset = ISC_LIST_HEAD(name->list); sigset != NULL;
|
|
+ sigset = ISC_LIST_NEXT(sigset, link))
|
|
{
|
|
- negsig = rdset;
|
|
+ if (sigset->type == dns_rdatatype_rrsig &&
|
|
+ sigset->covers == rdset->type)
|
|
+ {
|
|
+ neg = rdset;
|
|
+ negsig = sigset;
|
|
+ break;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
- if (negsig == NULL) {
|
|
+ if (neg == NULL || negsig == NULL) {
|
|
return (ISC_R_NOTFOUND);
|
|
}
|
|
/*
|
|
@@ -238,6 +236,7 @@ isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, const 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 1ae62fa..1226a4e 100644
|
|
--- a/lib/dns/resolver.c
|
|
+++ b/lib/dns/resolver.c
|
|
@@ -6010,7 +6010,9 @@ validated(isc_task_t *task, isc_event_t *event) {
|
|
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) {
|
|
diff --git a/lib/ns/query.c b/lib/ns/query.c
|
|
index 133ca3b..3000f1b 100644
|
|
--- a/lib/ns/query.c
|
|
+++ b/lib/ns/query.c
|
|
@@ -7603,7 +7603,9 @@ query_addnoqnameproof(query_ctx_t *qctx) {
|
|
}
|
|
|
|
result = dns_rdataset_getnoqname(qctx->noqname, fname, neg, negsig);
|
|
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
|
+ if (result != ISC_R_SUCCESS) {
|
|
+ goto cleanup;
|
|
+ }
|
|
|
|
query_addrrset(qctx, &fname, &neg, &negsig, dbuf,
|
|
DNS_SECTION_AUTHORITY);
|
|
--
|
|
2.55.0
|
|
|