bind/SOURCES/bind-9.16-CVE-2026-5946.patch
2026-06-10 09:00:12 -04:00

730 lines
26 KiB
Diff

From f215b6bb4a2a2bbed98195be7aa25e81d6e13b5c Mon Sep 17 00:00:00 2001
From: Evan Hunt <each@isc.org>
Date: Tue, 3 Mar 2026 14:00:38 -0800
Subject: [PATCH] Disable recursion for non-IN classes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Force recursion off, and set allow-recursion/allow-recursion-on ACLs
to none, for views with a class other than IN. Log a configuration
warning if recursion is explicitly enabled for a non-IN view.
This addresses YWH-PGM40640-74 and YWH-PGM40640-75 by preventing any
attempt at recursive processing in a class-CHAOS view, ensuring that
server addresses used for recursive queries and received in recursive
responses are of the expected format.
Fixes: isc-projects/bind9#5780
Fixes: isc-projects/bind9#5781
(cherry picked from commit 70532a37a1aec761e8a12444852866ce9d9d5fcc)
(cherry picked from commit cf0d5a4e385525e21f2ae39098b1ab90c1137a2a)
(cherry picked from commit e577560f65dbc6109fca8a597d16568a1cd8987c)
Disable UPDATE and NOTIFY for non-IN classes
Return NOTIMP for UPDATE and NOTIFY requests received for views with a
class other than IN. Only QUERY is now supported for non-IN views such
as CHAOS.
When running dns dns_rdata_tostruct() with types that are only defined
for class IN, ensure that the class is correct before proceeding.
Add an assertion that any zone being updated is of class IN. (Note
that previously, a DLZ zone could have its class value set incorrectly
to NONE; this has been fixed.)
This addresses YWH-PGM40640-70 and YWH-PGM40640-73 (as well as any
similar problems that might have occurred in the future) by minimizing
the code paths that can be reached by rdata classes other than IN, so it
is safe for the implementation to assume that rdatatypes that are only
defined for class IN, such as SVCB or WKS, have been parsed and
validated, and not accepted as unknown/opaque data.
Fixes: isc-projects/bind9#5777
Fixes: isc-projects/bind9#5779
(cherry picked from commit 9ae24c32bec16c0f64225ef04f34670018bf0765)
(cherry picked from commit a2ca2408b3ff031c426c5dc785f550c9d30bf4aa)
(cherry picked from commit bec30ad70d17e36241df9da259bb2ac85b3c3435)
Validate DNS message CLASS early in request processing
Reject requests with unsupported or misused CLASS values before
further processing. Only IN, CH, HS, RESERVED0 (for DNS Cookies),
ANY (for TKEY negotiation), and NONE (for DNS UPDATE) are accepted;
all other classes return NOTIMP. Misuse of NONE or ANY outside
their allowed contexts returns FORMERR.
This adds further protection against bugs of the same general class
as YWH-PGM40640-70 and YWH-PGM40640-73.
(cherry picked from commit d41865a458b9ecd76be4097ac1bea1005cad72db)
(cherry picked from commit 1c8016c91c3674929f87cbe7ad09f3670e05ad4e)
(cherry picked from commit 986533b5ae8e855e23430bd7f6af7552d82e0ece)
Reject meta-classes in UPDATE and NOTIFY messages
NOTIFY and UPDATE messages must specify a data class in the
QUESTION/ZONE section. NONE and ANY are meta-classes and not
appropriate here. Return FORMERR if either is used.
Rejecting messages with a query class of NONE addresses YWH-PGM40640-72,
YWH-PGM40640-82, and YWH-PGM40640-83. Rejecting messages with a query
class of ANY addresses YWH-PGM40640-87, YWH-PGM40640-88, and
YWH-PGM40640-117.
Fixes: isc-projects/bind9#5778
Fixes: isc-projects/bind9#5782
Fixes: isc-projects/bind9#5783
Fixes: isc-projects/bind9#5797
Fixes: isc-projects/bind9#5798
Fixes: isc-projects/bind9#5853
(cherry picked from commit 7de5160517ae69196d1c323b8627b267cdd10761)
(cherry picked from commit 3c44de9e6252ec1c7742ef02ecc0d6cbf1cde5e9)
(cherry picked from commit e7468f6be6dc98f86508627f4f333b6d09d2ac31)
Skip "deny-answer-address" for non-IN addresses
Ensure that we don't attempt an ACL match for answer addresses
when handling a class-CHAOS zone. This is an additional line of
defense for YWH-PGM40640-74.
(cherry picked from commit 4cd3d8e6d866143ddc62df821a1007bf3ee7f083)
(cherry picked from commit fa60101e910346e64fa2a684b903fbcb84d8243b)
(cherry picked from commit e60ee54f7d650783d3b6dd7fdd749c64c6593353)
Pass empty string instead of NULL to ns_client_dumpmessage()
The two new call sites added by the CLASS-validation work passed NULL
as the reason, but ns_client_dumpmessage() bails out early on a NULL
reason — so the message dump never happened. The intent was to dump
the message and let the follow-up ns_client_log() carry the reason
text, so pass "" to suppress the prefix without short-circuiting the
dump.
(cherry picked from commit 8af39c360407a92ef31bf233b9df760d1bb9fb5f)
(cherry picked from commit cd3a72e414d35c2ae573f4faea1148a95db7d5ff)
%RH
fixed resolver, checkconf test
---
bin/named/server.c | 41 ++++--------
bin/tests/system/checkconf/tests.sh | 14 +++-
.../checkconf/warn-chaos-recursion.conf | 25 ++++++++
bin/tests/system/resolver/tests.sh | 12 +++-
bin/tests/system/unknown/tests.sh | 12 ++--
lib/bind9/check.c | 22 ++++++-
lib/dns/adb.c | 3 +-
lib/dns/message.c | 11 ++++
lib/dns/resolver.c | 13 +++-
lib/ns/client.c | 64 ++++++++++++++++---
lib/ns/update.c | 38 +++++------
11 files changed, 181 insertions(+), 74 deletions(-)
create mode 100644 bin/tests/system/checkconf/warn-chaos-recursion.conf
diff --git a/bin/named/server.c b/bin/named/server.c
index 4cc69b5..c61de53 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -1925,10 +1925,12 @@ dlzconfigure_callback(dns_view_t *view, dns_dlzdb_t *dlzdb, dns_zone_t *zone) {
dns_rdataclass_t zclass = view->rdclass;
isc_result_t result;
+ dns_zone_setclass(zone, zclass);
result = dns_zonemgr_managezone(named_g_server->zonemgr, zone);
if (result != ISC_R_SUCCESS) {
return (result);
}
+
dns_zone_setstats(zone, named_g_server->zonestats);
return (named_zone_configure_writeable_dlz(dlzdb, zone, zclass,
@@ -4180,6 +4182,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
obj = NULL;
result = named_config_get(maps, "max-cache-size", &obj);
INSIST(result == ISC_R_SUCCESS);
+
/*
* If "-T maxcachesize=..." is in effect, it overrides any other
* "max-cache-size" setting found in configuration, either implicit or
@@ -4930,34 +4933,15 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
}
/*
- * We have default hints for class IN if we need them.
+ * We have default root hints for class IN if we need them.
+ * Each view gets its own rootdb so a priming response only
+ * writes into that view's copy. Other classes don't support
+ * recursion and don't need hints.
*/
if (view->rdclass == dns_rdataclass_in && view->hints == NULL) {
dns_view_sethints(view, named_g_server->in_roothints);
}
- /*
- * If we still have no hints, this is a non-IN view with no
- * "hints zone" configured. Issue a warning, except if this
- * is a root server. Root servers never need to consult
- * their hints, so it's no point requiring users to configure
- * them.
- */
- if (view->hints == NULL) {
- dns_zone_t *rootzone = NULL;
- (void)dns_view_findzone(view, dns_rootname, &rootzone);
- if (rootzone != NULL) {
- dns_zone_detach(&rootzone);
- need_hints = false;
- }
- if (need_hints) {
- isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL,
- NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING,
- "no root hints for view '%s'",
- view->name);
- }
- }
-
/*
* Configure the view's TSIG keys.
*/
@@ -5067,7 +5051,8 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
obj = NULL;
result = named_config_get(maps, "recursion", &obj);
INSIST(result == ISC_R_SUCCESS);
- view->recursion = cfg_obj_asboolean(obj);
+ view->recursion = (view->rdclass == dns_rdataclass_in &&
+ cfg_obj_asboolean(obj));
obj = NULL;
result = named_config_get(maps, "qname-minimization", &obj);
@@ -5168,13 +5153,13 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
CHECK(configure_view_acl(vconfig, config, NULL, "allow-query-cache-on",
NULL, actx, named_g_mctx, &view->cacheonacl));
- if (strcmp(view->name, "_bind") != 0 &&
- view->rdclass != dns_rdataclass_chaos) {
- /* named.conf only */
+ if (view->rdclass != dns_rdataclass_in) {
+ dns_acl_none(named_g_mctx, &view->recursionacl);
+ dns_acl_none(named_g_mctx, &view->recursiononacl);
+ } else {
CHECK(configure_view_acl(vconfig, config, NULL,
"allow-recursion", NULL, actx,
named_g_mctx, &view->recursionacl));
- /* named.conf only */
CHECK(configure_view_acl(vconfig, config, NULL,
"allow-recursion-on", NULL, actx,
named_g_mctx, &view->recursiononacl));
diff --git a/bin/tests/system/checkconf/tests.sh b/bin/tests/system/checkconf/tests.sh
index c1feed1..921707e 100644
--- a/bin/tests/system/checkconf/tests.sh
+++ b/bin/tests/system/checkconf/tests.sh
@@ -402,7 +402,8 @@ $CHECKCONF -l good.conf |
grep -v "is not implemented" |
grep -v "is not recommended" |
grep -v "no longer exists" |
-grep -v "is obsolete" > checkconf.out$n || ret=1
+grep -v "is obsolete" |
+grep -v "recursion will be disabled" > checkconf.out$n || ret=1
diff good.zonelist checkconf.out$n > diff.out$n || ret=1
if [ $ret != 0 ]; then echo_i "failed"; ret=1; fi
status=`expr $status + $ret`
@@ -603,5 +604,16 @@ status=$((status+ret))
rmdir keys
+n=$((n + 1))
+echo_i "check 'recursion yes;' is warned and disabled in a non-IN view ($n)"
+ret=0
+$CHECKCONF warn-chaos-recursion.conf >checkconf.out$n 2>&1 || ret=1
+grep -F "recursion will be disabled" checkconf.out$n >/dev/null || ret=1
+if [ $ret != 0 ]; then
+ echo_i "failed"
+ ret=1
+fi
+status=$((status + ret))
+
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
diff --git a/bin/tests/system/checkconf/warn-chaos-recursion.conf b/bin/tests/system/checkconf/warn-chaos-recursion.conf
new file mode 100644
index 0000000..e384533
--- /dev/null
+++ b/bin/tests/system/checkconf/warn-chaos-recursion.conf
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+options {
+ directory ".";
+};
+
+view chaos ch {
+ match-clients { any; };
+ recursion yes;
+ zone "." {
+ type hint;
+ file "chaos.hints";
+ };
+};
diff --git a/bin/tests/system/resolver/tests.sh b/bin/tests/system/resolver/tests.sh
index 2eae16f..30e86bc 100755
--- a/bin/tests/system/resolver/tests.sh
+++ b/bin/tests/system/resolver/tests.sh
@@ -16,6 +16,10 @@ DIGOPTS="-p ${PORT}"
RESOLVOPTS="-p ${PORT}"
RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s"
+dig_with_opts() {
+ "$DIG" $DIGOPTS "$@"
+}
+
status=0
n=0
@@ -853,10 +857,12 @@ if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
-echo_i "checking NXDOMAIN is returned when querying non existing domain in CH class ($n)"
+echo_i "checking REFUSED is returned when querying non existing domain in CH class ($n)"
ret=0
-$DIG $DIGOPTS @10.53.0.1 id.hostname txt ch > dig.ns1.out.${n} || ret=1
-grep "status: NXDOMAIN" dig.ns1.out.${n} > /dev/null || ret=1
+dig_with_opts @10.53.0.1 hostname.chaostest txt ch >dig.ns1.out.1.${n} || ret=1
+grep "status: NOERROR" dig.ns1.out.1.${n} >/dev/null || ret=1
+dig_with_opts @10.53.0.1 id.hostname txt ch >dig.ns1.out.2.${n} || ret=1
+grep "status: REFUSED" dig.ns1.out.2.${n} >/dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
diff --git a/bin/tests/system/unknown/tests.sh b/bin/tests/system/unknown/tests.sh
index e480f66..5576216 100644
--- a/bin/tests/system/unknown/tests.sh
+++ b/bin/tests/system/unknown/tests.sh
@@ -80,8 +80,8 @@ echo_i "querying for various representations of a CLASS10 TYPE1 record ($n)"
for i in 1 2
do
ret=0
- $DIG +short $DIGOPTS @10.53.0.1 a$i.example a class10 > dig.out.$i.test$n || ret=1
- echo '\# 4 0A000001' | $DIFF - dig.out.$i.test$n || ret=1
+ $DIG $DIGOPTS @10.53.0.1 a$i.example a class10 >dig.out.$i.test$n || ret=1
+ grep -q "NOTIMP" dig.out.$i.test$n || ret=1
if [ $ret != 0 ]
then
echo_i "#$i failed"
@@ -94,8 +94,8 @@ echo_i "querying for various representations of a CLASS10 TXT record ($n)"
for i in 1 2 3 4
do
ret=0
- $DIG +short $DIGOPTS @10.53.0.1 txt$i.example txt class10 > dig.out.$i.test$n || ret=1
- echo '"hello"' | $DIFF - dig.out.$i.test$n || ret=1
+ $DIG $DIGOPTS @10.53.0.1 txt$i.example txt class10 >dig.out.$i.test$n || ret=1
+ grep -q "NOTIMP" dig.out.$i.test$n || ret=1
if [ $ret != 0 ]
then
echo_i "#$i failed"
@@ -108,8 +108,8 @@ echo_i "querying for various representations of a CLASS10 TYPE123 record ($n)"
for i in 1 2
do
ret=0
- $DIG +short $DIGOPTS @10.53.0.1 unk$i.example type123 class10 > dig.out.$i.test$n || ret=1
- echo '\# 1 00' | $DIFF - dig.out.$i.test$n || ret=1
+ $DIG $DIGOPTS @10.53.0.1 unk$i.example type123 class10 >dig.out.$i.test$n || ret=1
+ grep -q "NOTIMP" dig.out.$i.test$n || ret=1
if [ $ret != 0 ]
then
echo_i "#$i failed"
diff --git a/lib/bind9/check.c b/lib/bind9/check.c
index 2225bee..e55c4fc 100644
--- a/lib/bind9/check.c
+++ b/lib/bind9/check.c
@@ -2271,13 +2271,17 @@ check_mirror_zone_notify(const cfg_obj_t *zoptions, const char *znamestr,
*/
static bool
check_recursion(const cfg_obj_t *config, const cfg_obj_t *voptions,
- const cfg_obj_t *goptions, isc_log_t *logctx,
- cfg_aclconfctx_t *actx, isc_mem_t *mctx) {
+ dns_rdataclass_t vclass, const cfg_obj_t *goptions,
+ isc_log_t *logctx, cfg_aclconfctx_t *actx, isc_mem_t *mctx) {
dns_acl_t *acl = NULL;
const cfg_obj_t *obj;
isc_result_t result;
bool retval = true;
+ if (vclass != dns_rdataclass_in) {
+ return false;
+ }
+
/*
* Check the "recursion" option first.
*/
@@ -2831,7 +2835,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
* contradicts the purpose of the former.
*/
if (ztype == CFG_ZONE_MIRROR &&
- !check_recursion(config, voptions, goptions, logctx, actx, mctx))
+ !check_recursion(config, voptions, zclass, goptions, logctx, actx,
+ mctx))
{
cfg_obj_log(zoptions, logctx, ISC_LOG_ERROR,
"zone '%s': mirror zones cannot be used if "
@@ -4553,6 +4558,17 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
cfg_aclconfctx_create(mctx, &actx);
+ if (vclass != dns_rdataclass_in) {
+ if (check_recursion(config, voptions, dns_rdataclass_in,
+ options, logctx, actx, mctx))
+ {
+ cfg_obj_log(opts, logctx, ISC_LOG_WARNING,
+ "recursion will be disabled for "
+ "non-IN view '%s'",
+ viewname);
+ }
+ }
+
if (voptions != NULL) {
(void)cfg_map_get(voptions, "zone", &zones);
} else {
diff --git a/lib/dns/adb.c b/lib/dns/adb.c
index 74fdc72..cc00798 100644
--- a/lib/dns/adb.c
+++ b/lib/dns/adb.c
@@ -941,7 +941,8 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
INSIST(DNS_ADB_VALID(adb));
rdtype = rdataset->type;
- INSIST((rdtype == dns_rdatatype_a) || (rdtype == dns_rdatatype_aaaa));
+ REQUIRE(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa);
+
if (rdtype == dns_rdatatype_a) {
findoptions = DNS_ADBFIND_INET;
} else {
diff --git a/lib/dns/message.c b/lib/dns/message.c
index aa434a7..a81943d 100644
--- a/lib/dns/message.c
+++ b/lib/dns/message.c
@@ -1085,6 +1085,17 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
rdtype = isc_buffer_getuint16(source);
rdclass = isc_buffer_getuint16(source);
+ /*
+ * Notify and update messages need to specify the data class.
+ */
+ if ((msg->opcode == dns_opcode_update ||
+ msg->opcode == dns_opcode_notify) &&
+ (rdclass == dns_rdataclass_none ||
+ rdclass == dns_rdataclass_any))
+ {
+ DO_ERROR(DNS_R_FORMERR);
+ }
+
/*
* If this class is different than the one we already read,
* this is an error.
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 5973bc1..460a15e 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -7369,9 +7369,16 @@ is_answeraddress_allowed(dns_view_t *view, dns_name_t *name,
}
/*
- * Otherwise, search the filter list for a match for each address
- * record. If a match is found, the address should be filtered,
- * so should the entire answer.
+ * deny-answer-address doesn't apply to non-IN classes.
+ */
+ if (rdataset->rdclass != dns_rdataclass_in) {
+ return true;
+ }
+
+ /*
+ * Otherwise, search the filter list for a match for each
+ * address record. If a match is found, the address should be
+ * filtered, so should the entire answer.
*/
for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
result = dns_rdataset_next(rdataset))
diff --git a/lib/ns/client.c b/lib/ns/client.c
index 87b8a18..554934f 100644
--- a/lib/ns/client.c
+++ b/lib/ns/client.c
@@ -40,6 +40,7 @@
#include <dns/dispatch.h>
#include <dns/dnstap.h>
#include <dns/edns.h>
+#include <dns/enumclass.h>
#include <dns/events.h>
#include <dns/message.h>
#include <dns/peer.h>
@@ -1937,7 +1938,9 @@ ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
}
}
- if (client->message->rdclass == 0) {
+ char classbuf[DNS_RDATACLASS_FORMATSIZE];
+ switch (client->message->rdclass) {
+ case dns_rdataclass_reserved0:
if ((client->attributes & NS_CLIENTATTR_WANTCOOKIE) != 0 &&
client->message->opcode == dns_opcode_query &&
client->message->counts[DNS_SECTION_QUESTION] == 0U)
@@ -1958,12 +1961,49 @@ ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
return;
}
+ ns_client_dumpmessage(client,
+ "message class could not be determined");
+ ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_FORMERR);
+ isc_task_unpause(client->task);
+ return;
+ case dns_rdataclass_in:
+ break;
+ case dns_rdataclass_chaos:
+ break;
+ case dns_rdataclass_hs:
+ break;
+ case dns_rdataclass_none:
+ if (client->message->opcode != dns_opcode_update) {
+ ns_client_dumpmessage(client,
+ "message class NONE can be only "
+ "used in DNS updates");
+ ns_client_error(client, DNS_R_FORMERR);
+ isc_task_unpause(client->task);
+ return;
+ }
+ break;
+ case dns_rdataclass_any:
+ /*
+ * Required for TKEY negotiation.
+ */
+ if (client->message->tkey == 0) {
+ ns_client_dumpmessage(client,
+ "message class ANY can be only "
+ "used for TKEY negotiation");
+ ns_client_error(client, DNS_R_FORMERR);
+ isc_task_unpause(client->task);
+ return;
+ }
+ break;
+ default:
+ dns_rdataclass_format(client->message->rdclass, classbuf,
+ sizeof(classbuf));
+ ns_client_dumpmessage(client, "");
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
- "message class could not be determined");
- ns_client_dumpmessage(client, "message class could not be "
- "determined");
- ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_FORMERR);
+ "invalid message class: %s", classbuf);
+
+ ns_client_error(client, DNS_R_NOTIMP);
isc_task_unpause(client->task);
return;
}
@@ -2017,7 +2057,7 @@ ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
ns_client_log(client, NS_LOGCATEGORY_CLIENT,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(1),
"no matching view in class '%s'", classname);
- ns_client_dumpmessage(client, "no matching view in class");
+ ns_client_dumpmessage(client, "");
ns_client_error(client, notimp ? DNS_R_NOTIMP : DNS_R_REFUSED);
isc_task_unpause(client->task);
return;
@@ -2201,6 +2241,10 @@ ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
break;
case dns_opcode_update:
CTRACE("update");
+ if (client->view->rdclass != dns_rdataclass_in) {
+ ns_client_error(client, DNS_R_NOTIMP);
+ break;
+ }
#ifdef HAVE_DNSTAP
dns_dt_send(client->view, DNS_DTTYPE_UQ, &client->peeraddr,
&client->destsockaddr, TCP_CLIENT(client), NULL,
@@ -2211,6 +2255,10 @@ ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
break;
case dns_opcode_notify:
CTRACE("notify");
+ if (client->view->rdclass != dns_rdataclass_in) {
+ ns_client_error(client, DNS_R_NOTIMP);
+ break;
+ }
ns_client_settimeout(client, 60);
ns_notify_start(client, handle);
break;
@@ -2302,7 +2350,7 @@ ns__client_setup(ns_client_t *client, ns_clientmgr_t *mgr, bool new) {
* The caller is responsible for that.
*/
- REQUIRE(NS_CLIENT_VALID(client) || (new &&client != NULL));
+ REQUIRE(NS_CLIENT_VALID(client) || (new && client != NULL));
REQUIRE(VALID_MANAGER(mgr) || !new);
if (new) {
@@ -2748,7 +2796,7 @@ ns_client_dumpmessage(ns_client_t *client, const char *reason) {
int len = 1024;
isc_result_t result;
- if (!isc_log_wouldlog(ns_lctx, ISC_LOG_DEBUG(1))) {
+ if (!isc_log_wouldlog(ns_lctx, ISC_LOG_DEBUG(1)) || reason == NULL) {
return;
}
diff --git a/lib/ns/update.c b/lib/ns/update.c
index 0e0bdc9..dc6ebdf 100644
--- a/lib/ns/update.c
+++ b/lib/ns/update.c
@@ -1288,7 +1288,10 @@ replaces_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {
return (true);
}
}
- if (db_rr->type == dns_rdatatype_wks) {
+
+ if (db_rr->rdclass == dns_rdataclass_in &&
+ db_rr->type == dns_rdatatype_wks)
+ {
/*
* Compare the address and protocol fields only. These
* form the first five bytes of the RR data. Do a
@@ -1432,8 +1435,7 @@ failure:
* 'rdata', and 'ttl', respectively.
*/
static void
-get_current_rr(dns_message_t *msg, dns_section_t section,
- dns_rdataclass_t zoneclass, dns_name_t **name,
+get_current_rr(dns_message_t *msg, dns_section_t section, dns_name_t **name,
dns_rdata_t *rdata, dns_rdatatype_t *covers, dns_ttl_t *ttl,
dns_rdataclass_t *update_class) {
dns_rdataset_t *rdataset;
@@ -1449,7 +1451,7 @@ get_current_rr(dns_message_t *msg, dns_section_t section,
dns_rdataset_current(rdataset, rdata);
INSIST(dns_rdataset_next(rdataset) == ISC_R_NOMORE);
*update_class = rdata->rdclass;
- rdata->rdclass = zoneclass;
+ rdata->rdclass = dns_rdataclass_in;
}
/*%
@@ -1551,7 +1553,6 @@ send_update_event(ns_client_t *client, dns_zone_t *zone) {
dns_message_t *request = client->message;
dns_aclenv_t *env =
ns_interfacemgr_getaclenv(client->manager->interface->mgr);
- dns_rdataclass_t zoneclass;
dns_rdatatype_t covers;
dns_name_t *zonename = NULL;
dns_db_t *db = NULL;
@@ -1559,10 +1560,12 @@ send_update_event(ns_client_t *client, dns_zone_t *zone) {
CHECK(dns_zone_getdb(zone, &db));
zonename = dns_db_origin(db);
- zoneclass = dns_db_class(db);
dns_zone_getssutable(zone, &ssutable);
dns_db_currentversion(db, &ver);
+ /* Updates are only supported for class IN. */
+ INSIST(dns_zone_getclass(zone) == dns_rdataclass_in);
+
/*
* Update message processing can leak record existence information
* so check that we are allowed to query this zone. Additionally,
@@ -1603,13 +1606,13 @@ send_update_event(ns_client_t *client, dns_zone_t *zone) {
dns_ttl_t ttl;
dns_rdataclass_t update_class;
- get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, &name,
+ get_current_rr(request, DNS_SECTION_UPDATE, &name,
&rdata, &covers, &ttl, &update_class);
if (!dns_name_issubdomain(name, zonename)) {
FAILC(DNS_R_NOTZONE, "update RR is outside zone");
}
- if (update_class == zoneclass) {
+ if (update_class == dns_rdataclass_in) {
/*
* Check for meta-RRs. The RFC2136 pseudocode says
* check for ANY|AXFR|MAILA|MAILB, but the text adds
@@ -2733,9 +2736,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
isc_mem_t *mctx = client->mctx;
dns_rdatatype_t covers;
dns_message_t *request = client->message;
- dns_rdataclass_t zoneclass;
dns_name_t *zonename = NULL;
- dns_ssutable_t *ssutable = NULL;
dns_fixedname_t tmpnamefixed;
dns_name_t *tmpname = NULL;
dns_zoneopt_t options;
@@ -2754,10 +2755,9 @@ update_action(isc_task_t *task, isc_event_t *event) {
CHECK(dns_zone_getdb(zone, &db));
zonename = dns_db_origin(db);
- zoneclass = dns_db_class(db);
- dns_zone_getssutable(zone, &ssutable);
options = dns_zone_getoptions(zone);
+ INSIST(dns_zone_getclass(zone) == dns_rdataclass_in);
/*
* Get old and new versions now that queryacl has been checked.
*/
@@ -2778,8 +2778,8 @@ update_action(isc_task_t *task, isc_event_t *event) {
dns_rdataclass_t update_class;
bool flag;
- get_current_rr(request, DNS_SECTION_PREREQUISITE, zoneclass,
- &name, &rdata, &covers, &ttl, &update_class);
+ get_current_rr(request, DNS_SECTION_PREREQUISITE, &name, &rdata,
+ &covers, &ttl, &update_class);
if (ttl != 0) {
PREREQFAILC(DNS_R_FORMERR, "prerequisite TTL is not "
@@ -2846,7 +2846,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
"satisfied");
}
}
- } else if (update_class == zoneclass) {
+ } else if (update_class == dns_rdataclass_in) {
/* "temp<rr.name, rr.type> += rr;" */
result = temp_append(&temp, name, &rdata);
if (result != ISC_R_SUCCESS) {
@@ -2906,10 +2906,10 @@ update_action(isc_task_t *task, isc_event_t *event) {
dns_rdataclass_t update_class;
bool flag;
- get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, &name,
+ get_current_rr(request, DNS_SECTION_UPDATE, &name,
&rdata, &covers, &ttl, &update_class);
- if (update_class == zoneclass) {
+ if (update_class == dns_rdataclass_in) {
/*
* RFC1123 doesn't allow MF and MD in master zones.
*/
@@ -3488,10 +3488,6 @@ common:
dns_db_detach(&db);
}
- if (ssutable != NULL) {
- dns_ssutable_detach(&ssutable);
- }
-
isc_task_detach(&task);
uev->result = result;
if (zone != NULL) {
--
2.54.0