import CS bind-9.16.50-5.el9

This commit is contained in:
AlmaLinux RelEng Bot 2026-08-24 08:53:18 -04:00
parent 9c3c5b566d
commit de21376227
67 changed files with 3817 additions and 9110 deletions

View File

@ -1 +1 @@
30cbd1f3e9d2d47d653498143334128aac1f8fc0 SOURCES/bind-9.16.23.tar.xz
a10542aaabad60bbbb8d19efd43591c98c01c277 SOURCES/bind-9.16.50.tar.xz

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/bind-9.16.23.tar.xz
SOURCES/bind-9.16.50.tar.xz

View File

@ -1,70 +0,0 @@
From e9e7069ede766fa5c881517bdae74e2fc6682398 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Wed, 30 Jan 2019 14:37:17 +0100
Subject: [PATCH] Create feature-test in source directory
Feature-test tool is used in system tests to test compiled in changes.
Because we build more variants of named with different configuration,
compile feature-test for each of them this way.
Make gsstsig test supported
---
bin/named/Makefile.in | 14 ++++++++++++--
bin/tests/system/conf.sh.in | 2 +-
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/bin/named/Makefile.in b/bin/named/Makefile.in
index debb906adc..dd894fe934 100644
--- a/bin/named/Makefile.in
+++ b/bin/named/Makefile.in
@@ -56,7 +56,7 @@ CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include -I. \
${LIBXML2_CFLAGS} \
${MAXMINDDB_CFLAGS}
-CDEFINES = @CONTRIB_DLZ@
+CDEFINES = @USE_GSSAPI@ @CONTRIB_DLZ@
CWARNINGS =
@@ -93,7 +93,7 @@ NOSYMLIBS = ${NSLIBS} ${DNSLIBS} ${BIND9LIBS} \
SUBDIRS = unix
-TARGETS = named@EXEEXT@
+TARGETS = named@EXEEXT@ feature-test@EXEEXT@
GEOIP2LINKOBJS = geoip.@O@
@@ -156,6 +156,16 @@ named@EXEEXT@: ${OBJS} ${DEPLIBS}
export BASEOBJS="${OBJS} ${UOBJS}"; \
${FINALBUILDCMD}
+# Bit of hack, do not produce intermediate .o object for featuretest
+feature-test.@O@: ${top_srcdir}/bin/tests/system/feature-test.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -c ${top_srcdir}/bin/tests/system/feature-test.c
+
+feature-test@EXEEXT@: feature-test.@O@
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} \
+ -o $@ feature-test.@O@ ${ISCLIBS} ${LIBS}
+
+
clean distclean maintainer-clean::
rm -f ${TARGETS} ${OBJS}
diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in
index 9a61622143..f69c5be334 100644
--- a/bin/tests/system/conf.sh.in
+++ b/bin/tests/system/conf.sh.in
@@ -38,7 +38,7 @@ DELV=$TOP/bin/delv/delv
DIG=$TOP/bin/dig/dig
DNSTAPREAD=$TOP/bin/tools/dnstap-read
DSFROMKEY=$TOP/bin/dnssec/dnssec-dsfromkey
-FEATURETEST=$TOP/bin/tests/system/feature-test
+FEATURETEST=$TOP/bin/named/feature-test
FSTRM_CAPTURE=@FSTRM_CAPTURE@
HOST=$TOP/bin/dig/host
IMPORTKEY=$TOP/bin/dnssec/dnssec-importkey
--
2.45.2

File diff suppressed because it is too large Load Diff

View File

@ -1,65 +0,0 @@
From 607cec78382b016aad0fe041f2e1895b6896c647 Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Fri, 1 Mar 2019 15:48:20 +0100
Subject: [PATCH] Make alternative named builds testable in system tests
Red Hat has alternative variant builds of named, which are not ever
tested by system tests. New variables make it relatively easy to test
alternative variants.
For sdb variant use:
export NAMED_VARIANT=-sdb DNSSEC_VARIANT=
For pkcs variant use:
export NAMED_VARIANT=-pkcs11 DNSSEC_VARIANT=-pkcs11
---
bin/tests/system/conf.sh.in | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in
index d859909..9152f07 100644
--- a/bin/tests/system/conf.sh.in
+++ b/bin/tests/system/conf.sh.in
@@ -37,17 +37,17 @@ DDNSCONFGEN=$TOP/bin/confgen/ddns-confgen
DELV=$TOP/bin/delv/delv
DIG=$TOP/bin/dig/dig
DNSTAPREAD=$TOP/bin/tools/dnstap-read
-DSFROMKEY=$TOP/bin/dnssec/dnssec-dsfromkey
-FEATURETEST=$TOP/bin/named/feature-test
+DSFROMKEY=$TOP/bin/dnssec${DNSSEC_VARIANT}/dnssec-dsfromkey${DNSSEC_VARIANT}
+FEATURETEST=$TOP/bin/named${NAMED_VARIANT}/feature-test${NAMED_VARIANT}
FSTRM_CAPTURE=@FSTRM_CAPTURE@
HOST=$TOP/bin/dig/host
-IMPORTKEY=$TOP/bin/dnssec/dnssec-importkey
+IMPORTKEY=$TOP/bin/dnssec${DNSSEC_VARIANT}/dnssec-importkey${DNSSEC_VARIANT}
JOURNALPRINT=$TOP/bin/tools/named-journalprint
-KEYFRLAB=$TOP/bin/dnssec/dnssec-keyfromlabel
-KEYGEN=$TOP/bin/dnssec/dnssec-keygen
+KEYFRLAB=$TOP/bin/dnssec${DNSSEC_VARIANT}/dnssec-keyfromlabel${DNSSEC_VARIANT}
+KEYGEN=$TOP/bin/dnssec${DNSSEC_VARIANT}/dnssec-keygen${DNSSEC_VARIANT}
KEYMGR=$TOP/bin/python/dnssec-keymgr
MDIG=$TOP/bin/tools/mdig
-NAMED=$TOP/bin/named/named
+NAMED=$TOP/bin/named${NAMED_VARIANT}/named${NAMED_VARIANT}
NSEC3HASH=$TOP/bin/tools/nsec3hash
NSLOOKUP=$TOP/bin/dig/nslookup
NSUPDATE=$TOP/bin/nsupdate/nsupdate
@@ -56,12 +56,12 @@ PK11DEL="$TOP/bin/pkcs11/pkcs11-destroy -s ${SLOT:-0} -p ${HSMPIN:-1234} -w 0"
PK11GEN="$TOP/bin/pkcs11/pkcs11-keygen -q -s ${SLOT:-0} -p ${HSMPIN:-1234}"
PK11LIST="$TOP/bin/pkcs11/pkcs11-list -s ${SLOT:-0} -p ${HSMPIN:-1234}"
RESOLVE=$TOP/bin/tests/system/resolve
-REVOKE=$TOP/bin/dnssec/dnssec-revoke
+REVOKE=$TOP/bin/dnssec${DNSSEC_VARIANT}/dnssec-revoke${DNSSEC_VARIANT}
RNDC=$TOP/bin/rndc/rndc
RNDCCONFGEN=$TOP/bin/confgen/rndc-confgen
RRCHECKER=$TOP/bin/tools/named-rrchecker
-SETTIME=$TOP/bin/dnssec/dnssec-settime
-SIGNER=$TOP/bin/dnssec/dnssec-signzone
+SETTIME=$TOP/bin/dnssec${DNSSEC_VARIANT}/dnssec-settime${DNSSEC_VARIANT}
+SIGNER=$TOP/bin/dnssec${DNSSEC_VARIANT}/dnssec-signzone${DNSSEC_VARIANT}
TSIGKEYGEN=$TOP/bin/confgen/tsig-keygen
VERIFY=$TOP/bin/dnssec/dnssec-verify
WIRETEST=$TOP/bin/tests/wire_test
--
2.26.3

File diff suppressed because it is too large Load Diff

View File

@ -1,251 +0,0 @@
From 5b2798e01346cd77741873091babf6c4a3128449 Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Wed, 19 Jan 2022 17:38:18 +1100
Subject: [PATCH] Add additional name checks when using a forwarder
When using a forwarder, check that the owner name of response
records are within the bailiwick of the forwarded name space.
(cherry picked from commit 24155213be59faad17f0215ecf73ea49ab781e5b)
Check that the forward declaration is unchanged and not overridden
If we are using a fowarder, in addition to checking that names to
be cached are subdomains of the forwarded namespace, we must also
check that there are no subsidiary forwarded namespaces which would
take precedence. To be safe, we don't cache any responses if the
forwarding configuration has changed since the query was sent.
(cherry picked from commit 3fc7accd88cd0890f8f57bb13765876774298ba3)
Check cached names for possible "forward only" clause
When caching additional and glue data *not* from a forwarder, we must
check that there is no "forward only" clause covering the owner name
that would take precedence. Such names would normally be allowed by
baliwick rules, but a "forward only" zone introduces a new baliwick
scope.
(cherry picked from commit ea06552a3d1fed56f7d3a13710e084ec79797b78)
Look for zones deeper than the current domain or forward name
When caching glue, we need to ensure that there is no closer
source of truth for the name. If the owner name for the glue
record would be answered by a locally configured zone, do not
cache.
(cherry picked from commit 71b24210542730355149130770deea3e58d8527a)
---
lib/dns/resolver.c | 128 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 123 insertions(+), 5 deletions(-)
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index a7bc661bb7..7603a07b7b 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -63,6 +63,8 @@
#include <dns/stats.h>
#include <dns/tsig.h>
#include <dns/validator.h>
+#include <dns/zone.h>
+
#ifdef WANT_QUERYTRACE
#define RTRACE(m) \
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, \
@@ -337,6 +339,8 @@ struct fetchctx {
dns_fetch_t *qminfetch;
dns_rdataset_t qminrrset;
dns_name_t qmindcname;
+ dns_fixedname_t fwdfname;
+ dns_name_t *fwdname;
/*%
* The number of events we're waiting for.
@@ -3764,6 +3768,7 @@ fctx_getaddresses(fetchctx_t *fctx, bool badcache) {
if (result == ISC_R_SUCCESS) {
fwd = ISC_LIST_HEAD(forwarders->fwdrs);
fctx->fwdpolicy = forwarders->fwdpolicy;
+ dns_name_copynf(domain, fctx->fwdname);
if (fctx->fwdpolicy == dns_fwdpolicy_only &&
isstrictsubdomain(domain, &fctx->domain))
{
@@ -5153,6 +5158,9 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
fctx->restarts = 0;
fctx->querysent = 0;
fctx->referrals = 0;
+
+ fctx->fwdname = dns_fixedname_initname(&fctx->fwdfname);
+
TIME_NOW(&fctx->start);
fctx->timeouts = 0;
fctx->lamecount = 0;
@@ -5215,6 +5223,7 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type,
fname, &forwarders);
if (result == ISC_R_SUCCESS) {
fctx->fwdpolicy = forwarders->fwdpolicy;
+ dns_name_copynf(fname, fctx->fwdname);
}
if (fctx->fwdpolicy != dns_fwdpolicy_only) {
@@ -7118,6 +7127,107 @@ mark_related(dns_name_t *name, dns_rdataset_t *rdataset, bool external,
}
}
+/*
+ * Returns true if 'name' is external to the namespace for which
+ * the server being queried can answer, either because it's not a
+ * subdomain or because it's below a forward declaration or a
+ * locally served zone.
+ */
+static inline bool
+name_external(const dns_name_t *name, dns_rdatatype_t type, fetchctx_t *fctx) {
+ isc_result_t result;
+ dns_forwarders_t *forwarders = NULL;
+ dns_fixedname_t fixed, zfixed;
+ dns_name_t *fname = dns_fixedname_initname(&fixed);
+ dns_name_t *zfname = dns_fixedname_initname(&zfixed);
+ dns_name_t *apex = NULL;
+ dns_name_t suffix;
+ dns_zone_t *zone = NULL;
+ unsigned int labels;
+ dns_namereln_t rel;
+
+ apex = ISFORWARDER(fctx->addrinfo) ? fctx->fwdname : &fctx->domain;
+
+ /*
+ * The name is outside the queried namespace.
+ */
+ rel = dns_name_fullcompare(name, apex, &(int){ 0 },
+ &(unsigned int){ 0U });
+ if (rel != dns_namereln_subdomain && rel != dns_namereln_equal) {
+ return (true);
+ }
+
+ /*
+ * If the record lives in the parent zone, adjust the name so we
+ * look for the correct zone or forward clause.
+ */
+ labels = dns_name_countlabels(name);
+ if (dns_rdatatype_atparent(type) && labels > 1U) {
+ dns_name_init(&suffix, NULL);
+ dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
+ name = &suffix;
+ } else if (rel == dns_namereln_equal) {
+ /* If 'name' is 'apex', no further checking is needed. */
+ return (false);
+ }
+
+ /*
+ * If there is a locally served zone between 'apex' and 'name'
+ * then don't cache.
+ */
+ LOCK(&fctx->res->view->lock);
+ if (fctx->res->view->zonetable != NULL) {
+ unsigned int options = DNS_ZTFIND_NOEXACT | DNS_ZTFIND_MIRROR;
+ result = dns_zt_find(fctx->res->view->zonetable, name, options,
+ zfname, &zone);
+ if (zone != NULL) {
+ dns_zone_detach(&zone);
+ }
+ if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
+ if (dns_name_fullcompare(zfname, apex, &(int){ 0 },
+ &(unsigned int){ 0U }) ==
+ dns_namereln_subdomain)
+ {
+ UNLOCK(&fctx->res->view->lock);
+ return (true);
+ }
+ }
+ }
+ UNLOCK(&fctx->res->view->lock);
+
+ /*
+ * Look for a forward declaration below 'name'.
+ */
+ result = dns_fwdtable_find(fctx->res->view->fwdtable, name, fname,
+ &forwarders);
+
+ if (ISFORWARDER(fctx->addrinfo)) {
+ /*
+ * See if the forwarder declaration is better.
+ */
+ if (result == ISC_R_SUCCESS) {
+ return (!dns_name_equal(fname, fctx->fwdname));
+ }
+
+ /*
+ * If the lookup failed, the configuration must have
+ * changed: play it safe and don't cache.
+ */
+ return (true);
+ } else if (result == ISC_R_SUCCESS &&
+ forwarders->fwdpolicy == dns_fwdpolicy_only &&
+ !ISC_LIST_EMPTY(forwarders->fwdrs))
+ {
+ /*
+ * If 'name' is covered by a 'forward only' clause then we
+ * can't cache this repsonse.
+ */
+ return (true);
+ }
+
+ return (false);
+}
+
static isc_result_t
check_section(void *arg, const dns_name_t *addname, dns_rdatatype_t type,
dns_section_t section) {
@@ -7144,7 +7254,7 @@ check_section(void *arg, const dns_name_t *addname, dns_rdatatype_t type,
result = dns_message_findname(rctx->query->rmessage, section, addname,
dns_rdatatype_any, 0, &name, NULL);
if (result == ISC_R_SUCCESS) {
- external = !dns_name_issubdomain(name, &fctx->domain);
+ external = name_external(name, type, fctx);
if (type == dns_rdatatype_a) {
for (rdataset = ISC_LIST_HEAD(name->list);
rdataset != NULL;
@@ -8768,6 +8878,13 @@ rctx_answer_scan(respctx_t *rctx) {
break;
case dns_namereln_subdomain:
+ /*
+ * Don't accept DNAME from parent namespace.
+ */
+ if (name_external(name, dns_rdatatype_dname, fctx)) {
+ continue;
+ }
+
/*
* In-scope DNAME records must have at least
* as many labels as the domain being queried.
@@ -9081,13 +9198,11 @@ rctx_authority_positive(respctx_t *rctx) {
DNS_SECTION_AUTHORITY);
while (!done && result == ISC_R_SUCCESS) {
dns_name_t *name = NULL;
- bool external;
dns_message_currentname(rctx->query->rmessage,
DNS_SECTION_AUTHORITY, &name);
- external = !dns_name_issubdomain(name, &fctx->domain);
- if (!external) {
+ if (!name_external(name, dns_rdatatype_ns, fctx)) {
dns_rdataset_t *rdataset = NULL;
/*
@@ -9474,7 +9589,10 @@ rctx_authority_dnssec(respctx_t *rctx) {
}
if (!dns_name_issubdomain(name, &fctx->domain)) {
- /* Invalid name found; preserve it for logging later */
+ /*
+ * Invalid name found; preserve it for logging
+ * later.
+ */
rctx->found_name = name;
rctx->found_type = ISC_LIST_HEAD(name->list)->type;
continue;
--
2.34.1

View File

@ -1,81 +0,0 @@
From 33064cd077cf6fa386f0a5a840c2161868da7b3a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Tue, 8 Feb 2022 12:42:34 +0100
Subject: [PATCH] Run .closehandle_cb asynchrounosly in nmhandle_detach_cb()
When sock->closehandle_cb is set, we need to run nmhandle_detach_cb()
asynchronously to ensure correct order of multiple packets processing in
the isc__nm_process_sock_buffer(). When not run asynchronously, it
would cause:
a) out-of-order processing of the return codes from processbuffer();
b) stack growth because the next TCP DNS message read callback will
be called from within the current TCP DNS message read callback.
The sock->closehandle_cb is set to isc__nm_resume_processing() for TCP
sockets which calls isc__nm_process_sock_buffer(). If the read callback
(called from isc__nm_process_sock_buffer()->processbuffer()) doesn't
attach to the nmhandle (f.e. because it wants to drop the processing or
we send the response directly via uv_try_write()), the
isc__nm_resume_processing() (via .closehandle_cb) would call
isc__nm_process_sock_buffer() recursively.
The below shortened code path shows how the stack can grow:
1: ns__client_request(handle, ...);
2: isc_nm_tcpdns_sequential(handle);
3: ns_query_start(client, handle);
4: query_lookup(qctx);
5: query_send(qctcx->client);
6: isc__nmhandle_detach(&client->reqhandle);
7: nmhandle_detach_cb(&handle);
8: sock->closehandle_cb(sock); // isc__nm_resume_processing
9: isc__nm_process_sock_buffer(sock);
10: processbuffer(sock); // isc__nm_tcpdns_processbuffer
11: isc_nmhandle_attach(req->handle, &handle);
12: isc__nm_readcb(sock, req, ISC_R_SUCCESS);
13: isc__nm_async_readcb(NULL, ...);
14: uvreq->cb.recv(...); // ns__client_request
Instead, if 'sock->closehandle_cb' is set, we need to run detach the
handle asynchroniously in 'isc__nmhandle_detach', so that on line 8 in
the code flow above does not start this recursion. This ensures the
correct order when processing multiple packets in the function
'isc__nm_process_sock_buffer()' and prevents the stack growth.
When not run asynchronously, the out-of-order processing leaves the
first TCP socket open until all requests on the stream have been
processed.
If the pipelining is disabled on the TCP via `keep-response-order`
configuration option, named would keep the first socket in lingering
CLOSE_WAIT state when the client sends an incomplete packet and then
closes the connection from the client side.
(cherry picked from commit afee2b5a7bc933a2d987907fc327a9f118fdbd17)
---
lib/isc/netmgr/netmgr.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c
index 3283eb6e4f..0ed3182fb6 100644
--- a/lib/isc/netmgr/netmgr.c
+++ b/lib/isc/netmgr/netmgr.c
@@ -1746,8 +1746,12 @@ isc__nmhandle_detach(isc_nmhandle_t **handlep FLARG) {
handle = *handlep;
*handlep = NULL;
+ /*
+ * If the closehandle_cb is set, it needs to run asynchronously to
+ * ensure correct ordering of the isc__nm_process_sock_buffer().
+ */
sock = handle->sock;
- if (sock->tid == isc_nm_tid()) {
+ if (sock->tid == isc_nm_tid() && sock->closehandle_cb == NULL) {
nmhandle_detach_cb(&handle FLARG_PASS);
} else {
isc__netievent_detach_t *event =
--
2.34.1

View File

@ -1,60 +0,0 @@
From bf2ea6d8525bfd96a84dad221ba9e004adb710a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= <michal@isc.org>
Date: Thu, 8 Sep 2022 11:11:30 +0200
Subject: [PATCH] Bound the amount of work performed for delegations
Limit the amount of database lookups that can be triggered in
fctx_getaddresses() (i.e. when determining the name server addresses to
query next) by setting a hard limit on the number of NS RRs processed
for any delegation encountered. Without any limit in place, named can
be forced to perform large amounts of database lookups per each query
received, which severely impacts resolver performance.
The limit used (20) is an arbitrary value that is considered to be big
enough for any sane DNS delegation.
(cherry picked from commit 3a44097fd6c6c260765b628cd1d2c9cb7efb0b2a)
---
lib/dns/resolver.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index d2cf14bbc8..73a0ee9f77 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -195,6 +195,12 @@
*/
#define NS_FAIL_LIMIT 4
#define NS_RR_LIMIT 5
+/*
+ * IP address lookups are performed for at most NS_PROCESSING_LIMIT NS RRs in
+ * any NS RRset encountered, to avoid excessive resource use while processing
+ * large delegations.
+ */
+#define NS_PROCESSING_LIMIT 20
/* Number of hash buckets for zone counters */
#ifndef RES_DOMAIN_BUCKETS
@@ -3711,6 +3717,7 @@ fctx_getaddresses(fetchctx_t *fctx, bool badcache) {
bool need_alternate = false;
bool all_spilled = true;
unsigned int no_addresses = 0;
+ unsigned int ns_processed = 0;
FCTXTRACE5("getaddresses", "fctx->depth=", fctx->depth);
@@ -3902,6 +3909,11 @@ normal_nses:
dns_rdata_reset(&rdata);
dns_rdata_freestruct(&ns);
+
+ if (++ns_processed >= NS_PROCESSING_LIMIT) {
+ result = ISC_R_NOMORE;
+ break;
+ }
}
if (result != ISC_R_NOMORE) {
return (result);
--
2.37.3

View File

@ -1,116 +0,0 @@
From 3bcd32572504ac9b92e3c6ec1e2cee3df3b68309 Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Tue, 20 Sep 2022 11:34:42 +0200
Subject: [PATCH 2/4] Fix CVE-2022-3080
5960. [security] Fix serve-stale crash that could happen when
stale-answer-client-timeout was set to 0 and there was
a stale CNAME in the cache for an incoming query.
(CVE-2022-3080) [GL #3517]
---
lib/ns/include/ns/query.h | 1 +
lib/ns/query.c | 42 ++++++++++++++++++++++++---------------
2 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/lib/ns/include/ns/query.h b/lib/ns/include/ns/query.h
index 4d48cf6..34b3070 100644
--- a/lib/ns/include/ns/query.h
+++ b/lib/ns/include/ns/query.h
@@ -145,6 +145,7 @@ struct query_ctx {
bool authoritative; /* authoritative query? */
bool want_restart; /* CNAME chain or other
* restart needed */
+ bool refresh_rrset; /* stale RRset refresh needed */
bool need_wildcardproof; /* wildcard proof needed */
bool nxrewrite; /* negative answer from RPZ */
bool findcoveringnsec; /* lookup covering NSEC */
diff --git a/lib/ns/query.c b/lib/ns/query.c
index 249321c..a450cb7 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -5686,7 +5686,6 @@ query_lookup(query_ctx_t *qctx) {
bool dbfind_stale = false;
bool stale_timeout = false;
bool stale_found = false;
- bool refresh_rrset = false;
bool stale_refresh_window = false;
CCTRACE(ISC_LOG_DEBUG(3), "query_lookup");
@@ -5868,8 +5867,7 @@ query_lookup(query_ctx_t *qctx) {
"%s stale answer used, an attempt to "
"refresh the RRset will still be made",
namebuf);
- refresh_rrset = STALE(qctx->rdataset);
- qctx->client->nodetach = refresh_rrset;
+ qctx->refresh_rrset = STALE(qctx->rdataset);
}
} else {
/*
@@ -5907,17 +5905,6 @@ query_lookup(query_ctx_t *qctx) {
result = query_gotanswer(qctx, result);
- if (refresh_rrset) {
- /*
- * If we reached this point then it means that we have found a
- * stale RRset entry in cache and BIND is configured to allow
- * queries to be answered with stale data if no active RRset
- * is available, i.e. "stale-anwer-client-timeout 0". But, we
- * still need to refresh the RRset.
- */
- query_refresh_rrset(qctx);
- }
-
cleanup:
return (result);
}
@@ -7737,11 +7724,14 @@ query_addanswer(query_ctx_t *qctx) {
/*
* On normal lookups, clear any rdatasets that were added on a
- * lookup due to stale-answer-client-timeout.
+ * lookup due to stale-answer-client-timeout. Do not clear if we
+ * are going to refresh the RRset, because the stale contents are
+ * prioritized.
*/
if (QUERY_STALEOK(&qctx->client->query) &&
- !QUERY_STALETIMEOUT(&qctx->client->query))
+ !QUERY_STALETIMEOUT(&qctx->client->query) && !qctx->refresh_rrset)
{
+ CCTRACE(ISC_LOG_DEBUG(3), "query_clear_stale");
query_clear_stale(qctx->client);
/*
* We can clear the attribute to prevent redundant clearing
@@ -11457,9 +11447,29 @@ ns_query_done(query_ctx_t *qctx) {
/*
* Client may have been detached after query_send(), so
* we test and store the flag state here, for safety.
+ * If we are refreshing the RRSet, we must not detach from the client
+ * in the query_send(), so we need to override the flag.
*/
+ if (qctx->refresh_rrset) {
+ qctx->client->nodetach = true;
+ }
nodetach = qctx->client->nodetach;
query_send(qctx->client);
+
+ if (qctx->refresh_rrset) {
+ /*
+ * If we reached this point then it means that we have found a
+ * stale RRset entry in cache and BIND is configured to allow
+ * queries to be answered with stale data if no active RRset
+ * is available, i.e. "stale-anwer-client-timeout 0". But, we
+ * still need to refresh the RRset. To prevent adding duplicate
+ * RRsets, clear the RRsets from the message before doing the
+ * refresh.
+ */
+ message_clearrdataset(qctx->client->message, 0);
+ query_refresh_rrset(qctx);
+ }
+
if (!nodetach) {
qctx->detach_client = true;
}
--
2.37.3

View File

@ -1,240 +0,0 @@
From 18036bb3f435eaa20d60093738c61e5da42a6cfe Mon Sep 17 00:00:00 2001
From: Evan Hunt <each@isc.org>
Date: Thu, 1 Sep 2022 16:05:04 -0700
Subject: [PATCH] add an update quota
limit the number of simultaneous DNS UPDATE events that can be
processed by adding a quota for update and update forwarding.
this quota currently, arbitrarily, defaults to 100.
also add a statistics counter to record when the update quota
has been exceeded.
(cherry picked from commit 7c47254a140c3e9cf383cda73c7b6a55c4782826)
---
bin/named/bind9.xsl | 4 +++-
bin/named/bind9.xsl.h | 6 +++++-
bin/named/statschannel.c | 5 +++--
doc/arm/reference.rst | 5 +++++
lib/ns/include/ns/server.h | 1 +
lib/ns/include/ns/stats.h | 4 +++-
lib/ns/server.c | 2 ++
lib/ns/update.c | 37 ++++++++++++++++++++++++++++++++++++-
8 files changed, 58 insertions(+), 6 deletions(-)
diff --git a/bin/named/bind9.xsl b/bin/named/bind9.xsl
index 5078115..194625b 100644
--- a/bin/named/bind9.xsl
+++ b/bin/named/bind9.xsl
@@ -12,7 +12,9 @@
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" version="1.0">
<xsl:output method="html" indent="yes" version="4.0"/>
- <xsl:template match="statistics[@version=&quot;3.11&quot;]">
+ <!-- the version number **below** must match version in bin/named/statschannel.c -->
+ <!-- don't forget to update "/xml/v<STATS_XML_VERSION_MAJOR>" in the HTTP endpoints listed below -->
+ <xsl:template match="statistics[@version=&quot;3.11.1&quot;]">
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
diff --git a/bin/named/bind9.xsl.h b/bin/named/bind9.xsl.h
index e30f7f5..b182742 100644
--- a/bin/named/bind9.xsl.h
+++ b/bin/named/bind9.xsl.h
@@ -20,7 +20,11 @@ static char xslmsg[] =
"<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" "
"xmlns=\"http://www.w3.org/1999/xhtml\" version=\"1.0\">\n"
" <xsl:output method=\"html\" indent=\"yes\" version=\"4.0\"/>\n"
- " <xsl:template match=\"statistics[@version=&quot;3.11&quot;]\">\n"
+ " <!-- the version number **below** must match version in "
+ "bin/named/statschannel.c -->\n"
+ " <!-- don't forget to update \"/xml/v<STATS_XML_VERSION_MAJOR>\" in "
+ "the HTTP endpoints listed below -->\n"
+ " <xsl:template match=\"statistics[@version=&quot;3.11.1&quot;]\">\n"
" <html>\n"
" <head>\n"
" <script type=\"text/javascript\" "
diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c
index 832ce93..7361ead 100644
--- a/bin/named/statschannel.c
+++ b/bin/named/statschannel.c
@@ -335,6 +335,7 @@ init_desc(void) {
SET_NSSTATDESC(reclimitdropped,
"queries dropped due to recursive client limit",
"RecLimitDropped");
+ SET_NSSTATDESC(updatequota, "Update quota exceeded", "UpdateQuota");
INSIST(i == ns_statscounter_max);
@@ -2007,7 +2008,7 @@ generatexml(named_server_t *server, uint32_t flags, int *buflen,
"href=\"/bind9.xsl\""));
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "statistics"));
TRY0(xmlTextWriterWriteAttribute(writer, ISC_XMLCHAR "version",
- ISC_XMLCHAR "3.11"));
+ ISC_XMLCHAR "3.11.1"));
/* Set common fields for statistics dump */
dumparg.type = isc_statsformat_xml;
@@ -2876,7 +2877,7 @@ generatejson(named_server_t *server, size_t *msglen, const char **msg,
/*
* These statistics are included no matter which URL we use.
*/
- obj = json_object_new_string("1.5");
+ obj = json_object_new_string("1.5.1");
CHECKMEM(obj);
json_object_object_add(bindstats, "json-stats-version", obj);
diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst
index 2d05aec..25c20d7 100644
--- a/doc/arm/reference.rst
+++ b/doc/arm/reference.rst
@@ -6705,6 +6705,11 @@ Name Server Statistics Counters
``UpdateBadPrereq``
This indicates the number of dynamic updates rejected due to a prerequisite failure.
+``UpdateQuota``
+ This indicates the number of times a dynamic update or update
+ forwarding request was rejected because the number of pending
+ requests exceeded the update quota.
+
``RateDropped``
This indicates the number of responses dropped due to rate limits.
diff --git a/lib/ns/include/ns/server.h b/lib/ns/include/ns/server.h
index 6a1f345..0abb579 100644
--- a/lib/ns/include/ns/server.h
+++ b/lib/ns/include/ns/server.h
@@ -84,6 +84,7 @@ struct ns_server {
isc_quota_t recursionquota;
isc_quota_t tcpquota;
isc_quota_t xfroutquota;
+ isc_quota_t updquota;
/*% Test options and other configurables */
uint32_t options;
diff --git a/lib/ns/include/ns/stats.h b/lib/ns/include/ns/stats.h
index 3c08799..95b15d0 100644
--- a/lib/ns/include/ns/stats.h
+++ b/lib/ns/include/ns/stats.h
@@ -106,7 +106,9 @@ enum {
ns_statscounter_reclimitdropped = 66,
- ns_statscounter_max = 67,
+ ns_statscounter_updatequota = 67,
+
+ ns_statscounter_max = 68,
};
void
diff --git a/lib/ns/server.c b/lib/ns/server.c
index a970a28..540bc2e 100644
--- a/lib/ns/server.c
+++ b/lib/ns/server.c
@@ -52,6 +52,7 @@ ns_server_create(isc_mem_t *mctx, ns_matchview_t matchingview,
isc_quota_init(&sctx->xfroutquota, 10);
isc_quota_init(&sctx->tcpquota, 10);
isc_quota_init(&sctx->recursionquota, 100);
+ isc_quota_init(&sctx->updquota, 100);
CHECKFATAL(dns_tkeyctx_create(mctx, &sctx->tkeyctx));
@@ -131,6 +132,7 @@ ns_server_detach(ns_server_t **sctxp) {
isc_mem_put(sctx->mctx, altsecret, sizeof(*altsecret));
}
+ isc_quota_destroy(&sctx->updquota);
isc_quota_destroy(&sctx->recursionquota);
isc_quota_destroy(&sctx->tcpquota);
isc_quota_destroy(&sctx->xfroutquota);
diff --git a/lib/ns/update.c b/lib/ns/update.c
index 546b70a..1871438 100644
--- a/lib/ns/update.c
+++ b/lib/ns/update.c
@@ -1544,6 +1544,19 @@ send_update_event(ns_client_t *client, dns_zone_t *zone) {
update_event_t *event = NULL;
isc_task_t *zonetask = NULL;
+ result = isc_quota_attach(&client->manager->sctx->updquota,
+ &(isc_quota_t *){ NULL });
+ if (result != ISC_R_SUCCESS) {
+ update_log(client, zone, LOGLEVEL_PROTOCOL,
+ "update failed: too many DNS UPDATEs queued (%s)",
+ isc_result_totext(result));
+ ns_stats_increment(client->manager->sctx->nsstats,
+ ns_statscounter_updatequota);
+ ns_client_drop(client, result);
+ isc_nmhandle_detach(&client->reqhandle);
+ return (DNS_R_DROP);
+ }
+
event = (update_event_t *)isc_event_allocate(
client->mctx, client, DNS_EVENT_UPDATE, update_action, NULL,
sizeof(*event));
@@ -1676,12 +1689,18 @@ failure:
dns_zone_gettype(zone) == dns_zone_mirror);
inc_stats(client, zone, ns_statscounter_updaterej);
}
+
/*
* We failed without having sent an update event to the zone.
* We are still in the client task context, so we can
* simply give an error response without switching tasks.
*/
- respond(client, result);
+ if (result == DNS_R_DROP) {
+ ns_client_drop(client, result);
+ } else {
+ respond(client, result);
+ }
+
if (zone != NULL) {
dns_zone_detach(&zone);
}
@@ -3489,6 +3508,7 @@ updatedone_action(isc_task_t *task, isc_event_t *event) {
respond(client, uev->result);
+ isc_quota_detach(&(isc_quota_t *){ &client->manager->sctx->updquota });
isc_event_free(&event);
isc_nmhandle_detach(&client->updatehandle);
}
@@ -3505,6 +3525,8 @@ forward_fail(isc_task_t *task, isc_event_t *event) {
INSIST(client->nupdates > 0);
client->nupdates--;
respond(client, DNS_R_SERVFAIL);
+
+ isc_quota_detach(&(isc_quota_t *){ &client->manager->sctx->updquota });
isc_event_free(&event);
isc_nmhandle_detach(&client->updatehandle);
}
@@ -3542,6 +3564,8 @@ forward_done(isc_task_t *task, isc_event_t *event) {
client->nupdates--;
ns_client_sendraw(client, uev->answer);
dns_message_detach(&uev->answer);
+
+ isc_quota_detach(&(isc_quota_t *){ &client->manager->sctx->updquota });
isc_event_free(&event);
isc_nmhandle_detach(&client->updatehandle);
}
@@ -3576,6 +3600,17 @@ send_forward_event(ns_client_t *client, dns_zone_t *zone) {
update_event_t *event = NULL;
isc_task_t *zonetask = NULL;
+ result = isc_quota_attach(&client->manager->sctx->updquota,
+ &(isc_quota_t *){ NULL });
+ if (result != ISC_R_SUCCESS) {
+ update_log(client, zone, LOGLEVEL_PROTOCOL,
+ "update failed: too many DNS UPDATEs queued (%s)",
+ isc_result_totext(result));
+ ns_stats_increment(client->manager->sctx->nsstats,
+ ns_statscounter_updatequota);
+ return (DNS_R_DROP);
+ }
+
event = (update_event_t *)isc_event_allocate(
client->mctx, client, DNS_EVENT_UPDATE, forward_action, NULL,
sizeof(*event));
--
2.39.2

View File

@ -1,266 +0,0 @@
From 7fe2204a2e8952bf892e4a70fea2ef5167e1f509 Mon Sep 17 00:00:00 2001
From: Evan Hunt <each@isc.org>
Date: Thu, 1 Sep 2022 16:22:46 -0700
Subject: [PATCH] add a configuration option for the update quota
add an "update-quota" option to configure the update quota.
(cherry picked from commit f57758a7303ad0034ff2ff08eaaf2ef899630f19)
---
bin/named/config.c | 1 +
bin/named/named.conf.rst | 9 +++++----
bin/named/server.c | 1 +
bin/tests/system/checkconf/good.conf | 1 +
doc/arm/reference.rst | 7 ++++++-
doc/man/named.conf.5in | 9 +++++----
doc/misc/master.zoneopt.rst | 2 +-
doc/misc/options | 1 +
doc/misc/options.active | 1 +
doc/misc/options.grammar.rst | 3 ++-
doc/misc/slave.zoneopt.rst | 2 +-
lib/isccfg/namedconf.c | 1 +
12 files changed, 26 insertions(+), 12 deletions(-)
diff --git a/bin/named/config.c b/bin/named/config.c
index 5fedee84d9..494147015f 100644
--- a/bin/named/config.c
+++ b/bin/named/config.c
@@ -130,6 +130,7 @@ options {\n\
transfers-out 10;\n\
transfers-per-ns 2;\n\
trust-anchor-telemetry yes;\n\
+ update-quota 100;\n\
\n\
/* view */\n\
allow-new-zones no;\n\
diff --git a/bin/named/named.conf.rst b/bin/named/named.conf.rst
index 27eed5ca3e..4c9f9a7370 100644
--- a/bin/named/named.conf.rst
+++ b/bin/named/named.conf.rst
@@ -179,7 +179,7 @@ OPTIONS
answer-cookie boolean;
attach-cache string;
auth-nxdomain boolean; // default changed
- auto-dnssec ( allow | maintain | off );
+ auto-dnssec ( allow | maintain | off );// deprecated
automatic-interface-scan boolean;
avoid-v4-udp-ports { portrange; ... };
avoid-v6-udp-ports { portrange; ... };
@@ -446,6 +446,7 @@ OPTIONS
trust-anchor-telemetry boolean; // experimental
try-tcp-refresh boolean;
update-check-ksk boolean;
+ update-quota integer;
use-alt-transfer-source boolean;
use-v4-udp-ports { portrange; ... };
use-v6-udp-ports { portrange; ... };
@@ -584,7 +585,7 @@ VIEW
* ) ] [ dscp integer ];
attach-cache string;
auth-nxdomain boolean; // default changed
- auto-dnssec ( allow | maintain | off );
+ auto-dnssec ( allow | maintain | off );// deprecated
cache-file quoted_string;// deprecated
catalog-zones { zone string [ default-masters [ port integer ]
[ dscp integer ] { ( remote-servers | ipv4_address [ port
@@ -859,7 +860,7 @@ VIEW
integer | * ) ] [ dscp integer ];
alt-transfer-source-v6 ( ipv6_address | * ) [ port (
integer | * ) ] [ dscp integer ];
- auto-dnssec ( allow | maintain | off );
+ auto-dnssec ( allow | maintain | off );// deprecated
check-dup-records ( fail | warn | ignore );
check-integrity boolean;
check-mx ( fail | warn | ignore );
@@ -977,7 +978,7 @@ ZONE
] [ dscp integer ];
alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer |
* ) ] [ dscp integer ];
- auto-dnssec ( allow | maintain | off );
+ auto-dnssec ( allow | maintain | off );// deprecated
check-dup-records ( fail | warn | ignore );
check-integrity boolean;
check-mx ( fail | warn | ignore );
diff --git a/bin/named/server.c b/bin/named/server.c
index 20443ff8a9..78a21d62a2 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -8542,6 +8542,7 @@ load_configuration(const char *filename, named_server_t *server,
configure_server_quota(maps, "tcp-clients", &server->sctx->tcpquota);
configure_server_quota(maps, "recursive-clients",
&server->sctx->recursionquota);
+ configure_server_quota(maps, "update-quota", &server->sctx->updquota);
max = isc_quota_getmax(&server->sctx->recursionquota);
if (max > 1000) {
diff --git a/bin/tests/system/checkconf/good.conf b/bin/tests/system/checkconf/good.conf
index b1f7059acf..0ecdb68e95 100644
--- a/bin/tests/system/checkconf/good.conf
+++ b/bin/tests/system/checkconf/good.conf
@@ -75,6 +75,7 @@ options {
recursive-clients 3000;
serial-query-rate 100;
server-id none;
+ update-quota 200;
check-names primary warn;
check-names secondary ignore;
max-cache-size 20000000000000;
diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst
index 2603d60251..703663d0ba 100644
--- a/doc/arm/reference.rst
+++ b/doc/arm/reference.rst
@@ -3151,6 +3151,11 @@ system.
value as ``tcp-keepalive-timeout``. This value can be updated at
runtime by using ``rndc tcp-timeouts``.
+``update-quota``
+ This is the maximum number of simultaneous DNS UPDATE messages that
+ the server will accept for updating local authoritiative zones or
+ forwarding to a primary server. The default is ``100``.
+
.. _intervals:
Periodic Task Intervals
@@ -6840,7 +6845,7 @@ Name Server Statistics Counters
``UpdateQuota``
This indicates the number of times a dynamic update or update
forwarding request was rejected because the number of pending
- requests exceeded the update quota.
+ requests exceeded ``update-quota``.
``RateDropped``
This indicates the number of responses dropped due to rate limits.
diff --git a/doc/man/named.conf.5in b/doc/man/named.conf.5in
index 4c46f47592..c87afa2881 100644
--- a/doc/man/named.conf.5in
+++ b/doc/man/named.conf.5in
@@ -231,7 +231,7 @@ options {
answer\-cookie boolean;
attach\-cache string;
auth\-nxdomain boolean; // default changed
- auto\-dnssec ( allow | maintain | off );
+ auto\-dnssec ( allow | maintain | off );// deprecated
automatic\-interface\-scan boolean;
avoid\-v4\-udp\-ports { portrange; ... };
avoid\-v6\-udp\-ports { portrange; ... };
@@ -498,6 +498,7 @@ options {
trust\-anchor\-telemetry boolean; // experimental
try\-tcp\-refresh boolean;
update\-check\-ksk boolean;
+ update\-quota integer;
use\-alt\-transfer\-source boolean;
use\-v4\-udp\-ports { portrange; ... };
use\-v6\-udp\-ports { portrange; ... };
@@ -668,7 +669,7 @@ view string [ class ] {
* ) ] [ dscp integer ];
attach\-cache string;
auth\-nxdomain boolean; // default changed
- auto\-dnssec ( allow | maintain | off );
+ auto\-dnssec ( allow | maintain | off );// deprecated
cache\-file quoted_string;// deprecated
catalog\-zones { zone string [ default\-masters [ port integer ]
[ dscp integer ] { ( remote\-servers | ipv4_address [ port
@@ -943,7 +944,7 @@ view string [ class ] {
integer | * ) ] [ dscp integer ];
alt\-transfer\-source\-v6 ( ipv6_address | * ) [ port (
integer | * ) ] [ dscp integer ];
- auto\-dnssec ( allow | maintain | off );
+ auto\-dnssec ( allow | maintain | off );// deprecated
check\-dup\-records ( fail | warn | ignore );
check\-integrity boolean;
check\-mx ( fail | warn | ignore );
@@ -1065,7 +1066,7 @@ zone string [ class ] {
] [ dscp integer ];
alt\-transfer\-source\-v6 ( ipv6_address | * ) [ port ( integer |
* ) ] [ dscp integer ];
- auto\-dnssec ( allow | maintain | off );
+ auto\-dnssec ( allow | maintain | off );// deprecated
check\-dup\-records ( fail | warn | ignore );
check\-integrity boolean;
check\-mx ( fail | warn | ignore );
diff --git a/doc/misc/master.zoneopt.rst b/doc/misc/master.zoneopt.rst
index 8fc7e1b4f0..346d59813e 100644
--- a/doc/misc/master.zoneopt.rst
+++ b/doc/misc/master.zoneopt.rst
@@ -20,7 +20,7 @@
also-notify [ port <integer> ] [ dscp <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
- auto-dnssec ( allow | maintain | off );
+ auto-dnssec ( allow | maintain | off ); // deprecated
check-dup-records ( fail | warn | ignore );
check-integrity <boolean>;
check-mx ( fail | warn | ignore );
diff --git a/doc/misc/options b/doc/misc/options
index f57399499a..0dbcf101e1 100644
--- a/doc/misc/options
+++ b/doc/misc/options
@@ -404,6 +404,7 @@ options {
trust-anchor-telemetry <boolean>; // experimental
try-tcp-refresh <boolean>;
update-check-ksk <boolean>;
+ update-quota <integer>;
use-alt-transfer-source <boolean>;
use-id-pool <boolean>; // ancient
use-ixfr <boolean>; // obsolete
diff --git a/doc/misc/options.active b/doc/misc/options.active
index 5fc1ab29f4..eb75a86eae 100644
--- a/doc/misc/options.active
+++ b/doc/misc/options.active
@@ -363,6 +363,7 @@ options {
trust-anchor-telemetry <boolean>; // experimental
try-tcp-refresh <boolean>;
update-check-ksk <boolean>;
+ update-quota <integer>;
use-alt-transfer-source <boolean>;
use-v4-udp-ports { <portrange>; ... };
use-v6-udp-ports { <portrange>; ... };
diff --git a/doc/misc/options.grammar.rst b/doc/misc/options.grammar.rst
index 438072c95c..beef35341a 100644
--- a/doc/misc/options.grammar.rst
+++ b/doc/misc/options.grammar.rst
@@ -33,7 +33,7 @@
answer-cookie <boolean>;
attach-cache <string>;
auth-nxdomain <boolean>; // default changed
- auto-dnssec ( allow | maintain | off );
+ auto-dnssec ( allow | maintain | off ); // deprecated
automatic-interface-scan <boolean>;
avoid-v4-udp-ports { <portrange>; ... };
avoid-v6-udp-ports { <portrange>; ... };
@@ -300,6 +300,7 @@
trust-anchor-telemetry <boolean>; // experimental
try-tcp-refresh <boolean>;
update-check-ksk <boolean>;
+ update-quota <integer>;
use-alt-transfer-source <boolean>;
use-v4-udp-ports { <portrange>; ... };
use-v6-udp-ports { <portrange>; ... };
diff --git a/doc/misc/slave.zoneopt.rst b/doc/misc/slave.zoneopt.rst
index cc72dcbf67..468a7f4d9a 100644
--- a/doc/misc/slave.zoneopt.rst
+++ b/doc/misc/slave.zoneopt.rst
@@ -21,7 +21,7 @@
also-notify [ port <integer> ] [ dscp <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
alt-transfer-source ( <ipv4_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
alt-transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
- auto-dnssec ( allow | maintain | off );
+ auto-dnssec ( allow | maintain | off ); // deprecated
check-names ( fail | warn | ignore );
database <string>;
dialup ( notify | notify-passive | passive | refresh | <boolean> );
diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c
index 45de0196bf..6e63d86816 100644
--- a/lib/isccfg/namedconf.c
+++ b/lib/isccfg/namedconf.c
@@ -1267,6 +1267,7 @@ static cfg_clausedef_t options_clauses[] = {
{ "transfers-out", &cfg_type_uint32, 0 },
{ "transfers-per-ns", &cfg_type_uint32, 0 },
{ "treat-cr-as-space", &cfg_type_boolean, CFG_CLAUSEFLAG_ANCIENT },
+ { "update-quota", &cfg_type_uint32, 0 },
{ "use-id-pool", &cfg_type_boolean, CFG_CLAUSEFLAG_ANCIENT },
{ "use-ixfr", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
{ "use-v4-udp-ports", &cfg_type_bracketed_portlist, 0 },
--
2.39.1

View File

@ -1,470 +0,0 @@
From 93b8bd39145566053ad8b22cef597146e9175ea4 Mon Sep 17 00:00:00 2001
From: Evan Hunt <each@isc.org>
Date: Tue, 8 Nov 2022 17:32:41 -0800
Subject: [PATCH] move update ACL and update-policy checks before quota
check allow-update, update-policy, and allow-update-forwarding before
consuming quota slots, so that unauthorized clients can't fill the
quota.
(this moves the access check before the prerequisite check, which
violates the precise wording of RFC 2136. however, RFC co-author Paul
Vixie has stated that the RFC is mistaken on this point; it should have
said that access checking must happen *no later than* the completion of
prerequisite checks, not that it must happen exactly then.)
(cherry picked from commit 964f559edb5036880b8e463b8f190b9007ee055d)
---
lib/ns/update.c | 335 ++++++++++++++++++++++++++----------------------
1 file changed, 181 insertions(+), 154 deletions(-)
diff --git a/lib/ns/update.c b/lib/ns/update.c
index 9a8c309..036184b 100644
--- a/lib/ns/update.c
+++ b/lib/ns/update.c
@@ -261,6 +261,9 @@ static void
forward_done(isc_task_t *task, isc_event_t *event);
static isc_result_t
add_rr_prepare_action(void *data, rr_t *rr);
+static isc_result_t
+rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
+ const dns_rdata_t *rdata, bool *flag);
/**************************************************************************/
@@ -333,25 +336,26 @@ inc_stats(ns_client_t *client, dns_zone_t *zone, isc_statscounter_t counter) {
static isc_result_t
checkqueryacl(ns_client_t *client, dns_acl_t *queryacl, dns_name_t *zonename,
dns_acl_t *updateacl, dns_ssutable_t *ssutable) {
+ isc_result_t result;
char namebuf[DNS_NAME_FORMATSIZE];
char classbuf[DNS_RDATACLASS_FORMATSIZE];
- int level;
- isc_result_t result;
+ bool update_possible =
+ ((updateacl != NULL && !dns_acl_isnone(updateacl)) ||
+ ssutable != NULL);
result = ns_client_checkaclsilent(client, NULL, queryacl, true);
if (result != ISC_R_SUCCESS) {
+ int level = update_possible ? ISC_LOG_ERROR : ISC_LOG_INFO;
+
dns_name_format(zonename, namebuf, sizeof(namebuf));
dns_rdataclass_format(client->view->rdclass, classbuf,
sizeof(classbuf));
- level = (updateacl == NULL && ssutable == NULL) ? ISC_LOG_INFO
- : ISC_LOG_ERROR;
-
ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY,
NS_LOGMODULE_UPDATE, level,
"update '%s/%s' denied due to allow-query",
namebuf, classbuf);
- } else if (updateacl == NULL && ssutable == NULL) {
+ } else if (!update_possible) {
dns_name_format(zonename, namebuf, sizeof(namebuf));
dns_rdataclass_format(client->view->rdclass, classbuf,
sizeof(classbuf));
@@ -1543,6 +1547,156 @@ send_update_event(ns_client_t *client, dns_zone_t *zone) {
isc_result_t result = ISC_R_SUCCESS;
update_event_t *event = NULL;
isc_task_t *zonetask = NULL;
+ dns_ssutable_t *ssutable = NULL;
+ 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;
+ dns_dbversion_t *ver = NULL;
+
+ 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);
+
+ /*
+ * Update message processing can leak record existence information
+ * so check that we are allowed to query this zone. Additionally,
+ * if we would refuse all updates for this zone, we bail out here.
+ */
+ CHECK(checkqueryacl(client, dns_zone_getqueryacl(zone),
+ dns_zone_getorigin(zone),
+ dns_zone_getupdateacl(zone), ssutable));
+
+ /*
+ * Check requestor's permissions.
+ */
+ if (ssutable == NULL) {
+ CHECK(checkupdateacl(client, dns_zone_getupdateacl(zone),
+ "update", dns_zone_getorigin(zone), false,
+ false));
+ } else if (client->signer == NULL && !TCPCLIENT(client)) {
+ CHECK(checkupdateacl(client, NULL, "update",
+ dns_zone_getorigin(zone), false, true));
+ }
+
+ if (dns_zone_getupdatedisabled(zone)) {
+ FAILC(DNS_R_REFUSED, "dynamic update temporarily disabled "
+ "because the zone is frozen. Use "
+ "'rndc thaw' to re-enable updates.");
+ }
+
+ /*
+ * Prescan the update section, checking for updates that
+ * are illegal or violate policy.
+ */
+ for (result = dns_message_firstname(request, DNS_SECTION_UPDATE);
+ result == ISC_R_SUCCESS;
+ result = dns_message_nextname(request, DNS_SECTION_UPDATE))
+ {
+ dns_name_t *name = NULL;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_ttl_t ttl;
+ dns_rdataclass_t update_class;
+
+ get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, &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) {
+ /*
+ * Check for meta-RRs. The RFC2136 pseudocode says
+ * check for ANY|AXFR|MAILA|MAILB, but the text adds
+ * "or any other QUERY metatype"
+ */
+ if (dns_rdatatype_ismeta(rdata.type)) {
+ FAILC(DNS_R_FORMERR, "meta-RR in update");
+ }
+ result = dns_zone_checknames(zone, name, &rdata);
+ if (result != ISC_R_SUCCESS) {
+ FAIL(DNS_R_REFUSED);
+ }
+ } else if (update_class == dns_rdataclass_any) {
+ if (ttl != 0 || rdata.length != 0 ||
+ (dns_rdatatype_ismeta(rdata.type) &&
+ rdata.type != dns_rdatatype_any))
+ {
+ FAILC(DNS_R_FORMERR, "meta-RR in update");
+ }
+ } else if (update_class == dns_rdataclass_none) {
+ if (ttl != 0 || dns_rdatatype_ismeta(rdata.type)) {
+ FAILC(DNS_R_FORMERR, "meta-RR in update");
+ }
+ } else {
+ update_log(client, zone, ISC_LOG_WARNING,
+ "update RR has incorrect class %d",
+ update_class);
+ FAIL(DNS_R_FORMERR);
+ }
+
+ /*
+ * draft-ietf-dnsind-simple-secure-update-01 says
+ * "Unlike traditional dynamic update, the client
+ * is forbidden from updating NSEC records."
+ */
+ if (rdata.type == dns_rdatatype_nsec3) {
+ FAILC(DNS_R_REFUSED, "explicit NSEC3 updates are not "
+ "allowed "
+ "in secure zones");
+ } else if (rdata.type == dns_rdatatype_nsec) {
+ FAILC(DNS_R_REFUSED, "explicit NSEC updates are not "
+ "allowed "
+ "in secure zones");
+ } else if (rdata.type == dns_rdatatype_rrsig &&
+ !dns_name_equal(name, zonename))
+ {
+ FAILC(DNS_R_REFUSED, "explicit RRSIG updates are "
+ "currently "
+ "not supported in secure zones "
+ "except "
+ "at the apex");
+ }
+
+ if (ssutable != NULL) {
+ isc_netaddr_t netaddr;
+ dst_key_t *tsigkey = NULL;
+ isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
+
+ if (client->message->tsigkey != NULL) {
+ tsigkey = client->message->tsigkey->key;
+ }
+
+ if (rdata.type != dns_rdatatype_any) {
+ if (!dns_ssutable_checkrules(
+ ssutable, client->signer, name,
+ &netaddr, TCPCLIENT(client), env,
+ rdata.type, tsigkey))
+ {
+ FAILC(DNS_R_REFUSED, "rejected by "
+ "secure update");
+ }
+ } else {
+ if (!ssu_checkall(db, ver, name, ssutable,
+ client->signer, &netaddr, env,
+ TCPCLIENT(client), tsigkey))
+ {
+ FAILC(DNS_R_REFUSED, "rejected by "
+ "secure update");
+ }
+ }
+ }
+ }
+ if (result != ISC_R_NOMORE) {
+ FAIL(result);
+ }
+
+ update_log(client, zone, LOGLEVEL_DEBUG, "update section prescan OK");
result = isc_quota_attach(&client->manager->sctx->updquota,
&(isc_quota_t *){ NULL });
@@ -1552,9 +1706,7 @@ send_update_event(ns_client_t *client, dns_zone_t *zone) {
isc_result_totext(result));
ns_stats_increment(client->manager->sctx->nsstats,
ns_statscounter_updatequota);
- ns_client_drop(client, result);
- isc_nmhandle_detach(&client->reqhandle);
- return (DNS_R_DROP);
+ CHECK(DNS_R_DROP);
}
event = (update_event_t *)isc_event_allocate(
@@ -1571,6 +1723,16 @@ send_update_event(ns_client_t *client, dns_zone_t *zone) {
dns_zone_gettask(zone, &zonetask);
isc_task_send(zonetask, ISC_EVENT_PTR(&event));
+failure:
+ if (db != NULL) {
+ dns_db_closeversion(db, &ver, false);
+ dns_db_detach(&db);
+ }
+
+ if (ssutable != NULL) {
+ dns_ssutable_detach(&ssutable);
+ }
+
return (result);
}
@@ -1671,9 +1833,6 @@ ns_update_start(ns_client_t *client, isc_nmhandle_t *handle,
break;
case dns_zone_secondary:
case dns_zone_mirror:
- CHECK(checkupdateacl(client, dns_zone_getforwardacl(zone),
- "update forwarding", zonename, true,
- false));
CHECK(send_forward_event(client, zone));
break;
default:
@@ -1685,8 +1844,6 @@ ns_update_start(ns_client_t *client, isc_nmhandle_t *handle,
failure:
if (result == DNS_R_REFUSED) {
- INSIST(dns_zone_gettype(zone) == dns_zone_secondary ||
- dns_zone_gettype(zone) == dns_zone_mirror);
inc_stats(client, zone, ns_statscounter_updaterej);
}
@@ -2578,7 +2735,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
dns_rdatatype_t covers;
dns_message_t *request = client->message;
dns_rdataclass_t zoneclass;
- dns_name_t *zonename;
+ dns_name_t *zonename = NULL;
dns_ssutable_t *ssutable = NULL;
dns_fixedname_t tmpnamefixed;
dns_name_t *tmpname = NULL;
@@ -2590,8 +2747,6 @@ update_action(isc_task_t *task, isc_event_t *event) {
dns_ttl_t maxttl = 0;
uint32_t maxrecords;
uint64_t records;
- dns_aclenv_t *env =
- ns_interfacemgr_getaclenv(client->manager->interface->mgr);
INSIST(event->ev_type == DNS_EVENT_UPDATE);
@@ -2602,14 +2757,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
zonename = dns_db_origin(db);
zoneclass = dns_db_class(db);
dns_zone_getssutable(zone, &ssutable);
-
- /*
- * Update message processing can leak record existence information
- * so check that we are allowed to query this zone. Additionally
- * if we would refuse all updates for this zone we bail out here.
- */
- CHECK(checkqueryacl(client, dns_zone_getqueryacl(zone), zonename,
- dns_zone_getupdateacl(zone), ssutable));
+ options = dns_zone_getoptions(zone);
/*
* Get old and new versions now that queryacl has been checked.
@@ -2745,135 +2893,10 @@ update_action(isc_task_t *task, isc_event_t *event) {
update_log(client, zone, LOGLEVEL_DEBUG, "prerequisites are OK");
- /*
- * Check Requestor's Permissions. It seems a bit silly to do this
- * only after prerequisite testing, but that is what RFC2136 says.
- */
- if (ssutable == NULL) {
- CHECK(checkupdateacl(client, dns_zone_getupdateacl(zone),
- "update", zonename, false, false));
- } else if (client->signer == NULL && !TCPCLIENT(client)) {
- CHECK(checkupdateacl(client, NULL, "update", zonename, false,
- true));
- }
-
- if (dns_zone_getupdatedisabled(zone)) {
- FAILC(DNS_R_REFUSED, "dynamic update temporarily disabled "
- "because the zone is frozen. Use "
- "'rndc thaw' to re-enable updates.");
- }
-
- /*
- * Perform the Update Section Prescan.
- */
-
- for (result = dns_message_firstname(request, DNS_SECTION_UPDATE);
- result == ISC_R_SUCCESS;
- result = dns_message_nextname(request, DNS_SECTION_UPDATE))
- {
- dns_name_t *name = NULL;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_ttl_t ttl;
- dns_rdataclass_t update_class;
- get_current_rr(request, DNS_SECTION_UPDATE, zoneclass, &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) {
- /*
- * Check for meta-RRs. The RFC2136 pseudocode says
- * check for ANY|AXFR|MAILA|MAILB, but the text adds
- * "or any other QUERY metatype"
- */
- if (dns_rdatatype_ismeta(rdata.type)) {
- FAILC(DNS_R_FORMERR, "meta-RR in update");
- }
- result = dns_zone_checknames(zone, name, &rdata);
- if (result != ISC_R_SUCCESS) {
- FAIL(DNS_R_REFUSED);
- }
- } else if (update_class == dns_rdataclass_any) {
- if (ttl != 0 || rdata.length != 0 ||
- (dns_rdatatype_ismeta(rdata.type) &&
- rdata.type != dns_rdatatype_any))
- {
- FAILC(DNS_R_FORMERR, "meta-RR in update");
- }
- } else if (update_class == dns_rdataclass_none) {
- if (ttl != 0 || dns_rdatatype_ismeta(rdata.type)) {
- FAILC(DNS_R_FORMERR, "meta-RR in update");
- }
- } else {
- update_log(client, zone, ISC_LOG_WARNING,
- "update RR has incorrect class %d",
- update_class);
- FAIL(DNS_R_FORMERR);
- }
-
- /*
- * draft-ietf-dnsind-simple-secure-update-01 says
- * "Unlike traditional dynamic update, the client
- * is forbidden from updating NSEC records."
- */
- if (rdata.type == dns_rdatatype_nsec3) {
- FAILC(DNS_R_REFUSED, "explicit NSEC3 updates are not "
- "allowed "
- "in secure zones");
- } else if (rdata.type == dns_rdatatype_nsec) {
- FAILC(DNS_R_REFUSED, "explicit NSEC updates are not "
- "allowed "
- "in secure zones");
- } else if (rdata.type == dns_rdatatype_rrsig &&
- !dns_name_equal(name, zonename)) {
- FAILC(DNS_R_REFUSED, "explicit RRSIG updates are "
- "currently "
- "not supported in secure zones "
- "except "
- "at the apex");
- }
-
- if (ssutable != NULL) {
- isc_netaddr_t netaddr;
- dst_key_t *tsigkey = NULL;
- isc_netaddr_fromsockaddr(&netaddr, &client->peeraddr);
-
- if (client->message->tsigkey != NULL) {
- tsigkey = client->message->tsigkey->key;
- }
-
- if (rdata.type != dns_rdatatype_any) {
- if (!dns_ssutable_checkrules(
- ssutable, client->signer, name,
- &netaddr, TCPCLIENT(client), env,
- rdata.type, tsigkey))
- {
- FAILC(DNS_R_REFUSED, "rejected by "
- "secure update");
- }
- } else {
- if (!ssu_checkall(db, ver, name, ssutable,
- client->signer, &netaddr, env,
- TCPCLIENT(client), tsigkey))
- {
- FAILC(DNS_R_REFUSED, "rejected by "
- "secure update");
- }
- }
- }
- }
- if (result != ISC_R_NOMORE) {
- FAIL(result);
- }
-
- update_log(client, zone, LOGLEVEL_DEBUG, "update section prescan OK");
-
/*
* Process the Update Section.
*/
- options = dns_zone_getoptions(zone);
for (result = dns_message_firstname(request, DNS_SECTION_UPDATE);
result == ISC_R_SUCCESS;
result = dns_message_nextname(request, DNS_SECTION_UPDATE))
@@ -3307,10 +3330,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
if (result == ISC_R_SUCCESS && records > maxrecords) {
update_log(client, zone, ISC_LOG_ERROR,
"records in zone (%" PRIu64 ") "
- "exceeds"
- " max-"
- "records"
- " (%u)",
+ "exceeds max-records (%u)",
records, maxrecords);
result = DNS_R_TOOMANYRECORDS;
goto failure;
@@ -3601,6 +3621,13 @@ send_forward_event(ns_client_t *client, dns_zone_t *zone) {
update_event_t *event = NULL;
isc_task_t *zonetask = NULL;
+ result = checkupdateacl(client, dns_zone_getforwardacl(zone),
+ "update forwarding", dns_zone_getorigin(zone),
+ true, false);
+ if (result != ISC_R_SUCCESS) {
+ return (result);
+ }
+
result = isc_quota_attach(&client->manager->sctx->updquota,
&(isc_quota_t *){ NULL });
if (result != ISC_R_SUCCESS) {
--
2.39.1

View File

@ -1,272 +0,0 @@
From 54e281c11ee13eabc3c51d6391a58fc90836000c Mon Sep 17 00:00:00 2001
From: Evan Hunt <each@isc.org>
Date: Wed, 9 Nov 2022 21:56:16 -0800
Subject: [PATCH] test failure conditions
verify that updates are refused when the client is disallowed by
allow-query, and update forwarding is refused when the client is
is disallowed by update-forwarding.
verify that "too many DNS UPDATEs" appears in the log file when too
many simultaneous updates are processing.
(cherry picked from commit b91339b80e5b82a56622c93cc1e3cca2d0c11bc0)
---
bin/tests/system/nsupdate/ns1/named.conf.in | 2 +
bin/tests/system/nsupdate/tests.sh | 28 +++++++++++++
bin/tests/system/upforwd/clean.sh | 2 +
.../ns3/{named.conf.in => named1.conf.in} | 13 ++++--
bin/tests/system/upforwd/ns3/named2.conf.in | 41 +++++++++++++++++++
bin/tests/system/upforwd/setup.sh | 2 +-
bin/tests/system/upforwd/tests.sh | 39 ++++++++++++++++++
7 files changed, 123 insertions(+), 4 deletions(-)
rename bin/tests/system/upforwd/ns3/{named.conf.in => named1.conf.in} (78%)
create mode 100644 bin/tests/system/upforwd/ns3/named2.conf.in
diff --git a/bin/tests/system/nsupdate/ns1/named.conf.in b/bin/tests/system/nsupdate/ns1/named.conf.in
index 436c97d..83fe884 100644
--- a/bin/tests/system/nsupdate/ns1/named.conf.in
+++ b/bin/tests/system/nsupdate/ns1/named.conf.in
@@ -21,6 +21,7 @@ options {
recursion no;
notify yes;
minimal-responses no;
+ update-quota 1;
};
acl named-acl {
@@ -81,6 +82,7 @@ zone "other.nil" {
check-integrity no;
check-mx warn;
update-policy local;
+ allow-query { !10.53.0.2; any; };
allow-query-on { 10.53.0.1; 127.0.0.1; };
allow-transfer { any; };
};
diff --git a/bin/tests/system/nsupdate/tests.sh b/bin/tests/system/nsupdate/tests.sh
index b5f562f..13ba577 100755
--- a/bin/tests/system/nsupdate/tests.sh
+++ b/bin/tests/system/nsupdate/tests.sh
@@ -1268,6 +1268,34 @@ END
grep "NSEC3PARAM has excessive iterations (> 150)" nsupdate.out-$n >/dev/null || ret=1
[ $ret = 0 ] || { echo_i "failed"; status=1; }
+n=$((n + 1))
+ret=0
+echo_i "check that update is rejected if query is not allowed ($n)"
+{
+ $NSUPDATE -d <<END
+ local 10.53.0.2
+ server 10.53.0.1 ${PORT}
+ update add reject.other.nil 3600 IN TXT Whatever
+ send
+END
+} > nsupdate.out.test$n 2>&1
+grep 'failed: REFUSED' nsupdate.out.test$n > /dev/null || ret=1
+[ $ret = 0 ] || { echo_i "failed"; status=1; }
+
+n=$((n + 1))
+ret=0
+echo_i "check that update is rejected if quota is exceeded ($n)"
+for loop in 1 2 3 4 5 6 7 8 9 10; do
+{
+ $NSUPDATE -4 -l -p ${PORT} -k ns1/session.key > /dev/null 2>&1 <<END
+ update add txt-$loop.other.nil 3600 IN TXT Whatever
+ send
+END
+} &
+done
+wait_for_log 10 "too many DNS UPDATEs queued" ns1/named.run || ret=1
+[ $ret = 0 ] || { echo_i "failed"; status=1; }
+
if ! $FEATURETEST --gssapi ; then
echo_i "SKIPPED: GSSAPI tests"
else
diff --git a/bin/tests/system/upforwd/clean.sh b/bin/tests/system/upforwd/clean.sh
index 2025252..12311df 100644
--- a/bin/tests/system/upforwd/clean.sh
+++ b/bin/tests/system/upforwd/clean.sh
@@ -29,3 +29,5 @@ rm -f keyname keyname.err
rm -f ns*/named.lock
rm -f ns1/example2.db
rm -f ns*/managed-keys.bind*
+rm -f nsupdate.out.*
+rm -f ns*/named.run.prev
diff --git a/bin/tests/system/upforwd/ns3/named.conf.in b/bin/tests/system/upforwd/ns3/named1.conf.in
similarity index 78%
rename from bin/tests/system/upforwd/ns3/named.conf.in
rename to bin/tests/system/upforwd/ns3/named1.conf.in
index 7bd13d3..2f690ff 100644
--- a/bin/tests/system/upforwd/ns3/named.conf.in
+++ b/bin/tests/system/upforwd/ns3/named1.conf.in
@@ -28,20 +28,27 @@ key rndc_key {
};
controls {
- inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+ inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
zone "example" {
type secondary;
file "example.bk";
- allow-update-forwarding { any; };
+ allow-update-forwarding { 10.53.0.1; };
primaries { 10.53.0.1; };
};
zone "example2" {
type secondary;
file "example2.bk";
- allow-update-forwarding { any; };
+ allow-update-forwarding { 10.53.0.1; };
+ primaries { 10.53.0.1; };
+};
+
+zone "example3" {
+ type secondary;
+ file "example3.bk";
+ allow-update-forwarding { 10.53.0.1; };
primaries { 10.53.0.1; };
};
diff --git a/bin/tests/system/upforwd/ns3/named2.conf.in b/bin/tests/system/upforwd/ns3/named2.conf.in
new file mode 100644
index 0000000..e15459a
--- /dev/null
+++ b/bin/tests/system/upforwd/ns3/named2.conf.in
@@ -0,0 +1,41 @@
+/*
+ * 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 {
+ query-source address 10.53.0.3;
+ notify-source 10.53.0.3;
+ transfer-source 10.53.0.3;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { 10.53.0.3; };
+ listen-on-v6 { none; };
+ recursion no;
+ notify yes;
+ update-quota 1;
+};
+
+key rndc_key {
+ secret "1234abcd8765";
+ algorithm hmac-sha256;
+};
+
+controls {
+ inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+zone "example" {
+ type secondary;
+ file "example.bk";
+ allow-update-forwarding { any; };
+ primaries { 10.53.0.1; };
+};
diff --git a/bin/tests/system/upforwd/setup.sh b/bin/tests/system/upforwd/setup.sh
index e748078..88ab28d 100644
--- a/bin/tests/system/upforwd/setup.sh
+++ b/bin/tests/system/upforwd/setup.sh
@@ -17,7 +17,7 @@ cp -f ns3/nomaster.db ns3/nomaster1.db
copy_setports ns1/named.conf.in ns1/named.conf
copy_setports ns2/named.conf.in ns2/named.conf
-copy_setports ns3/named.conf.in ns3/named.conf
+copy_setports ns3/named1.conf.in ns3/named.conf
if $FEATURETEST --enable-dnstap
then
diff --git a/bin/tests/system/upforwd/tests.sh b/bin/tests/system/upforwd/tests.sh
index 8062d68..20fc46f 100644
--- a/bin/tests/system/upforwd/tests.sh
+++ b/bin/tests/system/upforwd/tests.sh
@@ -80,6 +80,7 @@ if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi
echo_i "updating zone (signed) ($n)"
ret=0
$NSUPDATE -y hmac-sha256:update.example:c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K -- - <<EOF || ret=1
+local 10.53.0.1
server 10.53.0.3 ${PORT}
update add updated.example. 600 A 10.10.10.1
update add updated.example. 600 TXT Foo
@@ -138,6 +139,7 @@ fi
echo_i "updating zone (unsigned) ($n)"
ret=0
$NSUPDATE -- - <<EOF || ret=1
+local 10.53.0.1
server 10.53.0.3 ${PORT}
update add unsigned.example. 600 A 10.10.10.1
update add unsigned.example. 600 TXT Foo
@@ -194,6 +196,7 @@ while [ $count -lt 5 -a $ret -eq 0 ]
do
(
$NSUPDATE -- - <<EOF
+local 10.53.0.1
server 10.53.0.3 ${PORT}
zone nomaster
update add unsigned.nomaster. 600 A 10.10.10.1
@@ -225,6 +228,7 @@ then
ret=0
keyname=`cat keyname`
$NSUPDATE -k $keyname.private -- - <<EOF
+ local 10.53.0.1
server 10.53.0.3 ${PORT}
zone example2
update add unsigned.example2. 600 A 10.10.10.1
@@ -249,5 +253,40 @@ EOF
fi
fi
+echo_i "attempting an update that should be rejected by ACL ($n)"
+ret=0
+{
+ $NSUPDATE -- - << EOF
+ local 10.53.0.2
+ server 10.53.0.3 ${PORT}
+ update add another.unsigned.example. 600 A 10.10.10.2
+ update add another.unsigned.example. 600 TXT Bar
+ send
+EOF
+} > nsupdate.out.$n 2>&1
+grep REFUSED nsupdate.out.$n > /dev/null || ret=1
+if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi
+n=`expr $n + 1`
+
+n=$((n + 1))
+ret=0
+echo_i "attempting updates that should exceed quota ($n)"
+# lower the update quota to 1.
+copy_setports ns3/named2.conf.in ns3/named.conf
+rndc_reconfig ns3 10.53.0.3
+nextpart ns3/named.run > /dev/null
+for loop in 1 2 3 4 5 6 7 8 9 10; do
+{
+ $NSUPDATE -- - > /dev/null 2>&1 <<END
+ local 10.53.0.1
+ server 10.53.0.3 ${PORT}
+ update add txt-$loop.unsigned.example 300 IN TXT Whatever
+ send
+END
+} &
+done
+wait_for_log 10 "too many DNS UPDATEs queued" ns3/named.run || ret=1
+[ $ret = 0 ] || { echo_i "failed"; status=1; }
+
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
--
2.39.2

View File

@ -1,53 +0,0 @@
From 1b6590eafce064cbf70f5afc2fe4d6f1bfdc3804 Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Thu, 27 Oct 2022 13:22:11 +1100
Subject: [PATCH] Move the mapping of SIG and RRSIG to ANY
dns_db_findext() asserts if RRSIG is passed to it and
query_lookup_stale() failed to map RRSIG to ANY to prevent this. To
avoid cases like this in the future, move the mapping of SIG and RRSIG
to ANY for qctx->type to qctx_init().
(cherry picked from commit 56eae064183488bcf7ff08c3edf59f2e1742c1b6)
---
lib/ns/query.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/lib/ns/query.c b/lib/ns/query.c
index a450cb7..f66bab4 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -5103,6 +5103,15 @@ qctx_init(ns_client_t *client, dns_fetchevent_t **eventp, dns_rdatatype_t qtype,
qctx->result = ISC_R_SUCCESS;
qctx->findcoveringnsec = qctx->view->synthfromdnssec;
+ /*
+ * If it's an RRSIG or SIG query, we'll iterate the node.
+ */
+ if (qctx->qtype == dns_rdatatype_rrsig ||
+ qctx->qtype == dns_rdatatype_sig)
+ {
+ qctx->type = dns_rdatatype_any;
+ }
+
CALL_HOOK_NORETURN(NS_QUERY_QCTX_INITIALIZED, qctx);
}
@@ -5243,14 +5252,6 @@ query_setup(ns_client_t *client, dns_rdatatype_t qtype) {
CALL_HOOK(NS_QUERY_SETUP, &qctx);
- /*
- * If it's a SIG query, we'll iterate the node.
- */
- if (qctx.qtype == dns_rdatatype_rrsig ||
- qctx.qtype == dns_rdatatype_sig) {
- qctx.type = dns_rdatatype_any;
- }
-
/*
* Check SERVFAIL cache
*/
--
2.39.1

View File

@ -1,27 +0,0 @@
From df8222fb189708199a185f73543b6e0602c1c72f Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Tue, 20 Sep 2022 11:21:45 +0200
Subject: [PATCH 3/4] Fix CVE-2022-38177
5961. [security] Fix memory leak in ECDSA verify processing.
(CVE-2022-38177) [GL #3487]
---
lib/dns/opensslecdsa_link.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c
index ce4c8c4..3847896 100644
--- a/lib/dns/opensslecdsa_link.c
+++ b/lib/dns/opensslecdsa_link.c
@@ -228,7 +228,7 @@ opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
}
if (sig->length != siglen) {
- return (DST_R_VERIFYFAILURE);
+ DST_RET(DST_R_VERIFYFAILURE);
}
if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen)) {
--
2.37.3

View File

@ -1,32 +0,0 @@
From 132ef295b8407f91e6922f4dfc4f30f1790b61c5 Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Tue, 20 Sep 2022 11:22:47 +0200
Subject: [PATCH 4/4] Fix CVE-2022-38178
5962. [security] Fix memory leak in EdDSA verify processing.
(CVE-2022-38178) [GL #3487]
---
lib/dns/openssleddsa_link.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/dns/openssleddsa_link.c b/lib/dns/openssleddsa_link.c
index 6a6a74d..3157011 100644
--- a/lib/dns/openssleddsa_link.c
+++ b/lib/dns/openssleddsa_link.c
@@ -234,11 +234,11 @@ openssleddsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
}
#endif /* if HAVE_OPENSSL_ED448 */
if (siglen == 0) {
- return (ISC_R_NOTIMPLEMENTED);
+ DST_RET(ISC_R_NOTIMPLEMENTED);
}
if (sig->length != siglen) {
- return (DST_R_VERIFYFAILURE);
+ DST_RET(DST_R_VERIFYFAILURE);
}
isc_buffer_usedregion(buf, &tbsreg);
--
2.37.3

View File

@ -1,128 +0,0 @@
From 20424b3bfe8d3fae92c11a30e79aeffd26dc2891 Mon Sep 17 00:00:00 2001
From: Aram Sargsyan <aram@isc.org>
Date: Mon, 14 Nov 2022 12:18:06 +0000
Subject: [PATCH] Cancel all fetch events in dns_resolver_cancelfetch()
Although 'dns_fetch_t' fetch can have two associated events, one for
each of 'DNS_EVENT_FETCHDONE' and 'DNS_EVENT_TRYSTALE' types, the
dns_resolver_cancelfetch() function is designed in a way that it
expects only one existing event, which it must cancel, and when it
happens so that 'stale-answer-client-timeout' is enabled and there
are two events, only one of them is canceled, and it results in an
assertion in dns_resolver_destroyfetch(), when it finds a dangling
event.
Change the logic of dns_resolver_cancelfetch() function so that it
cancels both the events (if they exist), and in the right order.
(cherry picked from commit ec2098ca35039e4f81fd0aa7c525eb960b8f47bf)
---
lib/dns/resolver.c | 53 +++++++++++++++++++++++++++++++++++-----------
lib/ns/query.c | 4 +++-
2 files changed, 44 insertions(+), 13 deletions(-)
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 18585b5..7cbfbb2 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -11254,8 +11254,9 @@ void
dns_resolver_cancelfetch(dns_fetch_t *fetch) {
fetchctx_t *fctx;
dns_resolver_t *res;
- dns_fetchevent_t *event, *next_event;
- isc_task_t *etask;
+ dns_fetchevent_t *event = NULL;
+ dns_fetchevent_t *event_trystale = NULL;
+ dns_fetchevent_t *event_fetchdone = NULL;
REQUIRE(DNS_FETCH_VALID(fetch));
fctx = fetch->private;
@@ -11267,32 +11268,60 @@ dns_resolver_cancelfetch(dns_fetch_t *fetch) {
LOCK(&res->buckets[fctx->bucketnum].lock);
/*
- * Find the completion event for this fetch (as opposed
+ * Find the events for this fetch (as opposed
* to those for other fetches that have joined the same
- * fctx) and send it with result = ISC_R_CANCELED.
+ * fctx) and send them with result = ISC_R_CANCELED.
*/
- event = NULL;
if (fctx->state != fetchstate_done) {
+ dns_fetchevent_t *next_event = NULL;
for (event = ISC_LIST_HEAD(fctx->events); event != NULL;
event = next_event) {
next_event = ISC_LIST_NEXT(event, ev_link);
if (event->fetch == fetch) {
ISC_LIST_UNLINK(fctx->events, event, ev_link);
- break;
+ switch (event->ev_type) {
+ case DNS_EVENT_TRYSTALE:
+ INSIST(event_trystale == NULL);
+ event_trystale = event;
+ break;
+ case DNS_EVENT_FETCHDONE:
+ INSIST(event_fetchdone == NULL);
+ event_fetchdone = event;
+ break;
+ default:
+ ISC_UNREACHABLE();
+ }
+ if (event_trystale != NULL &&
+ event_fetchdone != NULL)
+ {
+ break;
+ }
}
}
}
- if (event != NULL) {
- etask = event->ev_sender;
- event->ev_sender = fctx;
- event->result = ISC_R_CANCELED;
- isc_task_sendanddetach(&etask, ISC_EVENT_PTR(&event));
+
+ /*
+ * The "trystale" event must be sent before the "fetchdone" event,
+ * because the latter clears the "recursing" query attribute, which is
+ * required by both events (handled by the same callback function).
+ */
+ if (event_trystale != NULL) {
+ isc_task_t *etask = event_trystale->ev_sender;
+ event_trystale->ev_sender = fctx;
+ event_trystale->result = ISC_R_CANCELED;
+ isc_task_sendanddetach(&etask, ISC_EVENT_PTR(&event_trystale));
}
+ if (event_fetchdone != NULL) {
+ isc_task_t *etask = event_fetchdone->ev_sender;
+ event_fetchdone->ev_sender = fctx;
+ event_fetchdone->result = ISC_R_CANCELED;
+ isc_task_sendanddetach(&etask, ISC_EVENT_PTR(&event_fetchdone));
+ }
+
/*
* The fctx continues running even if no fetches remain;
* the answer is still cached.
*/
-
UNLOCK(&res->buckets[fctx->bucketnum].lock);
}
diff --git a/lib/ns/query.c b/lib/ns/query.c
index f66bab4..4f61374 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -6021,7 +6021,9 @@ fetch_callback(isc_task_t *task, isc_event_t *event) {
CTRACE(ISC_LOG_DEBUG(3), "fetch_callback");
if (event->ev_type == DNS_EVENT_TRYSTALE) {
- query_lookup_stale(client);
+ if (devent->result != ISC_R_CANCELED) {
+ query_lookup_stale(client);
+ }
isc_event_free(ISC_EVENT_PTR(&event));
return;
}
--
2.39.1

View File

@ -1,192 +0,0 @@
From ed920ea2ae1cc1214b42b82a5149758dbec941a5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Tue, 30 May 2023 08:46:17 +0200
Subject: [PATCH] Improve RBT overmem cache cleaning
When cache memory usage is over the configured cache size (overmem) and
we are cleaning unused entries, it might not be enough to clean just two
entries if the entries to be expired are smaller than the newly added
rdata. This could be abused by an attacker to cause a remote Denial of
Service by possibly running out of the operating system memory.
Currently, the addrdataset() tries to do a single TTL-based cleaning
considering the serve-stale TTL and then optionally moves to overmem
cleaning if we are in that condition. Then the overmem_purge() tries to
do another single TTL based cleaning from the TTL heap and then continue
with LRU-based cleaning up to 2 entries cleaned.
Squash the TTL-cleaning mechanism into single call from addrdataset(),
but ignore the serve-stale TTL if we are currently overmem.
Then instead of having a fixed number of entries to clean, pass the size
of newly added rdatasetheader to the overmem_purge() function and
cleanup at least the size of the newly added data. This prevents the
cache going over the configured memory limit (`max-cache-size`).
Additionally, refactor the overmem_purge() function to reduce for-loop
nesting for readability.
(cherry picked from commit f1d9e9ee3859976f403914d20ad2a10855343702)
---
lib/dns/rbtdb.c | 105 ++++++++++++++++++++++++++++++------------------
1 file changed, 65 insertions(+), 40 deletions(-)
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index 51178cc877..75f97f5550 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -599,7 +599,7 @@ static void
expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, bool tree_locked,
expire_t reason);
static void
-overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, isc_stdtime_t now,
+overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, size_t purgesize,
bool tree_locked);
static isc_result_t
resign_insert(dns_rbtdb_t *rbtdb, int idx, rdatasetheader_t *newheader);
@@ -6802,6 +6802,16 @@ cleanup:
static dns_dbmethods_t zone_methods;
+static size_t
+rdataset_size(rdatasetheader_t *header) {
+ if (!NONEXISTENT(header)) {
+ return (dns_rdataslab_size((unsigned char *)header,
+ sizeof(*header)));
+ }
+
+ return (sizeof(*header));
+}
+
static isc_result_t
addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
@@ -6965,7 +6975,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
}
if (cache_is_overmem) {
- overmem_purge(rbtdb, rbtnode->locknum, now, tree_locked);
+ overmem_purge(rbtdb, rbtnode->locknum, rdataset_size(newheader),
+ tree_locked);
}
NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
@@ -6984,10 +6995,18 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
}
header = isc_heap_element(rbtdb->heaps[rbtnode->locknum], 1);
- if (header != NULL && header->rdh_ttl + rbtdb->serve_stale_ttl <
- now - RBTDB_VIRTUAL)
- {
- expire_header(rbtdb, header, tree_locked, expire_ttl);
+ if (header != NULL) {
+ dns_ttl_t rdh_ttl = header->rdh_ttl;
+
+ /* Only account for stale TTL if cache is not overmem */
+ if (!cache_is_overmem) {
+ rdh_ttl += rbtdb->serve_stale_ttl;
+ }
+
+ if (rdh_ttl < now - RBTDB_VIRTUAL) {
+ expire_header(rbtdb, header, tree_locked,
+ expire_ttl);
+ }
}
/*
@@ -10531,52 +10550,58 @@ update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, isc_stdtime_t now) {
ISC_LIST_PREPEND(rbtdb->rdatasets[header->node->locknum], header, link);
}
+static size_t
+expire_lru_headers(dns_rbtdb_t *rbtdb, unsigned int locknum, size_t purgesize,
+ bool tree_locked) {
+ rdatasetheader_t *header, *header_prev;
+ size_t purged = 0;
+
+ for (header = ISC_LIST_TAIL(rbtdb->rdatasets[locknum]);
+ header != NULL && purged <= purgesize; header = header_prev)
+ {
+ header_prev = ISC_LIST_PREV(header, link);
+ /*
+ * Unlink the entry at this point to avoid checking it
+ * again even if it's currently used someone else and
+ * cannot be purged at this moment. This entry won't be
+ * referenced any more (so unlinking is safe) since the
+ * TTL was reset to 0.
+ */
+ ISC_LIST_UNLINK(rbtdb->rdatasets[locknum], header, link);
+ size_t header_size = rdataset_size(header);
+ expire_header(rbtdb, header, tree_locked, expire_lru);
+ purged += header_size;
+ }
+
+ return (purged);
+}
+
/*%
- * Purge some expired and/or stale (i.e. unused for some period) cache entries
- * under an overmem condition. To recover from this condition quickly, up to
- * 2 entries will be purged. This process is triggered while adding a new
- * entry, and we specifically avoid purging entries in the same LRU bucket as
- * the one to which the new entry will belong. Otherwise, we might purge
- * entries of the same name of different RR types while adding RRsets from a
- * single response (consider the case where we're adding A and AAAA glue records
- * of the same NS name).
+ * Purge some stale (i.e. unused for some period - LRU based cleaning) cache
+ * entries under the overmem condition. To recover from this condition quickly,
+ * we cleanup entries up to the size of newly added rdata (passed as purgesize).
+ *
+ * This process is triggered while adding a new entry, and we specifically avoid
+ * purging entries in the same LRU bucket as the one to which the new entry will
+ * belong. Otherwise, we might purge entries of the same name of different RR
+ * types while adding RRsets from a single response (consider the case where
+ * we're adding A and AAAA glue records of the same NS name).
*/
static void
-overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, isc_stdtime_t now,
+overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, size_t purgesize,
bool tree_locked) {
- rdatasetheader_t *header, *header_prev;
unsigned int locknum;
- int purgecount = 2;
+ size_t purged = 0;
for (locknum = (locknum_start + 1) % rbtdb->node_lock_count;
- locknum != locknum_start && purgecount > 0;
+ locknum != locknum_start && purged <= purgesize;
locknum = (locknum + 1) % rbtdb->node_lock_count)
{
NODE_LOCK(&rbtdb->node_locks[locknum].lock,
isc_rwlocktype_write);
- header = isc_heap_element(rbtdb->heaps[locknum], 1);
- if (header && header->rdh_ttl < now - RBTDB_VIRTUAL) {
- expire_header(rbtdb, header, tree_locked, expire_ttl);
- purgecount--;
- }
-
- for (header = ISC_LIST_TAIL(rbtdb->rdatasets[locknum]);
- header != NULL && purgecount > 0; header = header_prev)
- {
- header_prev = ISC_LIST_PREV(header, link);
- /*
- * Unlink the entry at this point to avoid checking it
- * again even if it's currently used someone else and
- * cannot be purged at this moment. This entry won't be
- * referenced any more (so unlinking is safe) since the
- * TTL was reset to 0.
- */
- ISC_LIST_UNLINK(rbtdb->rdatasets[locknum], header,
- link);
- expire_header(rbtdb, header, tree_locked, expire_lru);
- purgecount--;
- }
+ purged += expire_lru_headers(rbtdb, locknum, purgesize - purged,
+ tree_locked);
NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
isc_rwlocktype_write);
--
2.40.1

View File

@ -1,37 +0,0 @@
From e73ecbf039c3b2cd33dd2926691a8a346c9ca574 Mon Sep 17 00:00:00 2001
From: Matthijs Mekking <matthijs@isc.org>
Date: Tue, 2 Aug 2022 14:21:40 +0200
Subject: [PATCH 1/3] Don't enable serve-stale on duplicate queries
When checking if we should enable serve-stale, add an early out case
when the result is an error signalling a duplicate query or a query
that would be dropped.
(cherry picked from commit 059a4c2f4d9d3cff371842f43208d021509314fa)
(cherry picked from commit dd7dde5743715dc0dec2defbb92b1a8637977bf9)
---
lib/ns/query.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/lib/ns/query.c b/lib/ns/query.c
index 4f61374e2c..c169e22bf4 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -7205,6 +7205,14 @@ query_usestale(query_ctx_t *qctx, isc_result_t result) {
return (false);
}
+ if (result == DNS_R_DUPLICATE || result == DNS_R_DROP) {
+ /*
+ * Don't enable serve-stale if the result signals a duplicate
+ * query or query that is being dropped.
+ */
+ return (false);
+ }
+
qctx_clean(qctx);
qctx_freedata(qctx);
--
2.40.1

View File

@ -1,72 +0,0 @@
From 589c06568e3036bfe713d42b53c8e88005ce17e4 Mon Sep 17 00:00:00 2001
From: Evan Hunt <each@isc.org>
Date: Thu, 25 May 2023 23:53:50 -0700
Subject: [PATCH 2/3] Stale answer lookups could loop when over recursion quota
When a query was aborted because of the recursion quota being exceeded,
but triggered a stale answer response and a stale data refresh query,
it could cause named to loop back where we are iterating and following
a delegation. Having no good answer in cache, we would fall back to
using serve-stale again, use the stale data, try to refresh the RRset,
and loop back again, without ever terminating until crashing due to
stack overflow.
This happens because in the functions 'query_notfound()' and
'query_delegation_recurse()', we check whether we can fall back to
serving stale data. We shouldn't do so if we are already refreshing
an RRset due to having prioritized stale data in cache.
In other words, we need to add an extra check to 'query_usestale()' to
disallow serving stale data if we are currently refreshing a stale
RRset.
As an additional mitigation to prevent looping, we now use the result
code ISC_R_ALREADYRUNNING rather than ISC_R_FAILURE when a recursion
loop is encountered, and we check for that condition in
'query_usestale()' as well.
(cherry picked from commit 0101e28f91fb36b6a16a0049d3b3e2b7846f23f0)
---
lib/ns/query.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/lib/ns/query.c b/lib/ns/query.c
index c169e22bf4..1eb662ea4d 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -6229,7 +6229,7 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
if (recparam_match(&client->query.recparam, qtype, qname, qdomain)) {
ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_QUERY,
ISC_LOG_INFO, "recursion loop detected");
- return (ISC_R_FAILURE);
+ return (ISC_R_ALREADYRUNNING);
}
recparam_update(&client->query.recparam, qtype, qname, qdomain);
@@ -7205,10 +7205,21 @@ query_usestale(query_ctx_t *qctx, isc_result_t result) {
return (false);
}
- if (result == DNS_R_DUPLICATE || result == DNS_R_DROP) {
+ if (qctx->refresh_rrset) {
+ /*
+ * This is a refreshing query, we have already prioritized
+ * stale data, so don't enable serve-stale again.
+ */
+ return (false);
+ }
+
+ if (result == DNS_R_DUPLICATE || result == DNS_R_DROP ||
+ result == ISC_R_ALREADYRUNNING)
+ {
/*
* Don't enable serve-stale if the result signals a duplicate
- * query or query that is being dropped.
+ * query or a query that is being dropped or can't proceed
+ * because of a recursion loop.
*/
return (false);
}
--
2.40.1

View File

@ -1,60 +0,0 @@
From c20e9d30bae58d3120aa7c6a0e5dcae0e7e93dbd Mon Sep 17 00:00:00 2001
From: Matthijs Mekking <matthijs@isc.org>
Date: Thu, 1 Jun 2023 10:03:48 +0200
Subject: [PATCH 3/3] Fix serve-stale hang at shutdown
The 'refresh_rrset' variable is used to determine if we can detach from
the client. This can cause a hang on shutdown. To fix this, move setting
of the 'nodetach' variable up to where 'refresh_rrset' is set (in
query_lookup(), and thus not in ns_query_done()), and set it to false
when actually refreshing the RRset, so that when this lookup is
completed, the client will be detached.
(cherry picked from commit c003c5bc3c68f3e513654b6689e1f60280d14844)
---
lib/ns/query.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/lib/ns/query.c b/lib/ns/query.c
index 1eb662ea4d..4fe3e30f45 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -5644,6 +5644,7 @@ query_refresh_rrset(query_ctx_t *orig_qctx) {
qctx.client->query.dboptions &= ~(DNS_DBFIND_STALETIMEOUT |
DNS_DBFIND_STALEOK |
DNS_DBFIND_STALEENABLED);
+ qctx.client->nodetach = false;
/*
* We'll need some resources...
@@ -5868,7 +5869,14 @@ query_lookup(query_ctx_t *qctx) {
"%s stale answer used, an attempt to "
"refresh the RRset will still be made",
namebuf);
+
qctx->refresh_rrset = STALE(qctx->rdataset);
+
+ /*
+ * If we are refreshing the RRSet, we must not
+ * detach from the client in query_send().
+ */
+ qctx->client->nodetach = qctx->refresh_rrset;
}
} else {
/*
@@ -11469,12 +11477,7 @@ ns_query_done(query_ctx_t *qctx) {
/*
* Client may have been detached after query_send(), so
* we test and store the flag state here, for safety.
- * If we are refreshing the RRSet, we must not detach from the client
- * in the query_send(), so we need to override the flag.
*/
- if (qctx->refresh_rrset) {
- qctx->client->nodetach = true;
- }
nodetach = qctx->client->nodetach;
query_send(qctx->client);
--
2.40.1

View File

@ -1,168 +0,0 @@
From b137e12dc8118cddee20e372e480a495585e72b6 Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Tue, 19 Sep 2023 12:44:31 +0200
Subject: [PATCH] Fix CVE-2023-3341
6245. [security] Limit the amount of recursion that can be performed
by isccc_cc_fromwire. (CVE-2023-3341) [GL #4152]
---
lib/isccc/cc.c | 39 ++++++++++++++++++++++++--------
lib/isccc/include/isccc/result.h | 4 +++-
lib/isccc/result.c | 4 +++-
3 files changed, 35 insertions(+), 12 deletions(-)
diff --git a/lib/isccc/cc.c b/lib/isccc/cc.c
index 0be28b9057..3744d0f037 100644
--- a/lib/isccc/cc.c
+++ b/lib/isccc/cc.c
@@ -50,6 +50,10 @@
#define MAX_TAGS 256
#define DUP_LIFETIME 900
+#ifndef ISCCC_MAXDEPTH
+#define ISCCC_MAXDEPTH \
+ 10 /* Big enough for rndc which just sends a string each way. */
+#endif
typedef isccc_sexpr_t *sexpr_ptr;
@@ -480,19 +484,25 @@ verify(isccc_sexpr_t *alist, unsigned char *data, unsigned int length,
static isc_result_t
table_fromwire(isccc_region_t *source, isccc_region_t *secret,
- uint32_t algorithm, isccc_sexpr_t **alistp);
+ uint32_t algorithm, unsigned int depth, isccc_sexpr_t **alistp);
static isc_result_t
-list_fromwire(isccc_region_t *source, isccc_sexpr_t **listp);
+list_fromwire(isccc_region_t *source, unsigned int depth,
+ isccc_sexpr_t **listp);
static isc_result_t
-value_fromwire(isccc_region_t *source, isccc_sexpr_t **valuep) {
+value_fromwire(isccc_region_t *source, unsigned int depth,
+ isccc_sexpr_t **valuep) {
unsigned int msgtype;
uint32_t len;
isccc_sexpr_t *value;
isccc_region_t active;
isc_result_t result;
+ if (depth > ISCCC_MAXDEPTH) {
+ return (ISCCC_R_MAXDEPTH);
+ }
+
if (REGION_SIZE(*source) < 1 + 4) {
return (ISC_R_UNEXPECTEDEND);
}
@@ -513,9 +523,9 @@ value_fromwire(isccc_region_t *source, isccc_sexpr_t **valuep) {
result = ISC_R_NOMEMORY;
}
} else if (msgtype == ISCCC_CCMSGTYPE_TABLE) {
- result = table_fromwire(&active, NULL, 0, valuep);
+ result = table_fromwire(&active, NULL, 0, depth + 1, valuep);
} else if (msgtype == ISCCC_CCMSGTYPE_LIST) {
- result = list_fromwire(&active, valuep);
+ result = list_fromwire(&active, depth + 1, valuep);
} else {
result = ISCCC_R_SYNTAX;
}
@@ -525,7 +535,7 @@ value_fromwire(isccc_region_t *source, isccc_sexpr_t **valuep) {
static isc_result_t
table_fromwire(isccc_region_t *source, isccc_region_t *secret,
- uint32_t algorithm, isccc_sexpr_t **alistp) {
+ uint32_t algorithm, unsigned int depth, isccc_sexpr_t **alistp) {
char key[256];
uint32_t len;
isc_result_t result;
@@ -535,6 +545,10 @@ table_fromwire(isccc_region_t *source, isccc_region_t *secret,
REQUIRE(alistp != NULL && *alistp == NULL);
+ if (depth > ISCCC_MAXDEPTH) {
+ return (ISCCC_R_MAXDEPTH);
+ }
+
checksum_rstart = NULL;
first_tag = true;
alist = isccc_alist_create();
@@ -551,7 +565,7 @@ table_fromwire(isccc_region_t *source, isccc_region_t *secret,
GET_MEM(key, len, source->rstart);
key[len] = '\0'; /* Ensure NUL termination. */
value = NULL;
- result = value_fromwire(source, &value);
+ result = value_fromwire(source, depth + 1, &value);
if (result != ISC_R_SUCCESS) {
goto bad;
}
@@ -589,14 +603,19 @@ bad:
}
static isc_result_t
-list_fromwire(isccc_region_t *source, isccc_sexpr_t **listp) {
+list_fromwire(isccc_region_t *source, unsigned int depth,
+ isccc_sexpr_t **listp) {
isccc_sexpr_t *list, *value;
isc_result_t result;
+ if (depth > ISCCC_MAXDEPTH) {
+ return (ISCCC_R_MAXDEPTH);
+ }
+
list = NULL;
while (!REGION_EMPTY(*source)) {
value = NULL;
- result = value_fromwire(source, &value);
+ result = value_fromwire(source, depth + 1, &value);
if (result != ISC_R_SUCCESS) {
isccc_sexpr_free(&list);
return (result);
@@ -628,7 +647,7 @@ isccc_cc_fromwire(isccc_region_t *source, isccc_sexpr_t **alistp,
return (ISCCC_R_UNKNOWNVERSION);
}
- return (table_fromwire(source, secret, algorithm, alistp));
+ return (table_fromwire(source, secret, algorithm, 0, alistp));
}
static isc_result_t
diff --git a/lib/isccc/include/isccc/result.h b/lib/isccc/include/isccc/result.h
index 5346babefc..5b6a876d1c 100644
--- a/lib/isccc/include/isccc/result.h
+++ b/lib/isccc/include/isccc/result.h
@@ -46,8 +46,10 @@
#define ISCCC_R_CLOCKSKEW (ISC_RESULTCLASS_ISCCC + 4)
/*% Duplicate */
#define ISCCC_R_DUPLICATE (ISC_RESULTCLASS_ISCCC + 5)
+/*% Maximum recursion depth */
+#define ISCCC_R_MAXDEPTH (ISC_RESULTCLASS_ISCCC + 6)
-#define ISCCC_R_NRESULTS 6 /*%< Number of results */
+#define ISCCC_R_NRESULTS 7 /*%< Number of results */
ISC_LANG_BEGINDECLS
diff --git a/lib/isccc/result.c b/lib/isccc/result.c
index 9285435209..1956cb1655 100644
--- a/lib/isccc/result.c
+++ b/lib/isccc/result.c
@@ -36,12 +36,14 @@ static const char *text[ISCCC_R_NRESULTS] = {
"bad auth", /* 3 */
"expired", /* 4 */
"clock skew", /* 5 */
- "duplicate" /* 6 */
+ "duplicate", /* 6 */
+ "max depth" /* 7 */
};
static const char *ids[ISCCC_R_NRESULTS] = {
"ISCCC_R_UNKNOWNVERSION", "ISCCC_R_SYNTAX", "ISCCC_R_BADAUTH",
"ISCCC_R_EXPIRED", "ISCCC_R_CLOCKSKEW", "ISCCC_R_DUPLICATE",
+ "ISCCC_R_MAXDEPTH"
};
#define ISCCC_RESULT_RESULTSET 2
--
2.41.0

View File

@ -1,88 +0,0 @@
From d258422d3e653621ce6340ba9af0153f8d4e8c07 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Sun, 11 Feb 2024 00:49:32 +0100
Subject: [PATCH] Test case insensitive matching in isc_ht hash table
implementation
The case insensitive matching in isc_ht was basically completely broken
as only the hashvalue computation was case insensitive, but the key
comparison was always case sensitive.
Import only test part from upstream.
(cherry picked from commit 175655b771fd17b06dfb8cfb29eaadf0f3b6a8b5)
(cherry picked from upstream commit f493a8394102b0aeb101d5dc2f963004c8741175)
---
lib/isc/tests/ht_test.c | 53 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/lib/isc/tests/ht_test.c b/lib/isc/tests/ht_test.c
index 74d95c1..65502b5 100644
--- a/lib/isc/tests/ht_test.c
+++ b/lib/isc/tests/ht_test.c
@@ -334,9 +334,62 @@ isc_ht_iterator_test(void **state) {
test_ht_iterator();
}
+static void
+isc_ht_case(void **state) {
+ UNUSED(state);
+
+ isc_ht_t *ht = NULL;
+ void *f = NULL;
+ isc_result_t result = ISC_R_UNSET;
+
+ unsigned char lower[16] = { "test case" };
+ unsigned char same[16] = { "test case" };
+ unsigned char upper[16] = { "TEST CASE" };
+ unsigned char mixed[16] = { "tEsT CaSe" };
+
+ isc_ht_init(&ht, test_mctx, 8, ISC_HT_CASE_SENSITIVE);
+ assert_non_null(ht);
+
+ result = isc_ht_add(ht, lower, 16, (void *)lower);
+ assert_int_equal(result, ISC_R_SUCCESS);
+
+ result = isc_ht_add(ht, same, 16, (void *)same);
+ assert_int_equal(result, ISC_R_EXISTS);
+
+ result = isc_ht_add(ht, upper, 16, (void *)upper);
+ assert_int_equal(result, ISC_R_SUCCESS);
+
+ result = isc_ht_find(ht, mixed, 16, &f);
+ assert_int_equal(result, ISC_R_NOTFOUND);
+ assert_null(f);
+
+ isc_ht_destroy(&ht);
+ assert_null(ht);
+
+ isc_ht_init(&ht, test_mctx, 8, ISC_HT_CASE_INSENSITIVE);
+ assert_non_null(ht);
+
+ result = isc_ht_add(ht, lower, 16, (void *)lower);
+ assert_int_equal(result, ISC_R_SUCCESS);
+
+ result = isc_ht_add(ht, same, 16, (void *)same);
+ assert_int_equal(result, ISC_R_EXISTS);
+
+ result = isc_ht_add(ht, upper, 16, (void *)upper);
+ assert_int_equal(result, ISC_R_EXISTS);
+
+ result = isc_ht_find(ht, mixed, 16, &f);
+ assert_int_equal(result, ISC_R_SUCCESS);
+ assert_ptr_equal(f, &lower);
+
+ isc_ht_destroy(&ht);
+ assert_null(ht);
+}
+
int
main(void) {
const struct CMUnitTest tests[] = {
+ cmocka_unit_test(isc_ht_case),
cmocka_unit_test(isc_ht_20),
cmocka_unit_test(isc_ht_8),
cmocka_unit_test(isc_ht_1),
--
2.43.0

View File

@ -1,75 +0,0 @@
From aa1b0fc4b24d26233db30c85ae3609e54e9fa6d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Sun, 11 Feb 2024 09:13:43 +0100
Subject: [PATCH] Add a system test for mixed-case data for the same owner
We were missing a test where a single owner name would have multiple
types with a different case. The generated RRSIGs and NSEC records will
then have different case than the signed records and message parser have
to cope with that and treat everything as the same owner.
(cherry picked from commit a114042059ecbbc94ae0f604ca681323a75af480)
(cherry picked from upstream commit b9c10a194da3358204f5ba7d91e55332db435614)
---
bin/tests/system/dnssec/ns3/secure.example.db.in | 5 +++++
bin/tests/system/dnssec/ns3/sign.sh | 4 +++-
bin/tests/system/dnssec/tests.sh | 15 +++++++++++++++
3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/bin/tests/system/dnssec/ns3/secure.example.db.in b/bin/tests/system/dnssec/ns3/secure.example.db.in
index 27f2b24..599566e 100644
--- a/bin/tests/system/dnssec/ns3/secure.example.db.in
+++ b/bin/tests/system/dnssec/ns3/secure.example.db.in
@@ -45,3 +45,8 @@ rrsigonly A 10.0.0.29
cnameandkey CNAME @
cnamenokey CNAME @
dnameandkey DNAME @
+
+mixedcase A 10.0.0.30
+mixedCASE TXT "mixed case"
+MIXEDcase AAAA 2002::
+mIxEdCaSe LOC 37 52 56.788 N 121 54 55.02 W 1120m 10m 100m 10m
diff --git a/bin/tests/system/dnssec/ns3/sign.sh b/bin/tests/system/dnssec/ns3/sign.sh
index 80d412e..d94f382 100644
--- a/bin/tests/system/dnssec/ns3/sign.sh
+++ b/bin/tests/system/dnssec/ns3/sign.sh
@@ -86,7 +86,9 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone
cat "$infile" "$cnameandkey.key" "$dnameandkey.key" "$keyname.key" > "$zonefile"
-"$SIGNER" -P -o "$zone" "$zonefile" > /dev/null
+"$SIGNER" -P -D -o "$zone" "$zonefile" >/dev/null
+cat "$zonefile" "$zonefile".signed >"$zonefile".tmp
+mv "$zonefile".tmp "$zonefile".signed
zone=bogus.example.
infile=bogus.example.db.in
diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh
index fe95c8d..0c03970 100644
--- a/bin/tests/system/dnssec/tests.sh
+++ b/bin/tests/system/dnssec/tests.sh
@@ -762,6 +762,21 @@ n=$((n+1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status+ret))
+echo_i "checking mixed-case positive validation ($n)"
+ret=0
+for type in a txt aaaa loc; do
+ dig_with_opts +noauth mixedcase.secure.example. \
+ @10.53.0.3 $type >dig.out.$type.ns3.test$n || ret=1
+ dig_with_opts +noauth mixedcase.secure.example. \
+ @10.53.0.4 $type >dig.out.$type.ns4.test$n || ret=1
+ digcomp --lc dig.out.$type.ns3.test$n dig.out.$type.ns4.test$n || ret=1
+ grep "status: NOERROR" dig.out.$type.ns4.test$n >/dev/null || ret=1
+ grep "flags:.*ad.*QUERY" dig.out.$type.ns4.test$n >/dev/null || ret=1
+done
+n=$((n + 1))
+test "$ret" -eq 0 || echo_i "failed"
+status=$((status + ret))
+
echo_i "checking multi-stage positive validation NSEC/NSEC3 ($n)"
ret=0
dig_with_opts +noauth a.nsec3.example. \
--
2.43.0

File diff suppressed because it is too large Load Diff

View File

@ -1,478 +0,0 @@
From c6e05ffc5fb784514ab54938867abaab41126c65 Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Mon, 12 Feb 2024 21:09:51 +0100
Subject: [PATCH] Prevent increased CPU consumption in DNSSEC validator
KeyTrap - Extreme CPU consumption in DNSSEC validator. Preparing an
NSEC3 closest encloser proof can exhaust CPU resources.
6322. [security] Specific DNS answers could cause a denial-of-service
condition due to DNS validation taking a long time.
(CVE-2023-50387) [GL #4424]
Resolves: CVE-2023-50387 CVE-2023-50868
---
lib/dns/dst_api.c | 27 +++++++++----
lib/dns/include/dns/validator.h | 1 +
lib/dns/include/dst/dst.h | 4 ++
lib/dns/resolver.c | 4 +-
lib/dns/validator.c | 67 +++++++++++++++------------------
lib/isc/include/isc/netmgr.h | 3 ++
lib/isc/netmgr/netmgr-int.h | 1 +
lib/isc/netmgr/netmgr.c | 36 +++++++++++-------
lib/isc/netmgr/tcp.c | 6 +--
lib/isc/netmgr/tcpdns.c | 4 +-
lib/isc/netmgr/udp.c | 6 +--
11 files changed, 91 insertions(+), 68 deletions(-)
diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c
index 62600dd..3aafd7c 100644
--- a/lib/dns/dst_api.c
+++ b/lib/dns/dst_api.c
@@ -160,7 +160,8 @@ computeid(dst_key_t *key);
static isc_result_t
frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
unsigned int protocol, dns_rdataclass_t rdclass,
- isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp);
+ isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
+ dst_key_t **keyp);
static isc_result_t
algorithm_status(unsigned int alg);
@@ -745,6 +746,13 @@ dst_key_todns(const dst_key_t *key, isc_buffer_t *target) {
isc_result_t
dst_key_fromdns(const dns_name_t *name, dns_rdataclass_t rdclass,
isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) {
+ return (dst_key_fromdns_ex(name, rdclass, source, mctx, false, keyp));
+}
+
+isc_result_t
+dst_key_fromdns_ex(const dns_name_t *name, dns_rdataclass_t rdclass,
+ isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
+ dst_key_t **keyp) {
uint8_t alg, proto;
uint32_t flags, extflags;
dst_key_t *key = NULL;
@@ -775,7 +783,7 @@ dst_key_fromdns(const dns_name_t *name, dns_rdataclass_t rdclass,
}
result = frombuffer(name, alg, flags, proto, rdclass, source, mctx,
- &key);
+ no_rdata, &key);
if (result != ISC_R_SUCCESS) {
return (result);
}
@@ -796,7 +804,7 @@ dst_key_frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
REQUIRE(dst_initialized);
result = frombuffer(name, alg, flags, protocol, rdclass, source, mctx,
- &key);
+ false, &key);
if (result != ISC_R_SUCCESS) {
return (result);
}
@@ -2288,7 +2296,8 @@ computeid(dst_key_t *key) {
static isc_result_t
frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
unsigned int protocol, dns_rdataclass_t rdclass,
- isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) {
+ isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
+ dst_key_t **keyp) {
dst_key_t *key;
isc_result_t ret;
@@ -2313,10 +2322,12 @@ frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
return (DST_R_UNSUPPORTEDALG);
}
- ret = key->func->fromdns(key, source);
- if (ret != ISC_R_SUCCESS) {
- dst_key_free(&key);
- return (ret);
+ if (!no_rdata) {
+ ret = key->func->fromdns(key, source);
+ if (ret != ISC_R_SUCCESS) {
+ dst_key_free(&key);
+ return (ret);
+ }
}
}
diff --git a/lib/dns/include/dns/validator.h b/lib/dns/include/dns/validator.h
index 4744014..fe97e41 100644
--- a/lib/dns/include/dns/validator.h
+++ b/lib/dns/include/dns/validator.h
@@ -148,6 +148,7 @@ struct dns_validator {
unsigned int authcount;
unsigned int authfail;
isc_stdtime_t start;
+ bool failed;
};
/*%
diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h
index f454ebb..36770b5 100644
--- a/lib/dns/include/dst/dst.h
+++ b/lib/dns/include/dst/dst.h
@@ -469,6 +469,10 @@ dst_key_tofile(const dst_key_t *key, int type, const char *directory);
*/
isc_result_t
+dst_key_fromdns_ex(const dns_name_t *name, dns_rdataclass_t rdclass,
+ isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
+ dst_key_t **keyp);
+isc_result_t
dst_key_fromdns(const dns_name_t *name, dns_rdataclass_t rdclass,
isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp);
/*%<
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 7cbfbb2..be1d735 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -10613,8 +10613,8 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
* Since we have a pool of tasks we bind them to task queues
* to spread the load evenly
*/
- result = isc_task_create_bound(taskmgr, 0,
- &res->buckets[i].task, i);
+ result = isc_task_create_bound(
+ taskmgr, 0, &res->buckets[i].task, ISC_NM_TASK_SLOW(i));
if (result != ISC_R_SUCCESS) {
isc_mutex_destroy(&res->buckets[i].lock);
goto cleanup_buckets;
diff --git a/lib/dns/validator.c b/lib/dns/validator.c
index e54fc70..e416cc9 100644
--- a/lib/dns/validator.c
+++ b/lib/dns/validator.c
@@ -1098,8 +1098,8 @@ create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
* 'rdataset'. If found, build a dst_key_t for it and point val->key at
* it.
*
- * If val->key is already non-NULL, locate it in the rdataset and then
- * search past it for the *next* key that could have signed 'siginfo', then
+ * If val->key is already non-NULL, start searching from the next position in
+ * 'rdataset' to find the *next* key that could have signed 'siginfo', then
* set val->key to that.
*
* Returns ISC_R_SUCCESS if a possible matching key has been found,
@@ -1112,59 +1112,59 @@ select_signing_key(dns_validator_t *val, dns_rdataset_t *rdataset) {
isc_buffer_t b;
dns_rdata_t rdata = DNS_RDATA_INIT;
dst_key_t *oldkey = val->key;
- bool foundold;
+ bool no_rdata = false;
if (oldkey == NULL) {
- foundold = true;
+ result = dns_rdataset_first(rdataset);
} else {
- foundold = false;
+ dst_key_free(&oldkey);
val->key = NULL;
+ result = dns_rdataset_next(rdataset);
}
-
- result = dns_rdataset_first(rdataset);
if (result != ISC_R_SUCCESS) {
- goto failure;
+ goto done;
}
+
do {
dns_rdataset_current(rdataset, &rdata);
isc_buffer_init(&b, rdata.data, rdata.length);
isc_buffer_add(&b, rdata.length);
INSIST(val->key == NULL);
- result = dst_key_fromdns(&siginfo->signer, rdata.rdclass, &b,
- val->view->mctx, &val->key);
+ result = dst_key_fromdns_ex(&siginfo->signer, rdata.rdclass, &b,
+ val->view->mctx, no_rdata,
+ &val->key);
if (result == ISC_R_SUCCESS) {
if (siginfo->algorithm ==
(dns_secalg_t)dst_key_alg(val->key) &&
siginfo->keyid ==
(dns_keytag_t)dst_key_id(val->key) &&
+ (dst_key_flags(val->key) & DNS_KEYFLAG_REVOKE) ==
+ 0 &&
dst_key_iszonekey(val->key))
{
- if (foundold) {
- /*
- * This is the key we're looking for.
- */
- return (ISC_R_SUCCESS);
- } else if (dst_key_compare(oldkey, val->key)) {
- foundold = true;
- dst_key_free(&oldkey);
+ if (no_rdata) {
+ /* Retry with full key */
+ dns_rdata_reset(&rdata);
+ dst_key_free(&val->key);
+ no_rdata = false;
+ continue;
}
+ /* This is the key we're looking for. */
+ goto done;
}
dst_key_free(&val->key);
}
dns_rdata_reset(&rdata);
result = dns_rdataset_next(rdataset);
+ no_rdata = true;
} while (result == ISC_R_SUCCESS);
+done:
if (result == ISC_R_NOMORE) {
result = ISC_R_NOTFOUND;
}
-failure:
- if (oldkey != NULL) {
- dst_key_free(&oldkey);
- }
-
return (result);
}
@@ -1557,20 +1557,9 @@ validate_answer(dns_validator_t *val, bool resume) {
continue;
}
- do {
- isc_result_t tresult;
- vresult = verify(val, val->key, &rdata,
- val->siginfo->keyid);
- if (vresult == ISC_R_SUCCESS) {
- break;
- }
-
- tresult = select_signing_key(val, val->keyset);
- if (tresult != ISC_R_SUCCESS) {
- break;
- }
- } while (1);
+ vresult = verify(val, val->key, &rdata, val->siginfo->keyid);
if (vresult != ISC_R_SUCCESS) {
+ val->failed = true;
validator_log(val, ISC_LOG_DEBUG(3),
"failed to verify rdataset");
} else {
@@ -1607,9 +1596,13 @@ validate_answer(dns_validator_t *val, bool resume) {
} else {
validator_log(val, ISC_LOG_DEBUG(3),
"verify failure: %s",
- isc_result_totext(result));
+ isc_result_totext(vresult));
resume = false;
}
+ if (val->failed) {
+ result = ISC_R_NOMORE;
+ break;
+ }
}
if (result != ISC_R_NOMORE) {
validator_log(val, ISC_LOG_DEBUG(3),
diff --git a/lib/isc/include/isc/netmgr.h b/lib/isc/include/isc/netmgr.h
index be9fd56..dfabdc8 100644
--- a/lib/isc/include/isc/netmgr.h
+++ b/lib/isc/include/isc/netmgr.h
@@ -455,6 +455,9 @@ isc_nm_tcpdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
* 'cb'.
*/
+#define ISC_NM_TASK_SLOW_OFFSET -2
+#define ISC_NM_TASK_SLOW(i) (ISC_NM_TASK_SLOW_OFFSET - 1 - i)
+
void
isc_nm_task_enqueue(isc_nm_t *mgr, isc_task_t *task, int threadid);
/*%<
diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h
index f7b54f9..70bb32d 100644
--- a/lib/isc/netmgr/netmgr-int.h
+++ b/lib/isc/netmgr/netmgr-int.h
@@ -673,6 +673,7 @@ struct isc_nm {
#ifdef NETMGR_TRACE
ISC_LIST(isc_nmsocket_t) active_sockets;
#endif
+ int nlisteners;
};
typedef enum isc_nmsocket_type {
diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c
index 0ed3182..898de41 100644
--- a/lib/isc/netmgr/netmgr.c
+++ b/lib/isc/netmgr/netmgr.c
@@ -269,31 +269,34 @@ isc__nm_winsock_destroy(void) {
#endif /* WIN32 */
static void
-isc__nm_threadpool_initialize(uint32_t workers) {
+isc__nm_threadpool_initialize(uint32_t nworkers) {
char buf[11];
int r = uv_os_getenv("UV_THREADPOOL_SIZE", buf,
&(size_t){ sizeof(buf) });
if (r == UV_ENOENT) {
- snprintf(buf, sizeof(buf), "%" PRIu32, workers);
+ snprintf(buf, sizeof(buf), "%" PRIu32, nworkers);
uv_os_setenv("UV_THREADPOOL_SIZE", buf);
}
}
void
-isc__netmgr_create(isc_mem_t *mctx, uint32_t workers, isc_nm_t **netmgrp) {
+isc__netmgr_create(isc_mem_t *mctx, uint32_t nworkers, isc_nm_t **netmgrp) {
isc_nm_t *mgr = NULL;
char name[32];
- REQUIRE(workers > 0);
+ REQUIRE(nworkers > 0);
#ifdef WIN32
isc__nm_winsock_initialize();
#endif /* WIN32 */
- isc__nm_threadpool_initialize(workers);
+ isc__nm_threadpool_initialize(nworkers);
mgr = isc_mem_get(mctx, sizeof(*mgr));
- *mgr = (isc_nm_t){ .nworkers = workers };
+ *mgr = (isc_nm_t){
+ .nworkers = nworkers * 2,
+ .nlisteners = nworkers,
+ };
isc_mem_attach(mctx, &mgr->mctx);
isc_mutex_init(&mgr->lock);
@@ -334,11 +337,12 @@ isc__netmgr_create(isc_mem_t *mctx, uint32_t workers, isc_nm_t **netmgrp) {
isc_mempool_associatelock(mgr->evpool, &mgr->evlock);
isc_mempool_setfillcount(mgr->evpool, 32);
- isc_barrier_init(&mgr->pausing, workers);
- isc_barrier_init(&mgr->resuming, workers);
+ isc_barrier_init(&mgr->pausing, mgr->nworkers);
+ isc_barrier_init(&mgr->resuming, mgr->nworkers);
- mgr->workers = isc_mem_get(mctx, workers * sizeof(isc__networker_t));
- for (size_t i = 0; i < workers; i++) {
+ mgr->workers = isc_mem_get(mctx,
+ mgr->nworkers * sizeof(isc__networker_t));
+ for (int i = 0; i < mgr->nworkers; i++) {
int r;
isc__networker_t *worker = &mgr->workers[i];
*worker = (isc__networker_t){
@@ -373,7 +377,7 @@ isc__netmgr_create(isc_mem_t *mctx, uint32_t workers, isc_nm_t **netmgrp) {
mgr->workers_running++;
isc_thread_create(nm_thread, &mgr->workers[i], &worker->thread);
- snprintf(name, sizeof(name), "isc-net-%04zu", i);
+ snprintf(name, sizeof(name), "isc-net-%04d", i);
isc_thread_setname(worker->thread, name);
}
@@ -848,9 +852,15 @@ isc_nm_task_enqueue(isc_nm_t *nm, isc_task_t *task, int threadid) {
isc__networker_t *worker = NULL;
if (threadid == -1) {
- tid = (int)isc_random_uniform(nm->nworkers);
+ tid = (int)isc_random_uniform(nm->nlisteners);
+ } else if (threadid == ISC_NM_TASK_SLOW_OFFSET) {
+ tid = nm->nlisteners +
+ (int)isc_random_uniform(nm->nworkers - nm->nlisteners);
+ } else if (threadid < ISC_NM_TASK_SLOW_OFFSET) {
+ tid = nm->nlisteners + (ISC_NM_TASK_SLOW(threadid) %
+ (nm->nworkers - nm->nlisteners));
} else {
- tid = threadid % nm->nworkers;
+ tid = threadid % nm->nlisteners;
}
worker = &nm->workers[tid];
diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c
index 5cca9f5..83bd2e2 100644
--- a/lib/isc/netmgr/tcp.c
+++ b/lib/isc/netmgr/tcp.c
@@ -321,7 +321,7 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
isc__nm_connectcb(sock, req, result, false);
} else {
isc__nmsocket_clearcb(sock);
- sock->tid = isc_random_uniform(mgr->nworkers);
+ sock->tid = isc_random_uniform(mgr->nlisteners);
isc__nm_connectcb(sock, req, result, true);
}
atomic_store(&sock->closed, true);
@@ -339,7 +339,7 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
isc__nm_put_netievent_tcpconnect(mgr, ievent);
} else {
atomic_init(&sock->active, false);
- sock->tid = isc_random_uniform(mgr->nworkers);
+ sock->tid = isc_random_uniform(mgr->nlisteners);
isc__nm_enqueue_ievent(&mgr->workers[sock->tid],
(isc__netievent_t *)ievent);
}
@@ -435,7 +435,7 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_sockaddr_t *iface,
#if defined(WIN32)
sock->nchildren = 1;
#else
- sock->nchildren = mgr->nworkers;
+ sock->nchildren = mgr->nlisteners;
#endif
children_size = sock->nchildren * sizeof(sock->children[0]);
sock->children = isc_mem_get(mgr->mctx, children_size);
diff --git a/lib/isc/netmgr/tcpdns.c b/lib/isc/netmgr/tcpdns.c
index 188790c..7f13ab2 100644
--- a/lib/isc/netmgr/tcpdns.c
+++ b/lib/isc/netmgr/tcpdns.c
@@ -305,7 +305,7 @@ isc_nm_tcpdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
isc__nm_put_netievent_tcpdnsconnect(mgr, ievent);
} else {
atomic_init(&sock->active, false);
- sock->tid = isc_random_uniform(mgr->nworkers);
+ sock->tid = isc_random_uniform(mgr->nlisteners);
isc__nm_enqueue_ievent(&mgr->workers[sock->tid],
(isc__netievent_t *)ievent);
}
@@ -404,7 +404,7 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_sockaddr_t *iface,
#if defined(WIN32)
sock->nchildren = 1;
#else
- sock->nchildren = mgr->nworkers;
+ sock->nchildren = mgr->nlisteners;
#endif
children_size = sock->nchildren * sizeof(sock->children[0]);
sock->children = isc_mem_get(mgr->mctx, children_size);
diff --git a/lib/isc/netmgr/udp.c b/lib/isc/netmgr/udp.c
index a91c425..f2e161c 100644
--- a/lib/isc/netmgr/udp.c
+++ b/lib/isc/netmgr/udp.c
@@ -126,7 +126,7 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_sockaddr_t *iface, isc_nm_recv_cb_t cb,
uv_os_sock_t fd = -1;
/*
- * We are creating mgr->nworkers duplicated sockets, one
+ * We are creating mgr->nlisteners duplicated sockets, one
* socket for each worker thread.
*/
sock = isc_mem_get(mgr->mctx, sizeof(isc_nmsocket_t));
@@ -136,7 +136,7 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_sockaddr_t *iface, isc_nm_recv_cb_t cb,
#if defined(WIN32)
sock->nchildren = 1;
#else
- sock->nchildren = mgr->nworkers;
+ sock->nchildren = mgr->nlisteners;
#endif
children_size = sock->nchildren * sizeof(sock->children[0]);
@@ -795,7 +795,7 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
isc__nm_put_netievent_udpconnect(mgr, event);
} else {
atomic_init(&sock->active, false);
- sock->tid = isc_random_uniform(mgr->nworkers);
+ sock->tid = isc_random_uniform(mgr->nlisteners);
isc__nm_enqueue_ievent(&mgr->workers[sock->tid],
(isc__netievent_t *)event);
}
--
2.43.0

View File

@ -1,111 +0,0 @@
From bef141d5795429cab745f29f7d080d1e2ea8f164 Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Mon, 12 Feb 2024 20:33:41 +0100
Subject: [PATCH] Prevent assertion failure when nxdomain-redirect is used with
RFC 1918 reverse zones
6316. [security] Specific queries could trigger an assertion check with
nxdomain-redirect enabled. (CVE-2023-5517) [GL #4281]
---
lib/ns/query.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/lib/ns/query.c b/lib/ns/query.c
index 4fe3e30..cc1d179 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -453,10 +453,10 @@ static void
query_addnxrrsetnsec(query_ctx_t *qctx);
static isc_result_t
-query_nxdomain(query_ctx_t *qctx, bool empty_wild);
+query_nxdomain(query_ctx_t *qctx, isc_result_t result);
static isc_result_t
-query_redirect(query_ctx_t *qctx);
+query_redirect(query_ctx_t *qctx, isc_result_t result);
static isc_result_t
query_ncache(query_ctx_t *qctx, isc_result_t result);
@@ -7262,8 +7262,7 @@ query_usestale(query_ctx_t *qctx, isc_result_t result) {
* result from the search.
*/
static isc_result_t
-query_gotanswer(query_ctx_t *qctx, isc_result_t res) {
- isc_result_t result = res;
+query_gotanswer(query_ctx_t *qctx, isc_result_t result) {
char errmsg[256];
CCTRACE(ISC_LOG_DEBUG(3), "query_gotanswer");
@@ -7333,16 +7332,16 @@ root_key_sentinel:
return (query_nodata(qctx, DNS_R_NXRRSET));
case DNS_R_EMPTYWILD:
- return (query_nxdomain(qctx, true));
+ return (query_nxdomain(qctx, DNS_R_EMPTYWILD));
case DNS_R_NXDOMAIN:
- return (query_nxdomain(qctx, false));
+ return (query_nxdomain(qctx, DNS_R_NXDOMAIN));
case DNS_R_COVERINGNSEC:
return (query_coveringnsec(qctx));
case DNS_R_NCACHENXDOMAIN:
- result = query_redirect(qctx);
+ result = query_redirect(qctx, result);
if (result != ISC_R_COMPLETE) {
return (result);
}
@@ -9155,10 +9154,10 @@ query_addnxrrsetnsec(query_ctx_t *qctx) {
* Handle NXDOMAIN and empty wildcard responses.
*/
static isc_result_t
-query_nxdomain(query_ctx_t *qctx, bool empty_wild) {
+query_nxdomain(query_ctx_t *qctx, isc_result_t result) {
dns_section_t section;
uint32_t ttl;
- isc_result_t result;
+ bool empty_wild = (result == DNS_R_EMPTYWILD);
CCTRACE(ISC_LOG_DEBUG(3), "query_nxdomain");
@@ -9167,7 +9166,7 @@ query_nxdomain(query_ctx_t *qctx, bool empty_wild) {
INSIST(qctx->is_zone || REDIRECT(qctx->client));
if (!empty_wild) {
- result = query_redirect(qctx);
+ result = query_redirect(qctx, result);
if (result != ISC_R_COMPLETE) {
return (result);
}
@@ -9253,7 +9252,7 @@ cleanup:
* redirecting, so query processing should continue past it.
*/
static isc_result_t
-query_redirect(query_ctx_t *qctx) {
+query_redirect(query_ctx_t *qctx, isc_result_t saved_result) {
isc_result_t result;
CCTRACE(ISC_LOG_DEBUG(3), "query_redirect");
@@ -9294,7 +9293,7 @@ query_redirect(query_ctx_t *qctx) {
SAVE(qctx->client->query.redirect.rdataset, qctx->rdataset);
SAVE(qctx->client->query.redirect.sigrdataset,
qctx->sigrdataset);
- qctx->client->query.redirect.result = DNS_R_NCACHENXDOMAIN;
+ qctx->client->query.redirect.result = saved_result;
dns_name_copynf(qctx->fname,
qctx->client->query.redirect.fname);
qctx->client->query.redirect.authoritative =
@@ -9908,7 +9907,7 @@ query_coveringnsec(query_ctx_t *qctx) {
* We now have the proof that we have an NXDOMAIN. Apply
* NXDOMAIN redirection if configured.
*/
- result = query_redirect(qctx);
+ result = query_redirect(qctx, DNS_R_COVERINGNSEC);
if (result != ISC_R_COMPLETE) {
redirected = true;
goto cleanup;
--
2.43.0

View File

@ -1,37 +0,0 @@
From 61112d1ce39848e08ec133f280cf8f729cb70d16 Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Mon, 12 Feb 2024 20:41:43 +0100
Subject: [PATCH] Prevent assertion failure if DNS64 and serve-stale is used
Enabling both DNS64 and serve-stale may cause an assertion failure
during recursive resolution.
6317. [security] Restore DNS64 state when handling a serve-stale timeout.
(CVE-2023-5679) [GL #4334]
Resolves: CVE-2023-5679
---
lib/ns/query.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/lib/ns/query.c b/lib/ns/query.c
index cc1d179..1993800 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -5983,6 +5983,13 @@ query_lookup_stale(ns_client_t *client) {
query_ctx_t qctx;
qctx_init(client, NULL, client->query.qtype, &qctx);
+ if (DNS64(client)) {
+ qctx.qtype = qctx.type = dns_rdatatype_a;
+ qctx.dns64 = true;
+ }
+ if (DNS64EXCLUDE(client)) {
+ qctx.dns64_exclude = true;
+ }
dns_db_attach(client->view->cachedb, &qctx.db);
client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK;
client->query.dboptions |= DNS_DBFIND_STALETIMEOUT;
--
2.43.0

View File

@ -1,52 +0,0 @@
From e91ab7758bed0cf3dcf8ed745f91063d7ec4011c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= <michal@isc.org>
Date: Thu, 4 Jan 2024 13:39:27 +0100
Subject: [PATCH] Fix map offsets in the "masterformat" system test
The "masterformat" system test attempts to check named-checkzone
behavior when it is fed corrupt map-format zone files. However, despite
the RBTDB and RBT structures having evolved over the years, the offsets
at which a valid map-format zone file is malformed by the "masterformat"
test have not been updated accordingly, causing the relevant checks to
introduce a different type of corruption than they were originally meant
to cause:
- the "bad node header" check originally mangled the 'type' member of
the rdatasetheader_t structure for cname.example.nil,
- the "bad node data" check originally mangled the 'serial' and
'rdh_ttl' members of the rdatasetheader_t structure for
aaaa.example.nil.
Update the offsets at which the map-format zone file is malformed at by
the "masterformat" system test so that the relevant checks fulfill their
original purpose again.
---
bin/tests/system/masterformat/tests.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/bin/tests/system/masterformat/tests.sh b/bin/tests/system/masterformat/tests.sh
index 364a0d2..bb4e6ec 100755
--- a/bin/tests/system/masterformat/tests.sh
+++ b/bin/tests/system/masterformat/tests.sh
@@ -295,7 +295,7 @@ status=$((status+ret))
echo_i "checking corrupt map files fail to load (bad node header) ($n)"
ret=0
cp map.5 badmap
-stomp badmap 2754 2 99
+stomp badmap 3706 2 99
$CHECKZONE -D -f map -F text -o text.5 example.nil badmap > /dev/null
[ $? = 1 ] || ret=1
n=$((n+1))
@@ -305,7 +305,7 @@ status=$((status+ret))
echo_i "checking corrupt map files fail to load (bad node data) ($n)"
ret=0
cp map.5 badmap
-stomp badmap 2897 5 127
+stomp badmap 3137 5 127
$CHECKZONE -D -f map -F text -o text.5 example.nil badmap > /dev/null
[ $? = 1 ] || ret=1
n=$((n+1))
--
2.44.0

View File

@ -1,283 +0,0 @@
From 6e08fef24d7ba491228a4083ea0f0e33253a1043 Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Mon, 12 Feb 2024 20:48:57 +0100
Subject: [PATCH] Specific recursive query patterns may lead to an
out-of-memory condition
6319. [security] Query patterns that continuously triggered cache
database maintenance could exhaust all available memory
on the host running named. (CVE-2023-6516) [GL #4383]
Resolves: CVE-2023-6516
---
lib/dns/include/dns/rbt.h | 6 ++
lib/dns/mapapi | 2 +-
lib/dns/rbt.c | 1 +
lib/dns/rbtdb.c | 149 +++++++++++++++++++++++++-------------
4 files changed, 107 insertions(+), 51 deletions(-)
diff --git a/lib/dns/include/dns/rbt.h b/lib/dns/include/dns/rbt.h
index b67e602..69655b0 100644
--- a/lib/dns/include/dns/rbt.h
+++ b/lib/dns/include/dns/rbt.h
@@ -164,6 +164,12 @@ struct dns_rbtnode {
uint16_t locknum; /* note that this is not in the bitfield */
isc_refcount_t references;
/*@}*/
+
+ /*%
+ * This linked list is used to store nodes from which tree pruning can
+ * be started.
+ */
+ ISC_LINK(dns_rbtnode_t) prunelink;
};
typedef isc_result_t (*dns_rbtfindcallback_t)(dns_rbtnode_t *node,
diff --git a/lib/dns/mapapi b/lib/dns/mapapi
index 1b502d3..a46e190 100644
--- a/lib/dns/mapapi
+++ b/lib/dns/mapapi
@@ -13,4 +13,4 @@
# Whenever releasing a new major release of BIND9, set this value
# back to 1.0 when releasing the first alpha. Map files are *never*
# compatible across major releases.
-MAPAPI=3.0
+MAPAPI=4.0
diff --git a/lib/dns/rbt.c b/lib/dns/rbt.c
index 7f2c2d2..a220368 100644
--- a/lib/dns/rbt.c
+++ b/lib/dns/rbt.c
@@ -2283,6 +2283,7 @@ create_node(isc_mem_t *mctx, const dns_name_t *name, dns_rbtnode_t **nodep) {
HASHVAL(node) = 0;
ISC_LINK_INIT(node, deadlink);
+ ISC_LINK_INIT(node, prunelink);
LOCKNUM(node) = 0;
WILD(node) = 0;
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index 75f97f5..2707507 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -515,6 +515,10 @@ struct dns_rbtdb {
*/
rbtnodelist_t *deadnodes;
+ /* List of nodes from which recursive tree pruning can be started from.
+ * Locked by tree_lock. */
+ rbtnodelist_t prunenodes;
+
/*
* Heaps. These are used for TTL based expiry in a cache,
* or for zone resigning in a zone DB. hmctx is the memory
@@ -1060,6 +1064,7 @@ free_rbtdb(dns_rbtdb_t *rbtdb, bool log, isc_event_t *event) {
unsigned int i;
isc_result_t result;
char buf[DNS_NAME_FORMATSIZE];
+ dns_rbtnode_t *node = NULL;
dns_rbt_t **treep;
isc_time_t start;
dns_dbonupdatelistener_t *listener, *listener_next;
@@ -1086,8 +1091,6 @@ free_rbtdb(dns_rbtdb_t *rbtdb, bool log, isc_event_t *event) {
* the overhead of unlinking all nodes here should be negligible.
*/
for (i = 0; i < rbtdb->node_lock_count; i++) {
- dns_rbtnode_t *node;
-
node = ISC_LIST_HEAD(rbtdb->deadnodes[i]);
while (node != NULL) {
ISC_LIST_UNLINK(rbtdb->deadnodes[i], node, deadlink);
@@ -1095,6 +1098,12 @@ free_rbtdb(dns_rbtdb_t *rbtdb, bool log, isc_event_t *event) {
}
}
+ node = ISC_LIST_HEAD(rbtdb->prunenodes);
+ while (node != NULL) {
+ ISC_LIST_UNLINK(rbtdb->prunenodes, node, prunelink);
+ node = ISC_LIST_HEAD(rbtdb->prunenodes);
+ }
+
if (event == NULL) {
rbtdb->quantum = (rbtdb->task != NULL) ? 100 : 0;
}
@@ -1934,19 +1943,32 @@ is_leaf(dns_rbtnode_t *node) {
node->left == NULL && node->right == NULL);
}
+/*%
+ * The tree lock must be held when this function is called as it reads and
+ * updates rbtdb->prunenodes.
+ */
static inline void
send_to_prune_tree(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
isc_rwlocktype_t locktype) {
- isc_event_t *ev;
- dns_db_t *db;
+ bool pruning_queued = (ISC_LIST_HEAD(rbtdb->prunenodes) != NULL);
+
+ INSIST(locktype == isc_rwlocktype_write);
- ev = isc_event_allocate(rbtdb->common.mctx, NULL, DNS_EVENT_RBTPRUNE,
- prune_tree, node, sizeof(isc_event_t));
new_reference(rbtdb, node, locktype);
- db = NULL;
- attach((dns_db_t *)rbtdb, &db);
- ev->ev_sender = db;
- isc_task_send(rbtdb->task, &ev);
+ INSIST(!ISC_LINK_LINKED(node, prunelink));
+ ISC_LIST_APPEND(rbtdb->prunenodes, node, prunelink);
+
+ if (!pruning_queued) {
+ isc_event_t *ev = NULL;
+ dns_db_t *db = NULL;
+
+ attach((dns_db_t *)rbtdb, &db);
+
+ ev = isc_event_allocate(rbtdb->common.mctx, NULL,
+ DNS_EVENT_RBTPRUNE, prune_tree, db,
+ sizeof(isc_event_t));
+ isc_task_send(rbtdb->task, &ev);
+ }
}
/*%
@@ -2220,17 +2242,26 @@ restore_locks:
}
/*
- * Prune the tree by recursively cleaning-up single leaves. In the worst
- * case, the number of iteration is the number of tree levels, which is at
- * most the maximum number of domain name labels, i.e, 127. In practice, this
- * should be much smaller (only a few times), and even the worst case would be
- * acceptable for a single event.
+ * Prune the tree by recursively cleaning up single leaves. Go through all
+ * nodes stored in the rbtdb->prunenodes list; for each of them, in the worst
+ * case, it will be necessary to traverse a number of tree levels equal to the
+ * maximum legal number of domain name labels (127); in practice, the number of
+ * tree levels to traverse will virtually always be much smaller (a few levels
+ * at most). While holding the tree lock throughout this entire operation is
+ * less than ideal, so is splitting the latter up by queueing a separate
+ * prune_tree() run for each node to start pruning from (as queueing requires
+ * allocating memory and can therefore potentially be exploited to exhaust
+ * available memory). Also note that actually freeing up the memory used by
+ * RBTDB nodes (which is what this function does) is essential to keeping cache
+ * memory use in check, so since the tree lock needs to be acquired anyway,
+ * freeing as many nodes as possible before the tree lock gets released is
+ * prudent.
*/
static void
prune_tree(isc_task_t *task, isc_event_t *event) {
- dns_rbtdb_t *rbtdb = event->ev_sender;
- dns_rbtnode_t *node = event->ev_arg;
- dns_rbtnode_t *parent;
+ dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)event->ev_arg;
+ dns_rbtnode_t *node = NULL;
+ dns_rbtnode_t *parent = NULL;
unsigned int locknum;
UNUSED(task);
@@ -2238,44 +2269,60 @@ prune_tree(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
- locknum = node->locknum;
- NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write);
- do {
- parent = node->parent;
- decrement_reference(rbtdb, node, 0, isc_rwlocktype_write,
- isc_rwlocktype_write, true);
- if (parent != NULL && parent->down == NULL) {
- /*
- * node was the only down child of the parent and has
- * just been removed. We'll then need to examine the
- * parent. Keep the lock if possible; otherwise,
- * release the old lock and acquire one for the parent.
- */
- if (parent->locknum != locknum) {
- NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
- isc_rwlocktype_write);
- locknum = parent->locknum;
- NODE_LOCK(&rbtdb->node_locks[locknum].lock,
- isc_rwlocktype_write);
+ while ((node = ISC_LIST_HEAD(rbtdb->prunenodes)) != NULL) {
+ locknum = node->locknum;
+ NODE_LOCK(&rbtdb->node_locks[locknum].lock,
+ isc_rwlocktype_write);
+ do {
+ if (ISC_LINK_LINKED(node, prunelink)) {
+ ISC_LIST_UNLINK(rbtdb->prunenodes, node,
+ prunelink);
}
- /*
- * We need to gain a reference to the node before
- * decrementing it in the next iteration.
- */
- if (ISC_LINK_LINKED(parent, deadlink)) {
- ISC_LIST_UNLINK(rbtdb->deadnodes[locknum],
+ parent = node->parent;
+ decrement_reference(rbtdb, node, 0,
+ isc_rwlocktype_write,
+ isc_rwlocktype_write, true);
+
+ if (parent != NULL && parent->down == NULL) {
+ /*
+ * node was the only down child of the parent
+ * and has just been removed. We'll then need
+ * to examine the parent. Keep the lock if
+ * possible; otherwise, release the old lock and
+ * acquire one for the parent.
+ */
+ if (parent->locknum != locknum) {
+ NODE_UNLOCK(
+ &rbtdb->node_locks[locknum].lock,
+ isc_rwlocktype_write);
+ locknum = parent->locknum;
+ NODE_LOCK(
+ &rbtdb->node_locks[locknum].lock,
+ isc_rwlocktype_write);
+ }
+
+ /*
+ * We need to gain a reference to the node
+ * before decrementing it in the next iteration.
+ */
+ if (ISC_LINK_LINKED(parent, deadlink)) {
+ ISC_LIST_UNLINK(
+ rbtdb->deadnodes[locknum],
parent, deadlink);
+ }
+ new_reference(rbtdb, parent,
+ isc_rwlocktype_write);
+ } else {
+ parent = NULL;
}
- new_reference(rbtdb, parent, isc_rwlocktype_write);
- } else {
- parent = NULL;
- }
- node = parent;
- } while (node != NULL);
- NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write);
+ node = parent;
+ } while (node != NULL);
+ NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
+ isc_rwlocktype_write);
+ }
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
detach((dns_db_t **)&rbtdb);
@@ -8726,6 +8773,8 @@ dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
ISC_LIST_INIT(rbtdb->deadnodes[i]);
}
+ ISC_LIST_INIT(rbtdb->prunenodes);
+
rbtdb->active = rbtdb->node_lock_count;
for (i = 0; i < (int)(rbtdb->node_lock_count); i++) {
--
2.43.0

View File

@ -1,4 +1,4 @@
From 460116952fe7f8ad684ca6248fc4d87c11c9d4a0 Mon Sep 17 00:00:00 2001
From 6a6f31df4c3c2a886fc6df75381d72b13eb4c024 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Thu, 23 May 2024 19:12:40 +0200
Subject: [PATCH] Add test for not-loading and not-transfering huge RRSets
@ -20,7 +20,6 @@ succeed when the cap is disabled.
(cherry picked from commit 8e3efb4e06ba68cc3f9bc5be2bacb2596bd74cb3)
(cherry picked from commit 4a0fe202a906e32d3316d161fff053d3b1737a18)
---
bin/tests/system/conf.sh.common | 1 +
bin/tests/system/limits/ns1/named.conf.in | 1 +
bin/tests/system/masterformat/clean.sh | 2 +
bin/tests/system/masterformat/ns1/compile.sh | 2 +
@ -29,36 +28,24 @@ succeed when the cap is disabled.
bin/tests/system/masterformat/ns1/uber.db.in | 22 +
.../system/masterformat/ns2/named.conf.in | 8 +
bin/tests/system/masterformat/setup.sh | 19 +-
bin/tests/system/masterformat/tests.sh | 64 +-
bin/tests/system/masterformat/tests.sh | 60 +
bin/tests/system/reclimit/ns1/big.db | 2515 +++++++++++++++++
bin/tests/system/reclimit/ns1/named.conf.in | 6 +
bin/tests/system/reclimit/ns1/root.db | 3 +
bin/tests/system/reclimit/ns3/named5.conf.in | 42 +
bin/tests/system/reclimit/tests.sh | 12 +-
bin/tests/system/resolver/tests.sh | 3 +-
16 files changed, 2729 insertions(+), 8 deletions(-)
15 files changed, 2728 insertions(+), 4 deletions(-)
create mode 100644 bin/tests/system/masterformat/ns1/huge.db.in
create mode 100644 bin/tests/system/masterformat/ns1/uber.db.in
create mode 100644 bin/tests/system/reclimit/ns1/big.db
create mode 100644 bin/tests/system/reclimit/ns3/named5.conf.in
diff --git a/bin/tests/system/conf.sh.common b/bin/tests/system/conf.sh.common
index 61edca2d21..9fab00ff5c 100644
--- a/bin/tests/system/conf.sh.common
+++ b/bin/tests/system/conf.sh.common
@@ -710,6 +710,7 @@ copy_setports() {
-e "s/${atsign}ALTERNATIVE_ALGORITHM${atsign}/${ALTERNATIVE_ALGORITHM}/g" \
-e "s/${atsign}ALTERNATIVE_ALGORITHM_NUMBER${atsign}/${ALTERNATIVE_ALGORITHM_NUMBER}/g" \
-e "s/${atsign}ALTERNATIVE_BITS${atsign}/${ALTERNATIVE_BITS}/g" \
+ -e "s/${atsign}DEFAULT_HMAC${atsign}/${DEFAULT_HMAC}/g" \
-e "s/${atsign}DISABLED_ALGORITHM${atsign}/${DISABLED_ALGORITHM}/g" \
-e "s/${atsign}DISABLED_ALGORITHM_NUMBER${atsign}/${DISABLED_ALGORITHM_NUMBER}/g" \
-e "s/${atsign}DISABLED_BITS${atsign}/${DISABLED_BITS}/g" \
diff --git a/bin/tests/system/limits/ns1/named.conf.in b/bin/tests/system/limits/ns1/named.conf.in
index a2724a4d30..59c30b4c37 100644
index 118fdbd9b1..cf0aa783b1 100644
--- a/bin/tests/system/limits/ns1/named.conf.in
+++ b/bin/tests/system/limits/ns1/named.conf.in
@@ -20,6 +20,7 @@ options {
@@ -22,6 +22,7 @@ options {
recursion no;
notify yes;
minimal-responses no;
@ -67,10 +54,10 @@ index a2724a4d30..59c30b4c37 100644
zone "." {
diff --git a/bin/tests/system/masterformat/clean.sh b/bin/tests/system/masterformat/clean.sh
index 82502fc430..a9183af6ff 100755
index c53c7ab4bc..c606c6183a 100755
--- a/bin/tests/system/masterformat/clean.sh
+++ b/bin/tests/system/masterformat/clean.sh
@@ -14,6 +14,8 @@ rm -f ./ns1/example.db.compat
@@ -16,6 +16,8 @@ rm -f ./ns1/example.db.compat
rm -f ./ns1/example.db.serial.raw
rm -f ./ns1/large.db ./ns1/large.db.raw
rm -f ./ns1/example.db.map ./ns1/signed.db.map
@ -80,18 +67,18 @@ index 82502fc430..a9183af6ff 100755
rm -f ./dig.out.*
rm -f ./dig.out
diff --git a/bin/tests/system/masterformat/ns1/compile.sh b/bin/tests/system/masterformat/ns1/compile.sh
index 7d35986117..9972e51aa4 100755
index ad24bb3201..34279547a0 100755
--- a/bin/tests/system/masterformat/ns1/compile.sh
+++ b/bin/tests/system/masterformat/ns1/compile.sh
@@ -27,6 +27,8 @@ $CHECKZONE -D -F raw -L 3333 -o example.db.serial.raw example \
$CHECKZONE -D -F raw -o large.db.raw large large.db > /dev/null 2>&1
@@ -29,6 +29,8 @@ $CHECKZONE -D -F raw -L 3333 -o example.db.serial.raw example \
$CHECKZONE -D -F raw -o large.db.raw large large.db >/dev/null 2>&1
$CHECKZONE -D -F map -o example.db.map example-map \
example.db > /dev/null 2>&1
example.db >/dev/null 2>&1
+$CHECKZONE -D -F raw -o huge.db.raw huge huge.db >/dev/null 2>&1
+$CHECKZONE -D -F raw -o uber.db.raw uber uber.db >/dev/null 2>&1
$KEYGEN -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -f KSK signed > /dev/null 2>&1
$KEYGEN -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" signed > /dev/null 2>&1
$KEYGEN -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -f KSK signed >/dev/null 2>&1
$KEYGEN -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" signed >/dev/null 2>&1
diff --git a/bin/tests/system/masterformat/ns1/huge.db.in b/bin/tests/system/masterformat/ns1/huge.db.in
new file mode 100644
index 0000000000..5a818632a8
@ -121,10 +108,10 @@ index 0000000000..5a818632a8
+ NS ns
+ns A 10.53.0.1
diff --git a/bin/tests/system/masterformat/ns1/named.conf.in b/bin/tests/system/masterformat/ns1/named.conf.in
index 2b7c11c991..4c3614f671 100644
index cc95655691..1434ec34d6 100644
--- a/bin/tests/system/masterformat/ns1/named.conf.in
+++ b/bin/tests/system/masterformat/ns1/named.conf.in
@@ -20,6 +20,7 @@ options {
@@ -22,6 +22,7 @@ options {
notify no;
session-keyfile "session.key";
servfail-ttl 0;
@ -132,7 +119,7 @@ index 2b7c11c991..4c3614f671 100644
};
key rndc_key {
@@ -75,6 +76,20 @@ zone "large" {
@@ -77,6 +78,20 @@ zone "large" {
allow-transfer { any; };
};
@ -182,10 +169,10 @@ index 0000000000..5a818632a8
+ NS ns
+ns A 10.53.0.1
diff --git a/bin/tests/system/masterformat/ns2/named.conf.in b/bin/tests/system/masterformat/ns2/named.conf.in
index 4df1d37990..0468ddd17a 100644
index c0f2987318..df778bc64b 100644
--- a/bin/tests/system/masterformat/ns2/named.conf.in
+++ b/bin/tests/system/masterformat/ns2/named.conf.in
@@ -19,6 +19,7 @@ options {
@@ -21,6 +21,7 @@ options {
recursion no;
notify no;
servfail-ttl 0;
@ -193,7 +180,7 @@ index 4df1d37990..0468ddd17a 100644
};
zone "example" {
@@ -59,3 +60,10 @@ zone "large" {
@@ -61,3 +62,10 @@ zone "large" {
masterfile-format raw;
file "large.bk";
};
@ -205,10 +192,10 @@ index 4df1d37990..0468ddd17a 100644
+ file "huge.bk";
+};
diff --git a/bin/tests/system/masterformat/setup.sh b/bin/tests/system/masterformat/setup.sh
index ffc2b42a84..7af1ad978a 100755
index f3042428bd..57b8a24952 100755
--- a/bin/tests/system/masterformat/setup.sh
+++ b/bin/tests/system/masterformat/setup.sh
@@ -22,8 +22,23 @@ cp ns1/example.db ns2/
@@ -24,8 +24,23 @@ cp ns1/example.db ns2/
cp ns2/formerly-text.db.in ns2/formerly-text.db
cp ns1/large.db.in ns1/large.db
awk 'END {
@ -217,7 +204,7 @@ index ffc2b42a84..7af1ad978a 100755
+ for (i = 0; i < 500; i++ ) { print "a TXT", i; }
+ for (i = 0; i < 1000; i++ ) { print "b TXT", i; }
for (i = 0; i < 2000; i++ ) { print "c TXT", i; }
}' < /dev/null >> ns1/large.db
}' </dev/null >>ns1/large.db
+cp ns1/huge.db.in ns1/huge.db
+awk 'END {
+ for (i = 0; i < 500; i++ ) { print "a TXT", i; }
@ -235,17 +222,13 @@ index ffc2b42a84..7af1ad978a 100755
+}' </dev/null >>ns1/uber.db
cd ns1 && $SHELL compile.sh
diff --git a/bin/tests/system/masterformat/tests.sh b/bin/tests/system/masterformat/tests.sh
index bb4e6ec3cd..83ab738faf 100755
index 3a4eb3e116..c3be164d56 100755
--- a/bin/tests/system/masterformat/tests.sh
+++ b/bin/tests/system/masterformat/tests.sh
@@ -188,10 +188,66 @@ echo_i "checking that large rdatasets loaded ($n)"
for i in 0 1 2 3 4 5 6 7 8 9
do
ret=0
-for a in a b c
-do
- $DIG +tcp txt "${a}.large" @10.53.0.2 -p "${PORT}" > "dig.out.ns2.test$n"
- grep "status: NOERROR" "dig.out.ns2.test$n" > /dev/null || ret=1
@@ -190,6 +190,66 @@ for i in 0 1 2 3 4 5 6 7 8 9; do
for a in a b c; do
$DIG +tcp txt "${a}.large" @10.53.0.2 -p "${PORT}" >"dig.out.ns2.test$n"
grep "status: NOERROR" "dig.out.ns2.test$n" >/dev/null || ret=1
+ for a in a b c
+ do
+ $DIG +tcp txt "${a}.large" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$a.test$n"
@ -306,9 +289,9 @@ index bb4e6ec3cd..83ab738faf 100755
+ for a in a b c d e; do
+ $DIG +tcp txt "${a}.uber" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$a.test$n"
+ grep "status: SERVFAIL" "dig.out.ns1.$a.test$n" >/dev/null || ret=1
done
[ $ret -eq 0 ] && break
sleep 1
done
[ $ret -eq 0 ] && break
sleep 1
diff --git a/bin/tests/system/reclimit/ns1/big.db b/bin/tests/system/reclimit/ns1/big.db
new file mode 100644
index 0000000000..bddceb76e7
@ -2831,10 +2814,10 @@ index 0000000000..bddceb76e7
+biganswer.big. 60 IN A 10.10.50.49
+biganswer.big. 60 IN A 10.10.50.50
diff --git a/bin/tests/system/reclimit/ns1/named.conf.in b/bin/tests/system/reclimit/ns1/named.conf.in
index 3eb07b7fd3..e6c3c38214 100644
index 63cb706883..c56c0dbf55 100644
--- a/bin/tests/system/reclimit/ns1/named.conf.in
+++ b/bin/tests/system/reclimit/ns1/named.conf.in
@@ -20,6 +20,12 @@ options {
@@ -22,6 +22,12 @@ options {
listen-on-v6 { none; };
recursion no;
dnssec-validation no;
@ -2848,10 +2831,10 @@ index 3eb07b7fd3..e6c3c38214 100644
+ file "big.db";
+};
diff --git a/bin/tests/system/reclimit/ns1/root.db b/bin/tests/system/reclimit/ns1/root.db
index 3a6f7880ba..569abd5ee5 100644
index 412715cc64..30e175b335 100644
--- a/bin/tests/system/reclimit/ns1/root.db
+++ b/bin/tests/system/reclimit/ns1/root.db
@@ -17,3 +17,6 @@ example.net. 60 IN NS direct.example.net.
@@ -19,3 +19,6 @@ example.net. 60 IN NS direct.example.net.
direct.example.net. 60 IN A 10.53.0.2
example.com. 60 IN NS direct.example.com.
direct.example.com. 60 IN A 10.53.0.4
@ -2907,12 +2890,12 @@ index 0000000000..56f704a3c0
+
+zone "." { type hint; file "hints.db"; };
diff --git a/bin/tests/system/reclimit/tests.sh b/bin/tests/system/reclimit/tests.sh
index c7d088af53..f76f955a60 100644
index a20344555b..b332e381ff 100644
--- a/bin/tests/system/reclimit/tests.sh
+++ b/bin/tests/system/reclimit/tests.sh
@@ -204,6 +204,16 @@ eval count=`cat dig.out.3.test$n`
@@ -221,6 +221,16 @@ eval count=$(cat dig.out.3.test$n)
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
status=$(expr $status + $ret)
-#grep "duplicate query" ns3/named.run
+n=$((n + 1))
@ -2929,19 +2912,19 @@ index c7d088af53..f76f955a60 100644
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
diff --git a/bin/tests/system/resolver/tests.sh b/bin/tests/system/resolver/tests.sh
index bd997a61a4..711ee0537c 100755
index 09fff0dd13..d9121d9ae5 100755
--- a/bin/tests/system/resolver/tests.sh
+++ b/bin/tests/system/resolver/tests.sh
@@ -566,7 +566,8 @@ $DIG $DIGOPTS @10.53.0.5 fetchall.tld any > dig.out.3.${n} || ret=1
@@ -607,7 +607,8 @@ sleep 1
# because of the order of the records in the cache
$DIG $DIGOPTS @10.53.0.5 fetchall.tld any >dig.out.3.${n} || ret=1
dig_with_opts @10.53.0.5 fetchall.tld any >dig.out.3.${n} || ret=1
ttl3=$(awk '/^fetchall.tld/ { print $2; exit }' dig.out.3.${n})
-test "${ttl3:-0}" -gt "${ttl2:-1}" || ret=1
+#test "${ttl3:-0}" -gt "${ttl2:-1}" || ret=1
+test "${ttl3:-0}" -gt "${ttl2:-1}" || echo_i "Later TTL is not greater, $ttl3 <= $ttl2"
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
status=$((status + ret))
--
2.45.2
2.53.0

View File

@ -1,27 +0,0 @@
From 7bc5e5abf5a3cd66f11cc649b6ecf4c39c92bd9e Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Fri, 9 Aug 2024 12:32:20 +0200
Subject: [PATCH] fixup! Add test for not-loading and not-transfering huge
RRSets
---
bin/tests/system/conf.sh.common | 3 +++
1 file changed, 3 insertions(+)
diff --git a/bin/tests/system/conf.sh.common b/bin/tests/system/conf.sh.common
index 9fab00f..e617595 100644
--- a/bin/tests/system/conf.sh.common
+++ b/bin/tests/system/conf.sh.common
@@ -301,6 +301,9 @@ DISABLED_ALGORITHM=ECDSAP384SHA384
DISABLED_ALGORITHM_NUMBER=14
DISABLED_BITS=384
+# Default HMAC algorithm.
+export DEFAULT_HMAC=hmac-sha256
+
#
# Useful functions in test scripts
#
--
2.45.2

View File

@ -1,4 +1,4 @@
From 2df11e5a549a71a8f792ac5207254b6a9e09859c Mon Sep 17 00:00:00 2001
From 4ff43d14005c2cafcc950ad726a9a86c25452e5a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Fri, 1 Mar 2024 08:26:07 +0100
Subject: [PATCH] Add a limit to the number of RRs in RRSets
@ -18,42 +18,42 @@ be configured globally, per-view and per-zone.
(cherry picked from commit f63d72fb7e5813585c92d7f92bdcc5885cd04edc)
---
bin/named/config.c | 1 +
bin/named/server.c | 9 ++++
bin/named/server.c | 9 +++++
bin/named/zoneconf.c | 8 ++++
bin/tests/system/dyndb/driver/db.c | 3 +-
doc/arm/reference.rst | 12 +++++
doc/arm/reference.rst | 12 ++++++
doc/misc/master.zoneopt | 2 +
doc/misc/mirror.zoneopt | 2 +
doc/misc/options | 44 +++++++++++-------
doc/misc/options.active | 44 +++++++++++-------
doc/misc/options | 44 +++++++++++++--------
doc/misc/options.active | 27 ++++++++-----
doc/misc/redirect.zoneopt | 2 +
doc/misc/slave.zoneopt | 2 +
doc/misc/static-stub.zoneopt | 2 +
doc/misc/stub.zoneopt | 2 +
lib/dns/cache.c | 13 ++++++
lib/dns/db.c | 9 ++++
lib/dns/cache.c | 13 +++++++
lib/dns/db.c | 9 +++++
lib/dns/dnsrps.c | 3 +-
lib/dns/ecdb.c | 8 +++-
lib/dns/include/dns/cache.h | 6 +++
lib/dns/include/dns/db.h | 8 ++++
lib/dns/include/dns/rdataslab.h | 6 ++-
lib/dns/include/dns/view.h | 7 +++
lib/dns/include/dns/zone.h | 26 +++++++++++
lib/dns/rbtdb.c | 45 ++++++++++++------
lib/dns/rdataslab.c | 10 ++--
lib/dns/include/dns/view.h | 7 ++++
lib/dns/include/dns/zone.h | 26 +++++++++++++
lib/dns/rbtdb.c | 45 +++++++++++++++-------
lib/dns/rdataslab.c | 10 +++--
lib/dns/sdb.c | 3 +-
lib/dns/sdlz.c | 3 +-
lib/dns/view.c | 11 +++++
lib/dns/xfrin.c | 24 ++--------
lib/dns/zone.c | 74 ++++++++++++++++++++++--------
lib/dns/view.c | 11 ++++++
lib/dns/xfrin.c | 24 +++---------
lib/dns/zone.c | 61 +++++++++++++++++++++++++++---
lib/isccfg/namedconf.c | 3 ++
30 files changed, 296 insertions(+), 96 deletions(-)
30 files changed, 286 insertions(+), 76 deletions(-)
diff --git a/bin/named/config.c b/bin/named/config.c
index c37015f3b2..9cba6f588b 100644
index 522798a..72dec1a 100644
--- a/bin/named/config.c
+++ b/bin/named/config.c
@@ -215,6 +215,7 @@ options {\n\
@@ -226,6 +226,7 @@ options {\n\
ixfr-from-differences false;\n\
max-journal-size default;\n\
max-records 0;\n\
@ -62,10 +62,10 @@ index c37015f3b2..9cba6f588b 100644
max-retry-time 1209600; /* 2 weeks */\n\
max-transfer-idle-in 60;\n\
diff --git a/bin/named/server.c b/bin/named/server.c
index 8fd9ee7e5a..7bf5f2664d 100644
index 098e21d..f550814 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -5418,6 +5418,15 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
@@ -5452,6 +5452,15 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
dns_resolver_setclientsperquery(view->resolver, cfg_obj_asuint32(obj),
max_clients_per_query);
@ -82,10 +82,10 @@ index 8fd9ee7e5a..7bf5f2664d 100644
result = named_config_get(maps, "max-recursion-depth", &obj);
INSIST(result == ISC_R_SUCCESS);
diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c
index 97c2094ca2..ae5cc656ee 100644
index 2e614aa..81f6879 100644
--- a/bin/named/zoneconf.c
+++ b/bin/named/zoneconf.c
@@ -1092,6 +1092,14 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
@@ -1072,6 +1072,14 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_zone_setmaxrecords(zone, 0);
}
@ -101,10 +101,10 @@ index 97c2094ca2..ae5cc656ee 100644
#define SIGNED ".signed"
size_t signedlen = strlen(filename) + sizeof(SIGNED);
diff --git a/bin/tests/system/dyndb/driver/db.c b/bin/tests/system/dyndb/driver/db.c
index 77d335e2ea..6725a3bacd 100644
index 5f01185..727268f 100644
--- a/bin/tests/system/dyndb/driver/db.c
+++ b/bin/tests/system/dyndb/driver/db.c
@@ -592,7 +592,8 @@ static dns_dbmethods_t sampledb_methods = {
@@ -622,7 +622,8 @@ static dns_dbmethods_t sampledb_methods = {
NULL, /* setservestalerefresh */
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
@ -115,10 +115,10 @@ index 77d335e2ea..6725a3bacd 100644
/* Auxiliary driver functions. */
diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst
index ad7ff2761a..b1983ef30d 100644
index f982e0a..fbd8edb 100644
--- a/doc/arm/reference.rst
+++ b/doc/arm/reference.rst
@@ -2890,6 +2890,18 @@ system.
@@ -2945,6 +2945,18 @@ system.
This sets the maximum number of records permitted in a zone. The default is
zero, which means the maximum is unlimited.
@ -138,7 +138,7 @@ index ad7ff2761a..b1983ef30d 100644
This sets the maximum number (a "hard quota") of simultaneous recursive lookups
the server performs on behalf of clients. The default is
diff --git a/doc/misc/master.zoneopt b/doc/misc/master.zoneopt
index cc8a33b56f..864a852ef4 100644
index 953e3a2..b2fc2c8 100644
--- a/doc/misc/master.zoneopt
+++ b/doc/misc/master.zoneopt
@@ -38,8 +38,10 @@ zone <string> [ <class> ] {
@ -153,7 +153,7 @@ index cc8a33b56f..864a852ef4 100644
notify ( explicit | master-only | primary-only | <boolean> );
notify-delay <integer>;
diff --git a/doc/misc/mirror.zoneopt b/doc/misc/mirror.zoneopt
index 3d45a3d1e5..701edce540 100644
index 3d45a3d..701edce 100644
--- a/doc/misc/mirror.zoneopt
+++ b/doc/misc/mirror.zoneopt
@@ -19,12 +19,14 @@ zone <string> [ <class> ] {
@ -172,7 +172,7 @@ index 3d45a3d1e5..701edce540 100644
min-retry-time <integer>;
multi-master <boolean>;
diff --git a/doc/misc/options b/doc/misc/options
index 90d07f5a56..ee152b8179 100644
index 0dbcf10..93eb156 100644
--- a/doc/misc/options
+++ b/doc/misc/options
@@ -170,13 +170,16 @@ options {
@ -196,7 +196,7 @@ index 90d07f5a56..ee152b8179 100644
+ unlimited | <integer> ) ] [ suffix ( increment
+ | timestamp ) ]; // not configured
+ dnstap-version ( <quoted_string> | none ); // not configured
dscp <integer>;
dscp <integer>; // deprecated
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
<integer> ] [ dscp <integer> ] | <ipv4_address> [ port
@@ -200,13 +203,13 @@ options {
@ -236,7 +236,7 @@ index 90d07f5a56..ee152b8179 100644
max-udp-size <integer>;
max-zone-ttl ( unlimited | <duration> );
memstatistics <boolean>;
@@ -569,8 +574,9 @@ view <string> [ <class> ] {
@@ -570,8 +575,9 @@ view <string> [ <class> ] {
dnssec-secure-to-insecure <boolean>;
dnssec-update-mode ( maintain | no-resign );
dnssec-validation ( yes | no | auto );
@ -248,7 +248,7 @@ index 90d07f5a56..ee152b8179 100644
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
<integer> ] [ dscp <integer> ] | <ipv4_address> [ port
<integer> ] [ dscp <integer> ] | <ipv6_address> [ port
@@ -622,6 +628,7 @@ view <string> [ <class> ] {
@@ -623,6 +629,7 @@ view <string> [ <class> ] {
max-journal-size ( default | unlimited | <sizeval> );
max-ncache-ttl <duration>;
max-records <integer>;
@ -256,7 +256,7 @@ index 90d07f5a56..ee152b8179 100644
max-recursion-depth <integer>;
max-recursion-queries <integer>;
max-refresh-time <integer>;
@@ -631,6 +638,7 @@ view <string> [ <class> ] {
@@ -632,6 +639,7 @@ view <string> [ <class> ] {
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
@ -264,7 +264,7 @@ index 90d07f5a56..ee152b8179 100644
max-udp-size <integer>;
max-zone-ttl ( unlimited | <duration> );
message-compression <boolean>;
@@ -854,12 +862,14 @@ view <string> [ <class> ] {
@@ -855,12 +863,14 @@ view <string> [ <class> ] {
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
@ -279,7 +279,7 @@ index 90d07f5a56..ee152b8179 100644
max-zone-ttl ( unlimited | <duration> );
min-refresh-time <integer>;
min-retry-time <integer>;
@@ -971,12 +981,14 @@ zone <string> [ <class> ] {
@@ -972,12 +982,14 @@ zone <string> [ <class> ] {
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
@ -295,34 +295,10 @@ index 90d07f5a56..ee152b8179 100644
min-refresh-time <integer>;
min-retry-time <integer>;
diff --git a/doc/misc/options.active b/doc/misc/options.active
index 0229d8da6d..ad4e29a9ba 100644
index eb75a86..f3ac9e7 100644
--- a/doc/misc/options.active
+++ b/doc/misc/options.active
@@ -156,13 +156,16 @@ options {
dnssec-secure-to-insecure <boolean>;
dnssec-update-mode ( maintain | no-resign );
dnssec-validation ( yes | no | auto );
- dnstap { ( all | auth | client | forwarder | resolver | update ) [
- ( query | response ) ]; ... };
- dnstap-identity ( <quoted_string> | none | hostname );
- dnstap-output ( file | unix ) <quoted_string> [ size ( unlimited |
- <size> ) ] [ versions ( unlimited | <integer> ) ] [ suffix (
- increment | timestamp ) ];
- dnstap-version ( <quoted_string> | none );
+ dnstap { ( all | auth | client | forwarder |
+ resolver | update ) [ ( query | response ) ];
+ ... }; // not configured
+ dnstap-identity ( <quoted_string> | none |
+ hostname ); // not configured
+ dnstap-output ( file | unix ) <quoted_string> [
+ size ( unlimited | <size> ) ] [ versions (
+ unlimited | <integer> ) ] [ suffix ( increment
+ | timestamp ) ]; // not configured
+ dnstap-version ( <quoted_string> | none ); // not configured
dscp <integer>;
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
<integer> ] [ dscp <integer> ] | <ipv4_address> [ port
@@ -181,13 +184,13 @@ options {
@@ -181,13 +181,13 @@ options {
forward ( first | only );
forwarders [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address>
| <ipv6_address> ) [ port <integer> ] [ dscp <integer> ]; ... };
@ -343,7 +319,7 @@ index 0229d8da6d..ad4e29a9ba 100644
geoip-directory ( <quoted_string> | none );
glue-cache <boolean>;
heartbeat-interval <integer>;
@@ -217,6 +220,7 @@ options {
@@ -217,6 +217,7 @@ options {
max-journal-size ( default | unlimited | <sizeval> );
max-ncache-ttl <duration>;
max-records <integer>;
@ -351,7 +327,7 @@ index 0229d8da6d..ad4e29a9ba 100644
max-recursion-depth <integer>;
max-recursion-queries <integer>;
max-refresh-time <integer>;
@@ -227,6 +231,7 @@ options {
@@ -227,6 +228,7 @@ options {
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
@ -359,7 +335,7 @@ index 0229d8da6d..ad4e29a9ba 100644
max-udp-size <integer>;
max-zone-ttl ( unlimited | <duration> );
memstatistics <boolean>;
@@ -513,8 +518,9 @@ view <string> [ <class> ] {
@@ -514,8 +516,9 @@ view <string> [ <class> ] {
dnssec-secure-to-insecure <boolean>;
dnssec-update-mode ( maintain | no-resign );
dnssec-validation ( yes | no | auto );
@ -371,7 +347,7 @@ index 0229d8da6d..ad4e29a9ba 100644
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
<integer> ] [ dscp <integer> ] | <ipv4_address> [ port
<integer> ] [ dscp <integer> ] | <ipv6_address> [ port
@@ -559,6 +565,7 @@ view <string> [ <class> ] {
@@ -560,6 +563,7 @@ view <string> [ <class> ] {
max-journal-size ( default | unlimited | <sizeval> );
max-ncache-ttl <duration>;
max-records <integer>;
@ -379,7 +355,7 @@ index 0229d8da6d..ad4e29a9ba 100644
max-recursion-depth <integer>;
max-recursion-queries <integer>;
max-refresh-time <integer>;
@@ -568,6 +575,7 @@ view <string> [ <class> ] {
@@ -569,6 +573,7 @@ view <string> [ <class> ] {
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
@ -387,7 +363,7 @@ index 0229d8da6d..ad4e29a9ba 100644
max-udp-size <integer>;
max-zone-ttl ( unlimited | <duration> );
message-compression <boolean>;
@@ -774,12 +782,14 @@ view <string> [ <class> ] {
@@ -775,12 +780,14 @@ view <string> [ <class> ] {
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
@ -402,7 +378,7 @@ index 0229d8da6d..ad4e29a9ba 100644
max-zone-ttl ( unlimited | <duration> );
min-refresh-time <integer>;
min-retry-time <integer>;
@@ -884,12 +894,14 @@ zone <string> [ <class> ] {
@@ -885,12 +892,14 @@ zone <string> [ <class> ] {
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
@ -418,7 +394,7 @@ index 0229d8da6d..ad4e29a9ba 100644
min-refresh-time <integer>;
min-retry-time <integer>;
diff --git a/doc/misc/redirect.zoneopt b/doc/misc/redirect.zoneopt
index 6a5ef660a2..c4ab59ddad 100644
index 6a5ef66..c4ab59d 100644
--- a/doc/misc/redirect.zoneopt
+++ b/doc/misc/redirect.zoneopt
@@ -8,6 +8,8 @@ zone <string> [ <class> ] {
@ -431,7 +407,7 @@ index 6a5ef660a2..c4ab59ddad 100644
primaries [ port <integer> ] [ dscp <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
zone-statistics ( full | terse | none | <boolean> );
diff --git a/doc/misc/slave.zoneopt b/doc/misc/slave.zoneopt
index 8cb7c3143f..ccd88e5c15 100644
index c46202d..52ce7cf 100644
--- a/doc/misc/slave.zoneopt
+++ b/doc/misc/slave.zoneopt
@@ -31,12 +31,14 @@ zone <string> [ <class> ] {
@ -450,7 +426,7 @@ index 8cb7c3143f..ccd88e5c15 100644
min-retry-time <integer>;
multi-master <boolean>;
diff --git a/doc/misc/static-stub.zoneopt b/doc/misc/static-stub.zoneopt
index f89d46248a..102b980c7a 100644
index f89d462..102b980 100644
--- a/doc/misc/static-stub.zoneopt
+++ b/doc/misc/static-stub.zoneopt
@@ -5,6 +5,8 @@ zone <string> [ <class> ] {
@ -463,7 +439,7 @@ index f89d46248a..102b980c7a 100644
server-names { <string>; ... };
zone-statistics ( full | terse | none | <boolean> );
diff --git a/doc/misc/stub.zoneopt b/doc/misc/stub.zoneopt
index 2db604dae6..ca4bf1ce39 100644
index 2db604d..ca4bf1c 100644
--- a/doc/misc/stub.zoneopt
+++ b/doc/misc/stub.zoneopt
@@ -13,10 +13,12 @@ zone <string> [ <class> ] {
@ -480,10 +456,10 @@ index 2db604dae6..ca4bf1ce39 100644
min-retry-time <integer>;
multi-master <boolean>;
diff --git a/lib/dns/cache.c b/lib/dns/cache.c
index ae173b86ab..9f0412dbe7 100644
index b5d2b09..8cb442b 100644
--- a/lib/dns/cache.c
+++ b/lib/dns/cache.c
@@ -148,6 +148,8 @@ struct dns_cache {
@@ -151,6 +151,8 @@ struct dns_cache {
/* Locked by 'filelock'. */
char *filename;
/* Access to the on-disk cache file is also locked by 'filelock'. */
@ -492,15 +468,15 @@ index ae173b86ab..9f0412dbe7 100644
};
/***
@@ -175,6 +177,7 @@ cache_create_db(dns_cache_t *cache, dns_db_t **db) {
cache->db_argv, db);
if (result == ISC_R_SUCCESS) {
dns_db_setservestalettl(*db, cache->serve_stale_ttl);
+ dns_db_setmaxrrperset(*db, cache->maxrrperset);
@@ -184,6 +186,7 @@ cache_create_db(dns_cache_t *cache, dns_db_t **db) {
}
return (result);
}
@@ -1277,6 +1280,16 @@ dns_cache_updatestats(dns_cache_t *cache, isc_result_t result) {
dns_db_setservestalettl(*db, cache->serve_stale_ttl);
+ dns_db_setmaxrrperset(*db, cache->maxrrperset);
if (cache->taskmgr == NULL) {
return (ISC_R_SUCCESS);
@@ -1316,6 +1319,16 @@ dns_cache_updatestats(dns_cache_t *cache, isc_result_t result) {
}
}
@ -518,10 +494,10 @@ index ae173b86ab..9f0412dbe7 100644
* XXX: Much of the following code has been copied in from statschannel.c.
* We should refactor this into a generic function in stats.c that can be
diff --git a/lib/dns/db.c b/lib/dns/db.c
index ec537486cb..8439265a7f 100644
index f90add1..a575d62 100644
--- a/lib/dns/db.c
+++ b/lib/dns/db.c
@@ -1122,3 +1122,12 @@ dns_db_setgluecachestats(dns_db_t *db, isc_stats_t *stats) {
@@ -1137,3 +1137,12 @@ dns_db_setgluecachestats(dns_db_t *db, isc_stats_t *stats) {
return (ISC_R_NOTIMPLEMENTED);
}
@ -535,10 +511,10 @@ index ec537486cb..8439265a7f 100644
+ }
+}
diff --git a/lib/dns/dnsrps.c b/lib/dns/dnsrps.c
index 0f2ffb5f35..539090d1bd 100644
index 8c04337..f4d9bae 100644
--- a/lib/dns/dnsrps.c
+++ b/lib/dns/dnsrps.c
@@ -970,7 +970,8 @@ static dns_dbmethods_t rpsdb_db_methods = {
@@ -975,7 +975,8 @@ static dns_dbmethods_t rpsdb_db_methods = {
NULL, /* setservestalerefresh */
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
@ -549,10 +525,10 @@ index 0f2ffb5f35..539090d1bd 100644
static dns_rdatasetmethods_t rpsdb_rdataset_methods = {
diff --git a/lib/dns/ecdb.c b/lib/dns/ecdb.c
index 1d9343361d..bab5da5503 100644
index abbb8d9..42a1248 100644
--- a/lib/dns/ecdb.c
+++ b/lib/dns/ecdb.c
@@ -426,7 +426,7 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
@@ -428,7 +428,7 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
}
result = dns_rdataslab_fromrdataset(rdataset, mctx, &r,
@ -561,7 +537,7 @@ index 1d9343361d..bab5da5503 100644
if (result != ISC_R_SUCCESS) {
goto unlock;
}
@@ -556,7 +556,11 @@ static dns_dbmethods_t ecdb_methods = {
@@ -560,7 +560,11 @@ static dns_dbmethods_t ecdb_methods = {
NULL, /* getsize */
NULL, /* setservestalettl */
NULL, /* getservestalettl */
@ -575,10 +551,10 @@ index 1d9343361d..bab5da5503 100644
static isc_result_t
diff --git a/lib/dns/include/dns/cache.h b/lib/dns/include/dns/cache.h
index 22e94da9d5..3fa2a891e0 100644
index 02dd1ac..34539eb 100644
--- a/lib/dns/include/dns/cache.h
+++ b/lib/dns/include/dns/cache.h
@@ -337,6 +337,12 @@ dns_cache_updatestats(dns_cache_t *cache, isc_result_t result);
@@ -334,6 +334,12 @@ dns_cache_updatestats(dns_cache_t *cache, isc_result_t result);
* Update cache statistics based on result code in 'result'
*/
@ -592,18 +568,18 @@ index 22e94da9d5..3fa2a891e0 100644
int
dns_cache_renderxml(dns_cache_t *cache, void *writer0);
diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h
index 90bd7fb112..732bfe473d 100644
index ae27639..e0d17f2 100644
--- a/lib/dns/include/dns/db.h
+++ b/lib/dns/include/dns/db.h
@@ -182,6 +182,7 @@ typedef struct dns_dbmethods {
@@ -184,6 +184,7 @@ typedef struct dns_dbmethods {
isc_result_t (*getservestalerefresh)(dns_db_t *db, uint32_t *interval);
isc_result_t (*setgluecachestats)(dns_db_t *db, isc_stats_t *stats);
isc_result_t (*adjusthashsize)(dns_db_t *db, size_t size);
+ void (*setmaxrrperset)(dns_db_t *db, uint32_t value);
} dns_dbmethods_t;
typedef isc_result_t (*dns_dbcreatefunc_t)(isc_mem_t *mctx,
@@ -1783,6 +1784,13 @@ dns_db_setgluecachestats(dns_db_t *db, isc_stats_t *stats);
typedef isc_result_t (*dns_dbcreatefunc_t)(isc_mem_t *mctx,
@@ -1796,6 +1797,13 @@ dns_db_setgluecachestats(dns_db_t *db, isc_stats_t *stats);
* dns_rdatasetstats_create(); otherwise NULL.
*/
@ -618,10 +594,10 @@ index 90bd7fb112..732bfe473d 100644
#endif /* DNS_DB_H */
diff --git a/lib/dns/include/dns/rdataslab.h b/lib/dns/include/dns/rdataslab.h
index 5a22f099c3..f2f3513a19 100644
index 5a1c30f..89c8fc2 100644
--- a/lib/dns/include/dns/rdataslab.h
+++ b/lib/dns/include/dns/rdataslab.h
@@ -65,7 +65,8 @@ ISC_LANG_BEGINDECLS
@@ -67,7 +67,8 @@ ISC_LANG_BEGINDECLS
isc_result_t
dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
@ -631,7 +607,7 @@ index 5a22f099c3..f2f3513a19 100644
/*%<
* Slabify a rdataset. The slab area will be allocated and returned
* in 'region'.
@@ -121,7 +122,8 @@ isc_result_t
@@ -123,7 +124,8 @@ isc_result_t
dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
unsigned int reservelen, isc_mem_t *mctx,
dns_rdataclass_t rdclass, dns_rdatatype_t type,
@ -642,18 +618,18 @@ index 5a22f099c3..f2f3513a19 100644
* Merge 'oslab' and 'nslab'.
*/
diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h
index 2cf7eced16..0d502f4dd2 100644
index d6e7f10..b7cf663 100644
--- a/lib/dns/include/dns/view.h
+++ b/lib/dns/include/dns/view.h
@@ -186,6 +186,7 @@ struct dns_view {
@@ -188,6 +188,7 @@ struct dns_view {
dns_dlzdblist_t dlz_unsearched;
uint32_t fail_ttl;
dns_badcache_t *failcache;
dns_badcache_t *failcache;
+ uint32_t maxrrperset;
/*
* Configurable data for server use only,
@@ -1339,6 +1340,12 @@ dns_view_staleanswerenabled(dns_view_t *view);
@@ -1354,6 +1355,12 @@ dns_view_staleanswerenabled(dns_view_t *view);
*\li 'view' to be valid.
*/
@ -667,10 +643,10 @@ index 2cf7eced16..0d502f4dd2 100644
#endif /* DNS_VIEW_H */
diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h
index 08e2263c5b..e902043357 100644
index 4bdc936..a98b28f 100644
--- a/lib/dns/include/dns/zone.h
+++ b/lib/dns/include/dns/zone.h
@@ -162,6 +162,19 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx);
@@ -164,6 +164,19 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx);
*\li #ISC_R_UNEXPECTED
*/
@ -690,7 +666,7 @@ index 08e2263c5b..e902043357 100644
void
dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass);
/*%<
@@ -330,6 +343,19 @@ dns_zone_getmaxrecords(dns_zone_t *zone);
@@ -332,6 +345,19 @@ dns_zone_getmaxrecords(dns_zone_t *zone);
*\li uint32_t maxrecords.
*/
@ -711,10 +687,10 @@ index 08e2263c5b..e902043357 100644
dns_zone_setmaxttl(dns_zone_t *zone, uint32_t maxttl);
/*%<
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index e840c0665d..ca71bb9c03 100644
index d4c1829..e8de346 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -482,6 +482,7 @@ struct dns_rbtdb {
@@ -496,6 +496,7 @@ struct dns_rbtdb {
rbtdb_serial_t current_serial;
rbtdb_serial_t least_serial;
rbtdb_serial_t next_serial;
@ -722,7 +698,7 @@ index e840c0665d..ca71bb9c03 100644
rbtdb_version_t *current_version;
rbtdb_version_t *future_version;
rbtdb_versionlist_t open_versions;
@@ -6495,7 +6496,7 @@ find_header:
@@ -6538,7 +6539,7 @@ find_header:
rbtdb->common.mctx,
rbtdb->common.rdclass,
(dns_rdatatype_t)header->type, flags,
@ -731,16 +707,16 @@ index e840c0665d..ca71bb9c03 100644
}
if (result == ISC_R_SUCCESS) {
/*
@@ -6880,7 +6881,7 @@ delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
@@ -6896,7 +6897,7 @@ delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
static inline isc_result_t
static isc_result_t
addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
- dns_rdataset_t *rdataset) {
+ uint32_t maxrrperset, dns_rdataset_t *rdataset) {
struct noqname *noqname;
isc_mem_t *mctx = rbtdb->common.mctx;
dns_name_t name;
@@ -6901,12 +6902,12 @@ addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
@@ -6917,12 +6918,12 @@ addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
noqname->negsig = NULL;
noqname->type = neg.type;
dns_name_dup(&name, mctx, &noqname->name);
@ -755,16 +731,16 @@ index e840c0665d..ca71bb9c03 100644
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
@@ -6925,7 +6926,7 @@ cleanup:
@@ -6941,7 +6942,7 @@ cleanup:
static inline isc_result_t
static isc_result_t
addclosest(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
- dns_rdataset_t *rdataset) {
+ uint32_t maxrrperset, dns_rdataset_t *rdataset) {
struct noqname *closest;
isc_mem_t *mctx = rbtdb->common.mctx;
dns_name_t name;
@@ -6946,12 +6947,12 @@ addclosest(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
@@ -6962,12 +6963,12 @@ addclosest(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
closest->negsig = NULL;
closest->type = neg.type;
dns_name_dup(&name, mctx, &closest->name);
@ -779,7 +755,7 @@ index e840c0665d..ca71bb9c03 100644
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
@@ -7028,7 +7029,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
@@ -7048,7 +7049,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
}
result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
@ -789,7 +765,7 @@ index e840c0665d..ca71bb9c03 100644
if (result != ISC_R_SUCCESS) {
return (result);
}
@@ -7086,7 +7088,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
@@ -7106,7 +7108,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
RDATASET_ATTR_SET(newheader, RDATASET_ATTR_OPTOUT);
}
if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0) {
@ -799,7 +775,7 @@ index e840c0665d..ca71bb9c03 100644
if (result != ISC_R_SUCCESS) {
free_rdataset(rbtdb, rbtdb->common.mctx,
newheader);
@@ -7094,7 +7097,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
@@ -7114,7 +7117,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
}
}
if ((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0) {
@ -809,7 +785,7 @@ index e840c0665d..ca71bb9c03 100644
if (result != ISC_R_SUCCESS) {
free_rdataset(rbtdb, rbtdb->common.mctx,
newheader);
@@ -7261,7 +7265,8 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
@@ -7268,7 +7272,8 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
nodefullname(db, node, nodename);
result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
@ -819,7 +795,7 @@ index e840c0665d..ca71bb9c03 100644
if (result != ISC_R_SUCCESS) {
return (result);
}
@@ -7669,7 +7674,8 @@ loading_addrdataset(void *arg, const dns_name_t *name,
@@ -7672,7 +7677,8 @@ loading_addrdataset(void *arg, const dns_name_t *name,
}
result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
@ -829,7 +805,7 @@ index e840c0665d..ca71bb9c03 100644
if (result != ISC_R_SUCCESS) {
return (result);
}
@@ -8608,6 +8614,15 @@ setgluecachestats(dns_db_t *db, isc_stats_t *stats) {
@@ -8612,6 +8618,15 @@ setgluecachestats(dns_db_t *db, isc_stats_t *stats) {
return (ISC_R_SUCCESS);
}
@ -845,7 +821,7 @@ index e840c0665d..ca71bb9c03 100644
static dns_stats_t *
getrrsetstats(dns_db_t *db) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
@@ -8731,7 +8746,8 @@ static dns_dbmethods_t zone_methods = { attach,
@@ -8735,7 +8750,8 @@ static dns_dbmethods_t zone_methods = { attach,
NULL, /* setservestalerefresh */
NULL, /* getservestalerefresh */
setgluecachestats,
@ -855,7 +831,7 @@ index e840c0665d..ca71bb9c03 100644
static dns_dbmethods_t cache_methods = { attach,
detach,
@@ -8783,7 +8799,8 @@ static dns_dbmethods_t cache_methods = { attach,
@@ -8787,7 +8803,8 @@ static dns_dbmethods_t cache_methods = { attach,
setservestalerefresh,
getservestalerefresh,
NULL,
@ -866,10 +842,10 @@ index e840c0665d..ca71bb9c03 100644
isc_result_t
dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c
index dda903819a..b2d1e1cddb 100644
index d74e84c..bf4e045 100644
--- a/lib/dns/rdataslab.c
+++ b/lib/dns/rdataslab.c
@@ -116,7 +116,8 @@ fillin_offsets(unsigned char *offsetbase, unsigned int *offsettable,
@@ -118,7 +118,8 @@ fillin_offsets(unsigned char *offsetbase, unsigned int *offsettable,
isc_result_t
dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
@ -879,7 +855,7 @@ index dda903819a..b2d1e1cddb 100644
/*
* Use &removed as a sentinel pointer for duplicate
* rdata as rdata.data == NULL is valid.
@@ -158,7 +159,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
@@ -160,7 +161,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
return (ISC_R_SUCCESS);
}
@ -888,7 +864,7 @@ index dda903819a..b2d1e1cddb 100644
return (DNS_R_TOOMANYRECORDS);
}
@@ -488,7 +489,8 @@ isc_result_t
@@ -492,7 +493,8 @@ isc_result_t
dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
unsigned int reservelen, isc_mem_t *mctx,
dns_rdataclass_t rdclass, dns_rdatatype_t type,
@ -898,7 +874,7 @@ index dda903819a..b2d1e1cddb 100644
unsigned char *ocurrent, *ostart, *ncurrent, *tstart, *tcurrent, *data;
unsigned int ocount, ncount, count, olength, tlength, tcount, length;
dns_rdata_t ordata = DNS_RDATA_INIT;
@@ -528,7 +530,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
@@ -532,7 +534,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
#endif /* if DNS_RDATASET_FIXED */
INSIST(ocount > 0 && ncount > 0);
@ -908,10 +884,10 @@ index dda903819a..b2d1e1cddb 100644
}
diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c
index d9de422409..84cd324fb4 100644
index 7822d6e..282c327 100644
--- a/lib/dns/sdb.c
+++ b/lib/dns/sdb.c
@@ -1312,7 +1312,8 @@ static dns_dbmethods_t sdb_methods = {
@@ -1319,7 +1319,8 @@ static dns_dbmethods_t sdb_methods = {
NULL, /* setservestalerefresh */
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
@ -922,10 +898,10 @@ index d9de422409..84cd324fb4 100644
static isc_result_t
diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c
index c8a615a0f3..60a1d23b3b 100644
index 106e24b..299c7d8 100644
--- a/lib/dns/sdlz.c
+++ b/lib/dns/sdlz.c
@@ -1284,7 +1284,8 @@ static dns_dbmethods_t sdlzdb_methods = {
@@ -1292,7 +1292,8 @@ static dns_dbmethods_t sdlzdb_methods = {
NULL, /* setservestalerefresh */
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
@ -936,10 +912,10 @@ index c8a615a0f3..60a1d23b3b 100644
/*
diff --git a/lib/dns/view.c b/lib/dns/view.c
index dcb0f1804e..a672aa8bc8 100644
index a67dd73..9f5daf7 100644
--- a/lib/dns/view.c
+++ b/lib/dns/view.c
@@ -869,6 +869,8 @@ dns_view_setcache(dns_view_t *view, dns_cache_t *cache, bool shared) {
@@ -871,6 +871,8 @@ dns_view_setcache(dns_view_t *view, dns_cache_t *cache, bool shared) {
dns_cache_attach(cache, &view->cache);
dns_cache_attachdb(cache, &view->cachedb);
INSIST(DNS_DB_VALID(view->cachedb));
@ -948,7 +924,7 @@ index dcb0f1804e..a672aa8bc8 100644
}
bool
@@ -2544,3 +2546,12 @@ dns_view_staleanswerenabled(dns_view_t *view) {
@@ -2640,3 +2642,12 @@ dns_view_staleanswerenabled(dns_view_t *view) {
return (result);
}
@ -962,10 +938,10 @@ index dcb0f1804e..a672aa8bc8 100644
+ }
+}
diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c
index a4569f545c..c61e8f5f6b 100644
index a54d0d8..9d72b82 100644
--- a/lib/dns/xfrin.c
+++ b/lib/dns/xfrin.c
@@ -203,8 +203,6 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_task_t *task,
@@ -205,8 +205,6 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_task_t *task,
static isc_result_t
axfr_init(dns_xfrin_ctx_t *xfr);
static isc_result_t
@ -974,7 +950,7 @@ index a4569f545c..c61e8f5f6b 100644
axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
dns_ttl_t ttl, dns_rdata_t *rdata);
static isc_result_t
@@ -277,7 +275,11 @@ axfr_init(dns_xfrin_ctx_t *xfr) {
@@ -279,7 +277,11 @@ axfr_init(dns_xfrin_ctx_t *xfr) {
dns_db_detach(&xfr->db);
}
@ -987,7 +963,7 @@ index a4569f545c..c61e8f5f6b 100644
dns_rdatacallbacks_init(&xfr->axfr);
CHECK(dns_db_beginload(xfr->db, &xfr->axfr));
result = ISC_R_SUCCESS;
@@ -285,22 +287,6 @@ failure:
@@ -287,22 +289,6 @@ failure:
return (result);
}
@ -1011,10 +987,10 @@ index a4569f545c..c61e8f5f6b 100644
axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
dns_ttl_t ttl, dns_rdata_t *rdata) {
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index 65a3aacab7..5c8d97ed18 100644
index b457095..301f440 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -276,6 +276,7 @@ struct dns_zone {
@@ -307,6 +307,7 @@ struct dns_zone {
uint32_t minretry;
uint32_t maxrecords;
@ -1022,7 +998,7 @@ index 65a3aacab7..5c8d97ed18 100644
isc_sockaddr_t *masters;
isc_dscp_t *masterdscps;
@@ -2254,31 +2255,13 @@ zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
@@ -2304,12 +2305,7 @@ zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
"starting load");
@ -1036,26 +1012,7 @@ index 65a3aacab7..5c8d97ed18 100644
if (result != ISC_R_SUCCESS) {
dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
"loading zone: creating database: %s",
isc_result_totext(result));
goto cleanup;
}
- dns_db_settask(db, zone->task);
-
- if (zone->type == dns_zone_primary ||
- zone->type == dns_zone_secondary || zone->type == dns_zone_mirror)
- {
- result = dns_db_setgluecachestats(db, zone->gluecachestats);
- if (result == ISC_R_NOTIMPLEMENTED) {
- result = ISC_R_SUCCESS;
- }
- if (result != ISC_R_SUCCESS) {
- goto cleanup;
- }
- }
if (!dns_db_ispersistent(db)) {
if (zone->masterfile != NULL) {
@@ -12175,6 +12158,16 @@ dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) {
@@ -12313,6 +12309,16 @@ dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) {
zone->maxrecords = val;
}
@ -1072,23 +1029,23 @@ index 65a3aacab7..5c8d97ed18 100644
static bool
notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
isc_sockaddr_t *addr, dns_tsigkey_t *key) {
@@ -14579,6 +14572,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
@@ -14726,6 +14732,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
goto cleanup;
}
dns_db_settask(stub->db, zone->task);
dns_db_settask(stub->db, zone->task, zone->task);
+ dns_db_setmaxrrperset(stub->db, zone->maxrrperset);
}
result = dns_db_newversion(stub->db, &stub->version);
@@ -17300,6 +17294,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
@@ -17468,6 +17475,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
}
zone_attachdb(zone, db);
dns_db_settask(zone->db, zone->task);
dns_db_settask(zone->db, zone->task, zone->task);
+ dns_db_setmaxrrperset(zone->db, zone->maxrrperset);
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY);
return (ISC_R_SUCCESS);
@@ -23413,3 +23408,44 @@ zone_nsecttl(dns_zone_t *zone) {
@@ -23615,3 +23623,44 @@ zone_nsecttl(dns_zone_t *zone) {
return (ISC_MIN(zone->minimum, zone->soattl));
}
@ -1126,7 +1083,7 @@ index 65a3aacab7..5c8d97ed18 100644
+ break;
+ }
+
+ dns_db_settask(db, zone->task);
+ dns_db_settask(db, zone->task, zone->task);
+ dns_db_setmaxrrperset(db, zone->maxrrperset);
+
+ *dbp = db;
@ -1134,10 +1091,10 @@ index 65a3aacab7..5c8d97ed18 100644
+ return (ISC_R_SUCCESS);
+}
diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c
index aab0462936..dce30537dd 100644
index 6e63d86..ffe22b3 100644
--- a/lib/isccfg/namedconf.c
+++ b/lib/isccfg/namedconf.c
@@ -2236,6 +2236,9 @@ static cfg_clausedef_t zone_clauses[] = {
@@ -2241,6 +2241,9 @@ static cfg_clausedef_t zone_clauses[] = {
{ "max-records", &cfg_type_uint32,
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT },
@ -1148,5 +1105,5 @@ index aab0462936..dce30537dd 100644
CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
{ "max-retry-time", &cfg_type_uint32,
--
2.45.2
2.51.1

View File

@ -1,4 +1,4 @@
From 21385dbfc4875f9d72e158a48b9b4cf90dde8d03 Mon Sep 17 00:00:00 2001
From 95cbb61c35324ea2104313524852d5ecdabe167b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Tue, 28 May 2024 15:23:24 +0200
Subject: [PATCH] Add a test for not caching large number of RRsets
@ -53,7 +53,7 @@ priority and non-priority RR types into the database.
bin/tests/system/masterformat/clean.sh | 5 +
bin/tests/system/masterformat/ns1/compile.sh | 7 +-
.../ns1/{huge.db.in => empty.db.in} | 0
bin/tests/system/masterformat/ns1/large.db.in | 20 -
bin/tests/system/masterformat/ns1/large.db.in | 22 -
.../system/masterformat/ns1/named.conf.in | 21 +-
bin/tests/system/masterformat/ns1/uber.db.in | 22 -
.../system/masterformat/ns2/named.conf.in | 16 +-
@ -67,17 +67,17 @@ priority and non-priority RR types into the database.
bin/tests/system/reclimit/ns3/named6.conf.in | 43 +
bin/tests/system/reclimit/setup.sh | 5 +
bin/tests/system/reclimit/tests.sh | 329 +-
17 files changed, 3236 insertions(+), 2659 deletions(-)
17 files changed, 3236 insertions(+), 2661 deletions(-)
rename bin/tests/system/masterformat/ns1/{huge.db.in => empty.db.in} (100%)
delete mode 100644 bin/tests/system/masterformat/ns1/large.db.in
delete mode 100644 bin/tests/system/masterformat/ns1/uber.db.in
create mode 100644 bin/tests/system/reclimit/ns3/named6.conf.in
diff --git a/bin/tests/system/masterformat/clean.sh b/bin/tests/system/masterformat/clean.sh
index a9183af6ff..6bb9a4200a 100755
index c606c6183a..2b93c2bbdb 100755
--- a/bin/tests/system/masterformat/clean.sh
+++ b/bin/tests/system/masterformat/clean.sh
@@ -16,6 +16,11 @@ rm -f ./ns1/large.db ./ns1/large.db.raw
@@ -18,6 +18,11 @@ rm -f ./ns1/large.db ./ns1/large.db.raw
rm -f ./ns1/example.db.map ./ns1/signed.db.map
rm -f ./ns1/huge.db ./ns1/huge.db.raw
rm -f ./ns1/uber.db ./ns1/uber.db.raw
@ -90,40 +90,42 @@ index a9183af6ff..6bb9a4200a 100755
rm -f ./dig.out.*
rm -f ./dig.out
diff --git a/bin/tests/system/masterformat/ns1/compile.sh b/bin/tests/system/masterformat/ns1/compile.sh
index 9972e51aa4..164b0626e9 100755
index 34279547a0..7eee7cc804 100755
--- a/bin/tests/system/masterformat/ns1/compile.sh
+++ b/bin/tests/system/masterformat/ns1/compile.sh
@@ -24,11 +24,12 @@ $CHECKZONE -D -F raw=0 -o example.db.compat example-compat \
example.db > /dev/null 2>&1
@@ -26,11 +26,12 @@ $CHECKZONE -D -F raw=0 -o example.db.compat example-compat \
example.db >/dev/null 2>&1
$CHECKZONE -D -F raw -L 3333 -o example.db.serial.raw example \
example.db > /dev/null 2>&1
-$CHECKZONE -D -F raw -o large.db.raw large large.db > /dev/null 2>&1
example.db >/dev/null 2>&1
-$CHECKZONE -D -F raw -o large.db.raw large large.db >/dev/null 2>&1
+$CHECKZONE -D -F raw -o under-limit.db.raw under-limit under-limit.db >/dev/null 2>&1
$CHECKZONE -D -F map -o example.db.map example-map \
example.db > /dev/null 2>&1
example.db >/dev/null 2>&1
-$CHECKZONE -D -F raw -o huge.db.raw huge huge.db >/dev/null 2>&1
-$CHECKZONE -D -F raw -o uber.db.raw uber uber.db >/dev/null 2>&1
+$CHECKZONE -D -F raw -o on-limit.db.raw on-limit on-limit.db >/dev/null 2>&1
+$CHECKZONE -D -F raw -o over-limit.db.raw over-limit over-limit.db >/dev/null 2>&1
+$CHECKZONE -D -F raw -o 255types.db.raw 255types 255types.db >/dev/null 2>&1
$KEYGEN -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -f KSK signed > /dev/null 2>&1
$KEYGEN -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" signed > /dev/null 2>&1
$KEYGEN -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -f KSK signed >/dev/null 2>&1
$KEYGEN -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" signed >/dev/null 2>&1
diff --git a/bin/tests/system/masterformat/ns1/huge.db.in b/bin/tests/system/masterformat/ns1/empty.db.in
similarity index 100%
rename from bin/tests/system/masterformat/ns1/huge.db.in
rename to bin/tests/system/masterformat/ns1/empty.db.in
diff --git a/bin/tests/system/masterformat/ns1/large.db.in b/bin/tests/system/masterformat/ns1/large.db.in
deleted file mode 100644
index b30b456f52..0000000000
index 5a818632a8..0000000000
--- a/bin/tests/system/masterformat/ns1/large.db.in
+++ /dev/null
@@ -1,20 +0,0 @@
@@ -1,22 +0,0 @@
-; 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 http://mozilla.org/MPL/2.0/.
-; 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.
@ -140,10 +142,10 @@ index b30b456f52..0000000000
- NS ns
-ns A 10.53.0.1
diff --git a/bin/tests/system/masterformat/ns1/named.conf.in b/bin/tests/system/masterformat/ns1/named.conf.in
index 4c3614f671..f99acbf788 100644
index 1434ec34d6..85642a9af6 100644
--- a/bin/tests/system/masterformat/ns1/named.conf.in
+++ b/bin/tests/system/masterformat/ns1/named.conf.in
@@ -21,6 +21,7 @@ options {
@@ -23,6 +23,7 @@ options {
session-keyfile "session.key";
servfail-ttl 0;
max-records-per-type 2050;
@ -151,7 +153,7 @@ index 4c3614f671..f99acbf788 100644
};
key rndc_key {
@@ -69,23 +70,31 @@ zone "transfer4" {
@@ -71,23 +72,31 @@ zone "transfer4" {
};
@ -218,10 +220,10 @@ index 5a818632a8..0000000000
- NS ns
-ns A 10.53.0.1
diff --git a/bin/tests/system/masterformat/ns2/named.conf.in b/bin/tests/system/masterformat/ns2/named.conf.in
index 0468ddd17a..4636c21c08 100644
index df778bc64b..d4b2bb7b54 100644
--- a/bin/tests/system/masterformat/ns2/named.conf.in
+++ b/bin/tests/system/masterformat/ns2/named.conf.in
@@ -20,6 +20,7 @@ options {
@@ -22,6 +22,7 @@ options {
notify no;
servfail-ttl 0;
max-records-per-type 2000;
@ -229,7 +231,7 @@ index 0468ddd17a..4636c21c08 100644
};
zone "example" {
@@ -54,16 +55,23 @@ zone "transfer4" {
@@ -56,16 +57,23 @@ zone "transfer4" {
file "transfer.db.full";
};
@ -258,10 +260,10 @@ index 0468ddd17a..4636c21c08 100644
+ file "255types.bk";
};
diff --git a/bin/tests/system/masterformat/setup.sh b/bin/tests/system/masterformat/setup.sh
index 7af1ad978a..87d165e2f8 100755
index 57b8a24952..223ca0bd47 100755
--- a/bin/tests/system/masterformat/setup.sh
+++ b/bin/tests/system/masterformat/setup.sh
@@ -20,25 +20,34 @@ copy_setports ns3/named.conf.in ns3/named.conf
@@ -22,25 +22,34 @@ copy_setports ns3/named.conf.in ns3/named.conf
cp ns1/example.db ns2/
cp ns2/formerly-text.db.in ns2/formerly-text.db
@ -275,7 +277,7 @@ index 7af1ad978a..87d165e2f8 100755
- for (i = 0; i < 500; i++ ) { print "a TXT", i; }
- for (i = 0; i < 1000; i++ ) { print "b TXT", i; }
- for (i = 0; i < 2000; i++ ) { print "c TXT", i; }
-}' < /dev/null >> ns1/large.db
-}' </dev/null >>ns1/large.db
-cp ns1/huge.db.in ns1/huge.db
+ for (i = 0; i < 500; i++ ) { print "500-txt TXT", i; }
+ for (i = 0; i < 1000; i++ ) { print "1000-txt TXT", i; }
@ -315,39 +317,39 @@ index 7af1ad978a..87d165e2f8 100755
+echo "m TXT bunny" >>ns1/255types.db
cd ns1 && $SHELL compile.sh
diff --git a/bin/tests/system/masterformat/tests.sh b/bin/tests/system/masterformat/tests.sh
index 83ab738faf..fe86c4d85a 100755
index c3be164d56..029bf6251c 100755
--- a/bin/tests/system/masterformat/tests.sh
+++ b/bin/tests/system/masterformat/tests.sh
@@ -143,8 +143,7 @@ n=$((n+1))
status=$((status+ret))
@@ -145,7 +145,7 @@ n=$((n + 1))
status=$((status + ret))
echo_i "waiting for transfers to complete"
-for i in 0 1 2 3 4 5 6 7 8 9
-do
-for i in 0 1 2 3 4 5 6 7 8 9; do
+for _attempt in 0 1 2 3 4 5 6 7 8 9; do
test -f ns2/transfer.db.raw -a -f ns2/transfer.db.txt && break
sleep 1
test -f ns2/transfer.db.raw -a -f ns2/transfer.db.txt && break
sleep 1
done
@@ -172,8 +171,7 @@ n=$((n+1))
status=$((status+ret))
@@ -173,7 +173,7 @@ n=$((n + 1))
status=$((status + ret))
echo_i "checking that secondary formerly in text format is now raw ($n)"
-for i in 0 1 2 3 4 5 6 7 8 9
-do
-for i in 0 1 2 3 4 5 6 7 8 9; do
+for _attempt in 0 1 2 3 4 5 6 7 8 9; do
ret=0
israw ns2/formerly-text.db > /dev/null 2>&1 || ret=1
[ "$(rawversion ns2/formerly-text.db)" -eq 1 ] || ret=1
@@ -184,14 +182,12 @@ n=$((n+1))
ret=0
israw ns2/formerly-text.db >/dev/null 2>&1 || ret=1
[ "$(rawversion ns2/formerly-text.db)" -eq 1 ] || ret=1
@@ -184,16 +184,12 @@ n=$((n + 1))
[ $ret -eq 0 ] || echo_i "failed"
status=$((status+ret))
status=$((status + ret))
-echo_i "checking that large rdatasets loaded ($n)"
-for i in 0 1 2 3 4 5 6 7 8 9
-do
-for i in 0 1 2 3 4 5 6 7 8 9; do
+echo_i "checking that under-limit rdatasets loaded ($n)"
+for _attempt in 0 1 2 3 4 5 6 7 8 9; do
ret=0
ret=0
- for a in a b c; do
- $DIG +tcp txt "${a}.large" @10.53.0.2 -p "${PORT}" >"dig.out.ns2.test$n"
- grep "status: NOERROR" "dig.out.ns2.test$n" >/dev/null || ret=1
- for a in a b c
- do
- $DIG +tcp txt "${a}.large" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$a.test$n"
@ -358,7 +360,7 @@ index 83ab738faf..fe86c4d85a 100755
done
[ $ret -eq 0 ] && break
sleep 1
@@ -200,12 +196,12 @@ n=$((n + 1))
@@ -202,12 +198,12 @@ n=$((n + 1))
[ $ret -eq 0 ] || echo_i "failed"
status=$((status + ret))
@ -376,7 +378,7 @@ index 83ab738faf..fe86c4d85a 100755
done
[ $ret -eq 0 ] && break
sleep 1
@@ -214,12 +210,12 @@ n=$((n + 1))
@@ -216,12 +212,12 @@ n=$((n + 1))
[ $ret -eq 0 ] || echo_i "failed"
status=$((status + ret))
@ -394,7 +396,7 @@ index 83ab738faf..fe86c4d85a 100755
done
[ $ret -eq 0 ] && break
sleep 1
@@ -228,12 +224,12 @@ n=$((n + 1))
@@ -230,12 +226,12 @@ n=$((n + 1))
[ $ret -eq 0 ] || echo_i "failed"
status=$((status + ret))
@ -412,7 +414,7 @@ index 83ab738faf..fe86c4d85a 100755
done
[ $ret -eq 0 ] && break
sleep 1
@@ -242,12 +238,12 @@ n=$((n + 1))
@@ -244,12 +240,12 @@ n=$((n + 1))
[ $ret -eq 0 ] || echo_i "failed"
status=$((status + ret))
@ -427,12 +429,12 @@ index 83ab738faf..fe86c4d85a 100755
+ for rrcount in 500-txt 1000-txt 2000-txt 2050-txt 2100-txt; do
+ $DIG +tcp txt "${rrcount}.over-limit" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$rrcount.test$n"
+ grep "status: SERVFAIL" "dig.out.ns1.$rrcount.test$n" >/dev/null || ret=1
done
[ $ret -eq 0 ] && break
sleep 1
@@ -256,6 +252,29 @@ n=$((n+1))
done
[ $ret -eq 0 ] && break
sleep 1
@@ -258,6 +254,29 @@ n=$((n + 1))
[ $ret -eq 0 ] || echo_i "failed"
status=$((status+ret))
status=$((status + ret))
+echo_i "checking that 255 types are loaded ($n)"
+for _attempt in 0 1 2 3 4 5 6 7 8 9; do
@ -459,21 +461,21 @@ index 83ab738faf..fe86c4d85a 100755
+
echo_i "checking format transitions: text->raw->map->text ($n)"
ret=0
$CHECKZONE -D -f text -F text -o baseline.txt example.nil ns1/example.db > /dev/null
@@ -320,7 +339,7 @@ $PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} masterformat ns3
$CHECKZONE -D -f text -F text -o baseline.txt example.nil ns1/example.db >/dev/null
@@ -322,7 +341,7 @@ stop_server --use-rndc --port ${CONTROLPORT} ns3
rm ns3/*.jnl
restart
#shellcheck disable=SC2034
-for i in 0 1 2 3 4 5 6 7 8 9; do
+for _attempt in 0 1 2 3 4 5 6 7 8 9; do
lret=0
dig_with_opts +comm @10.53.0.3 moretext.dynamic txt > "dig.out.dynamic2.ns3.test$n"
grep "more text" "dig.out.dynamic2.ns3.test$n" > /dev/null 2>&1 || lret=1
lret=0
dig_with_opts +comm @10.53.0.3 moretext.dynamic txt >"dig.out.dynamic2.ns3.test$n"
grep "more text" "dig.out.dynamic2.ns3.test$n" >/dev/null 2>&1 || lret=1
diff --git a/bin/tests/system/reclimit/clean.sh b/bin/tests/system/reclimit/clean.sh
index 4db5894abd..181a6e639f 100644
index 0a92f90c3e..b63dc6141c 100644
--- a/bin/tests/system/reclimit/clean.sh
+++ b/bin/tests/system/reclimit/clean.sh
@@ -9,12 +9,16 @@
@@ -11,12 +11,16 @@
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
@ -5774,10 +5776,10 @@ index bddceb76e7..cefe8458f7 100644
+manytypes.big. IN TYPE65534 \# 0
+manytypes.big. IN A 10.53.0.1
diff --git a/bin/tests/system/reclimit/ns1/named.conf.in b/bin/tests/system/reclimit/ns1/named.conf.in
index e6c3c38214..a32c79110a 100644
index c56c0dbf55..c345c28c43 100644
--- a/bin/tests/system/reclimit/ns1/named.conf.in
+++ b/bin/tests/system/reclimit/ns1/named.conf.in
@@ -21,6 +21,7 @@ options {
@@ -23,6 +23,7 @@ options {
recursion no;
dnssec-validation no;
max-records-per-type 0;
@ -5785,7 +5787,7 @@ index e6c3c38214..a32c79110a 100644
};
zone "." { type primary; file "root.db"; };
@@ -29,3 +30,8 @@ zone "big." {
@@ -31,3 +32,8 @@ zone "big." {
type primary;
file "big.db";
};
@ -5795,10 +5797,10 @@ index e6c3c38214..a32c79110a 100644
+ file "signed.db.signed";
+};
diff --git a/bin/tests/system/reclimit/ns1/root.db b/bin/tests/system/reclimit/ns1/root.db
index 569abd5ee5..d0aa5296bf 100644
index 30e175b335..7b7c119e0a 100644
--- a/bin/tests/system/reclimit/ns1/root.db
+++ b/bin/tests/system/reclimit/ns1/root.db
@@ -18,5 +18,8 @@ direct.example.net. 60 IN A 10.53.0.2
@@ -20,5 +20,8 @@ direct.example.net. 60 IN A 10.53.0.2
example.com. 60 IN NS direct.example.com.
direct.example.com. 60 IN A 10.53.0.4
@ -5870,10 +5872,10 @@ index 0000000000..e1607e275d
+
+zone "." { type hint; file "hints.db"; };
diff --git a/bin/tests/system/reclimit/setup.sh b/bin/tests/system/reclimit/setup.sh
index 6800532acf..ca20192b69 100644
index 5b39cdf4c7..8ad0586a72 100644
--- a/bin/tests/system/reclimit/setup.sh
+++ b/bin/tests/system/reclimit/setup.sh
@@ -14,3 +14,8 @@ SYSTEMTESTTOP=..
@@ -16,3 +16,8 @@ SYSTEMTESTTOP=..
copy_setports ns1/named.conf.in ns1/named.conf
copy_setports ns3/named1.conf.in ns3/named.conf
@ -5883,10 +5885,10 @@ index 6800532acf..ca20192b69 100644
+$KEYGEN -K ns1 -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" signed >/dev/null 2>&1
+$SIGNER -K ns1 -S -f ns1/signed.db.signed -o signed ns1/signed.db >/dev/null
diff --git a/bin/tests/system/reclimit/tests.sh b/bin/tests/system/reclimit/tests.sh
index f76f955a60..ba574ad27a 100644
index b332e381ff..e9d7235a74 100644
--- a/bin/tests/system/reclimit/tests.sh
+++ b/bin/tests/system/reclimit/tests.sh
@@ -12,7 +12,9 @@
@@ -14,7 +14,9 @@
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
@ -5897,8 +5899,8 @@ index f76f955a60..ba574ad27a 100644
status=0
n=0
@@ -23,6 +25,10 @@ ns3_reset() {
$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush | sed 's/^/I:ns3 /'
@@ -25,6 +27,10 @@ ns3_reset() {
$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush | sed 's/^/I:ns3 /'
}
+ns3_flush() {
@ -5906,162 +5908,162 @@ index f76f955a60..ba574ad27a 100644
+}
+
ns3_sends_aaaa_queries() {
if grep "started AAAA fetch" ns3/named.run >/dev/null; then
return 0
@@ -63,12 +69,12 @@ echo_i "attempt excessive-depth lookup ($n)"
if grep "started AAAA fetch" ns3/named.run >/dev/null; then
return 0
@@ -65,12 +71,12 @@ echo_i "attempt excessive-depth lookup ($n)"
ret=0
echo "1000" > ans2/ans.limit
echo "1000" > ans4/ans.limit
-$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.4 reset > /dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect1.example.org > dig.out.1.test$n || ret=1
echo "1000" >ans2/ans.limit
echo "1000" >ans4/ans.limit
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.4 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect1.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.4 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect1.example.org >dig.out.1.test$n || ret=1
grep "status: SERVFAIL" dig.out.1.test$n > /dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.4 count txt > dig.out.4.test$n || ret=1
grep "status: SERVFAIL" dig.out.1.test$n >/dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
check_query_count dig.out.2.test$n dig.out.4.test$n 27 14
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
@@ -79,12 +85,12 @@ ret=0
echo "12" > ans2/ans.limit
echo "12" > ans4/ans.limit
status=$(expr $status + $ret)
@@ -81,12 +87,12 @@ ret=0
echo "12" >ans2/ans.limit
echo "12" >ans4/ans.limit
ns3_reset ns3/named1.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.4 reset > /dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect2.example.org > dig.out.1.test$n || ret=1
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.4 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect2.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.4 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect2.example.org >dig.out.1.test$n || ret=1
grep "status: NOERROR" dig.out.1.test$n > /dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.4 count txt > dig.out.4.test$n || ret=1
grep "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
check_query_count dig.out.2.test$n dig.out.4.test$n 50 26
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
@@ -96,12 +102,12 @@ echo_i "attempt excessive-depth lookup ($n)"
status=$(expr $status + $ret)
@@ -98,12 +104,12 @@ echo_i "attempt excessive-depth lookup ($n)"
ret=0
echo "12" > ans2/ans.limit
echo "12" >ans2/ans.limit
ns3_reset ns3/named2.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.4 reset > /dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect3.example.org > dig.out.1.test$n || ret=1
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.4 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect3.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.4 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect3.example.org >dig.out.1.test$n || ret=1
grep "status: SERVFAIL" dig.out.1.test$n > /dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.4 count txt > dig.out.4.test$n || ret=1
grep "status: SERVFAIL" dig.out.1.test$n >/dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
check_query_count dig.out.2.test$n dig.out.4.test$n 13 7
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
@@ -112,12 +118,12 @@ ret=0
echo "5" > ans2/ans.limit
echo "5" > ans4/ans.limit
status=$(expr $status + $ret)
@@ -114,12 +120,12 @@ ret=0
echo "5" >ans2/ans.limit
echo "5" >ans4/ans.limit
ns3_reset ns3/named2.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.4 reset > /dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect4.example.org > dig.out.1.test$n || ret=1
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.4 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect4.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.4 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect4.example.org >dig.out.1.test$n || ret=1
grep "status: NOERROR" dig.out.1.test$n > /dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.4 count txt > dig.out.4.test$n || ret=1
grep "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
check_query_count dig.out.2.test$n dig.out.4.test$n 22 12
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
@@ -130,14 +136,14 @@ ret=0
echo "13" > ans2/ans.limit
echo "13" > ans4/ans.limit
status=$(expr $status + $ret)
@@ -132,14 +138,14 @@ ret=0
echo "13" >ans2/ans.limit
echo "13" >ans4/ans.limit
ns3_reset ns3/named3.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.4 reset > /dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect5.example.org > dig.out.1.test$n || ret=1
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.4 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect5.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.4 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect5.example.org >dig.out.1.test$n || ret=1
if ns3_sends_aaaa_queries; then
grep "status: SERVFAIL" dig.out.1.test$n > /dev/null || ret=1
grep "status: SERVFAIL" dig.out.1.test$n >/dev/null || ret=1
fi
-$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.4 count txt > dig.out.4.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
eval count=`cat dig.out.2.test$n`
[ $count -le 50 ] || { ret=1; echo_i "count ($count) !<= 50"; }
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -148,10 +154,10 @@ echo_i "attempt permissible lookup ($n)"
eval count=$(cat dig.out.2.test$n)
[ $count -le 50 ] || {
ret=1
@@ -153,10 +159,10 @@ echo_i "attempt permissible lookup ($n)"
ret=0
echo "12" > ans2/ans.limit
echo "12" >ans2/ans.limit
ns3_reset ns3/named3.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect6.example.org > dig.out.1.test$n || ret=1
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect6.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect6.example.org >dig.out.1.test$n || ret=1
grep "status: NOERROR" dig.out.1.test$n > /dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
grep "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
eval count=`cat dig.out.2.test$n`
[ $count -le 50 ] || { ret=1; echo_i "count ($count) !<= 50"; }
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -164,12 +170,12 @@ echo_i "attempt excessive-queries lookup ($n)"
eval count=$(cat dig.out.2.test$n)
[ $count -le 50 ] || {
ret=1
@@ -172,12 +178,12 @@ echo_i "attempt excessive-queries lookup ($n)"
ret=0
echo "11" > ans2/ans.limit
echo "11" >ans2/ans.limit
ns3_reset ns3/named4.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect7.example.org > dig.out.1.test$n || ret=1
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect7.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect7.example.org >dig.out.1.test$n || ret=1
if ns3_sends_aaaa_queries; then
grep "status: SERVFAIL" dig.out.1.test$n > /dev/null || ret=1
grep "status: SERVFAIL" dig.out.1.test$n >/dev/null || ret=1
fi
-$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
eval count=`cat dig.out.2.test$n`
[ $count -le 40 ] || { ret=1; echo_i "count ($count) !<= 40"; }
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -180,10 +186,10 @@ echo_i "attempt permissible lookup ($n)"
eval count=$(cat dig.out.2.test$n)
[ $count -le 40 ] || {
ret=1
@@ -191,10 +197,10 @@ echo_i "attempt permissible lookup ($n)"
ret=0
echo "9" > ans2/ans.limit
echo "9" >ans2/ans.limit
ns3_reset ns3/named4.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect8.example.org > dig.out.1.test$n || ret=1
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect8.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect8.example.org >dig.out.1.test$n || ret=1
grep "status: NOERROR" dig.out.1.test$n > /dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
grep "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
eval count=`cat dig.out.2.test$n`
[ $count -le 40 ] || { ret=1; echo_i "count ($count) !<= 40"; }
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -193,12 +199,12 @@ n=`expr $n + 1`
eval count=$(cat dig.out.2.test$n)
[ $count -le 40 ] || {
ret=1
@@ -207,12 +213,12 @@ n=$(expr $n + 1)
echo_i "attempting NS explosion ($n)"
ret=0
ns3_reset ns3/named4.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset > /dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.3 ns1.1.example.net > dig.out.1.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt > dig.out.2.test$n || ret=1
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.3 ns1.1.example.net >dig.out.1.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts +short @10.53.0.3 ns1.1.example.net >dig.out.1.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
eval count=`cat dig.out.2.test$n`
eval count=$(cat dig.out.2.test$n)
[ $count -lt 50 ] || ret=1
-$DIG $DIGOPTS +short @10.53.0.7 count txt > dig.out.3.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.7 count txt >dig.out.3.test$n || ret=1
+dig_with_opts +short @10.53.0.7 count txt >dig.out.3.test$n || ret=1
eval count=`cat dig.out.3.test$n`
[ $count -lt 50 ] || { ret=1; echo_i "count ($count) !<= 50"; }
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -207,13 +213,254 @@ status=`expr $status + $ret`
eval count=$(cat dig.out.3.test$n)
[ $count -lt 50 ] || {
ret=1
@@ -224,13 +230,254 @@ status=$(expr $status + $ret)
n=$((n + 1))
echo_i "checking RRset that exceeds max-records-per-type ($n)"
ret=0
@ -6319,5 +6321,5 @@ index f76f955a60..ba574ad27a 100644
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
--
2.45.2
2.53.0

View File

@ -1,4 +1,4 @@
From a1c95d5fa479ac722f0cf758c494a37ffe1508c0 Mon Sep 17 00:00:00 2001
From 06236a2d32c1d8f29208321d276e742f9259efd2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Sat, 25 May 2024 11:46:56 +0200
Subject: [PATCH] Add a limit to the number of RR types for single name
@ -79,10 +79,10 @@ error being logged. This commit fixes that.
20 files changed, 156 insertions(+), 19 deletions(-)
diff --git a/bin/named/config.c b/bin/named/config.c
index 9cba6f588b..c9888ada65 100644
index 72dec1a..ec48840 100644
--- a/bin/named/config.c
+++ b/bin/named/config.c
@@ -218,6 +218,7 @@ options {\n\
@@ -229,6 +229,7 @@ options {\n\
max-records-per-type 100;\n\
max-refresh-time 2419200; /* 4 weeks */\n\
max-retry-time 1209600; /* 2 weeks */\n\
@ -91,10 +91,10 @@ index 9cba6f588b..c9888ada65 100644
max-transfer-idle-out 60;\n\
max-transfer-time-in 120;\n\
diff --git a/bin/named/server.c b/bin/named/server.c
index 7bf5f2664d..4cc69b54a1 100644
index f550814..c68b8d1 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -5427,6 +5427,15 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
@@ -5461,6 +5461,15 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
INSIST(result == ISC_R_SUCCESS);
dns_view_setmaxrrperset(view, cfg_obj_asuint32(obj));
@ -111,10 +111,10 @@ index 7bf5f2664d..4cc69b54a1 100644
result = named_config_get(maps, "max-recursion-depth", &obj);
INSIST(result == ISC_R_SUCCESS);
diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c
index ae5cc656ee..f6e8c64866 100644
index 81f6879..821e6a1 100644
--- a/bin/named/zoneconf.c
+++ b/bin/named/zoneconf.c
@@ -1100,6 +1100,14 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
@@ -1080,6 +1080,14 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
dns_zone_setmaxrrperset(zone, 0);
}
@ -130,10 +130,10 @@ index ae5cc656ee..f6e8c64866 100644
#define SIGNED ".signed"
size_t signedlen = strlen(filename) + sizeof(SIGNED);
diff --git a/bin/tests/system/dyndb/driver/db.c b/bin/tests/system/dyndb/driver/db.c
index 6725a3bacd..c95fc8212b 100644
index 727268f..398589a 100644
--- a/bin/tests/system/dyndb/driver/db.c
+++ b/bin/tests/system/dyndb/driver/db.c
@@ -593,7 +593,8 @@ static dns_dbmethods_t sampledb_methods = {
@@ -623,7 +623,8 @@ static dns_dbmethods_t sampledb_methods = {
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
NULL, /* adjusthashsize */
@ -144,10 +144,10 @@ index 6725a3bacd..c95fc8212b 100644
/* Auxiliary driver functions. */
diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst
index b1983ef30d..a8a3c7911d 100644
index fbd8edb..0ce2d1f 100644
--- a/doc/arm/reference.rst
+++ b/doc/arm/reference.rst
@@ -2902,6 +2902,18 @@ system.
@@ -2957,6 +2957,18 @@ system.
a failure. If set to 0, there is no cap on RRset size. The default is
100.
@ -167,10 +167,10 @@ index b1983ef30d..a8a3c7911d 100644
This sets the maximum number (a "hard quota") of simultaneous recursive lookups
the server performs on behalf of clients. The default is
diff --git a/lib/dns/cache.c b/lib/dns/cache.c
index 9f0412dbe7..0b474fc313 100644
index 8cb442b..125cfdc 100644
--- a/lib/dns/cache.c
+++ b/lib/dns/cache.c
@@ -150,6 +150,7 @@ struct dns_cache {
@@ -153,6 +153,7 @@ struct dns_cache {
/* Access to the on-disk cache file is also locked by 'filelock'. */
uint32_t maxrrperset;
@ -178,15 +178,15 @@ index 9f0412dbe7..0b474fc313 100644
};
/***
@@ -178,6 +179,7 @@ cache_create_db(dns_cache_t *cache, dns_db_t **db) {
if (result == ISC_R_SUCCESS) {
dns_db_setservestalettl(*db, cache->serve_stale_ttl);
@@ -187,6 +188,7 @@ cache_create_db(dns_cache_t *cache, dns_db_t **db) {
dns_db_setservestalettl(*db, cache->serve_stale_ttl);
dns_db_setmaxrrperset(*db, cache->maxrrperset);
+ dns_db_setmaxtypepername(*db, cache->maxtypepername);
}
return (result);
}
@@ -1290,6 +1292,16 @@ dns_cache_setmaxrrperset(dns_cache_t *cache, uint32_t value) {
if (cache->taskmgr == NULL) {
return (ISC_R_SUCCESS);
@@ -1329,6 +1331,16 @@ dns_cache_setmaxrrperset(dns_cache_t *cache, uint32_t value) {
}
}
@ -204,10 +204,10 @@ index 9f0412dbe7..0b474fc313 100644
* XXX: Much of the following code has been copied in from statschannel.c.
* We should refactor this into a generic function in stats.c that can be
diff --git a/lib/dns/db.c b/lib/dns/db.c
index 8439265a7f..18583d41c2 100644
index a575d62..1f19016 100644
--- a/lib/dns/db.c
+++ b/lib/dns/db.c
@@ -1131,3 +1131,12 @@ dns_db_setmaxrrperset(dns_db_t *db, uint32_t value) {
@@ -1146,3 +1146,12 @@ dns_db_setmaxrrperset(dns_db_t *db, uint32_t value) {
(db->methods->setmaxrrperset)(db, value);
}
}
@ -221,10 +221,10 @@ index 8439265a7f..18583d41c2 100644
+ }
+}
diff --git a/lib/dns/dnsrps.c b/lib/dns/dnsrps.c
index 539090d1bd..e1a1b21a8b 100644
index f4d9bae..43c28ae 100644
--- a/lib/dns/dnsrps.c
+++ b/lib/dns/dnsrps.c
@@ -971,7 +971,8 @@ static dns_dbmethods_t rpsdb_db_methods = {
@@ -976,7 +976,8 @@ static dns_dbmethods_t rpsdb_db_methods = {
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
NULL, /* adjusthashsize */
@ -235,10 +235,10 @@ index 539090d1bd..e1a1b21a8b 100644
static dns_rdatasetmethods_t rpsdb_rdataset_methods = {
diff --git a/lib/dns/ecdb.c b/lib/dns/ecdb.c
index bab5da5503..27d03b4e3a 100644
index 42a1248..3e562d8 100644
--- a/lib/dns/ecdb.c
+++ b/lib/dns/ecdb.c
@@ -560,7 +560,8 @@ static dns_dbmethods_t ecdb_methods = {
@@ -564,7 +564,8 @@ static dns_dbmethods_t ecdb_methods = {
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
NULL, /* adjusthashsize */
@ -249,10 +249,10 @@ index bab5da5503..27d03b4e3a 100644
static isc_result_t
diff --git a/lib/dns/include/dns/cache.h b/lib/dns/include/dns/cache.h
index 3fa2a891e0..72de21600a 100644
index 34539eb..eb6f1e9 100644
--- a/lib/dns/include/dns/cache.h
+++ b/lib/dns/include/dns/cache.h
@@ -343,6 +343,12 @@ dns_cache_setmaxrrperset(dns_cache_t *cache, uint32_t value);
@@ -340,6 +340,12 @@ dns_cache_setmaxrrperset(dns_cache_t *cache, uint32_t value);
* Set the maximum resource records per RRSet that can be cached.
*/
@ -266,18 +266,18 @@ index 3fa2a891e0..72de21600a 100644
int
dns_cache_renderxml(dns_cache_t *cache, void *writer0);
diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h
index 732bfe473d..411881d48a 100644
index e0d17f2..3c6c7f2 100644
--- a/lib/dns/include/dns/db.h
+++ b/lib/dns/include/dns/db.h
@@ -183,6 +183,7 @@ typedef struct dns_dbmethods {
@@ -185,6 +185,7 @@ typedef struct dns_dbmethods {
isc_result_t (*setgluecachestats)(dns_db_t *db, isc_stats_t *stats);
isc_result_t (*adjusthashsize)(dns_db_t *db, size_t size);
void (*setmaxrrperset)(dns_db_t *db, uint32_t value);
+ void (*setmaxtypepername)(dns_db_t *db, uint32_t value);
} dns_dbmethods_t;
typedef isc_result_t (*dns_dbcreatefunc_t)(isc_mem_t *mctx,
@@ -1791,6 +1792,16 @@ dns_db_setmaxrrperset(dns_db_t *db, uint32_t value);
typedef isc_result_t (*dns_dbcreatefunc_t)(isc_mem_t *mctx,
@@ -1804,6 +1805,16 @@ dns_db_setmaxrrperset(dns_db_t *db, uint32_t value);
* is nonzero, then any subsequent attempt to add an rdataset with
* more than 'value' RRs will return ISC_R_NOSPACE.
*/
@ -295,18 +295,18 @@ index 732bfe473d..411881d48a 100644
#endif /* DNS_DB_H */
diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h
index 0d502f4dd2..0a72f58e98 100644
index b7cf663..4151c11 100644
--- a/lib/dns/include/dns/view.h
+++ b/lib/dns/include/dns/view.h
@@ -187,6 +187,7 @@ struct dns_view {
@@ -189,6 +189,7 @@ struct dns_view {
uint32_t fail_ttl;
dns_badcache_t *failcache;
dns_badcache_t *failcache;
uint32_t maxrrperset;
+ uint32_t maxtypepername;
/*
* Configurable data for server use only,
@@ -1346,6 +1347,12 @@ dns_view_setmaxrrperset(dns_view_t *view, uint32_t value);
@@ -1361,6 +1362,12 @@ dns_view_setmaxrrperset(dns_view_t *view, uint32_t value);
* Set the maximum resource records per RRSet that can be cached.
*/
@ -320,10 +320,10 @@ index 0d502f4dd2..0a72f58e98 100644
#endif /* DNS_VIEW_H */
diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h
index e902043357..6fca11f3fd 100644
index a98b28f..d893dd2 100644
--- a/lib/dns/include/dns/zone.h
+++ b/lib/dns/include/dns/zone.h
@@ -356,6 +356,19 @@ dns_zone_setmaxrrperset(dns_zone_t *zone, uint32_t maxrrperset);
@@ -358,6 +358,19 @@ dns_zone_setmaxrrperset(dns_zone_t *zone, uint32_t maxrrperset);
*\li void
*/
@ -344,10 +344,10 @@ index e902043357..6fca11f3fd 100644
dns_zone_setmaxttl(dns_zone_t *zone, uint32_t maxttl);
/*%<
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index ca71bb9c03..ed5015c2d4 100644
index e8de346..c2cd63e 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -483,6 +483,7 @@ struct dns_rbtdb {
@@ -497,6 +497,7 @@ struct dns_rbtdb {
rbtdb_serial_t least_serial;
rbtdb_serial_t next_serial;
uint32_t maxrrperset;
@ -355,7 +355,7 @@ index ca71bb9c03..ed5015c2d4 100644
rbtdb_version_t *current_version;
rbtdb_version_t *future_version;
rbtdb_versionlist_t open_versions;
@@ -6222,19 +6223,13 @@ update_recordsandxfrsize(bool add, rbtdb_version_t *rbtversion,
@@ -6259,19 +6260,13 @@ update_recordsandxfrsize(bool add, rbtdb_version_t *rbtversion,
RWUNLOCK(&rbtversion->rwlock, isc_rwlocktype_write);
}
@ -377,7 +377,7 @@ index ca71bb9c03..ed5015c2d4 100644
}
static bool
@@ -6794,7 +6789,7 @@ find_header:
@@ -6809,7 +6804,7 @@ find_header:
if (!IS_CACHE(rbtdb) && overmaxtype(rbtdb, ntypes)) {
free_rdataset(rbtdb, rbtdb->common.mctx,
newheader);
@ -386,7 +386,7 @@ index ca71bb9c03..ed5015c2d4 100644
}
newheader->down = NULL;
@@ -8623,6 +8618,15 @@ setmaxrrperset(dns_db_t *db, uint32_t maxrrperset) {
@@ -8627,6 +8622,15 @@ setmaxrrperset(dns_db_t *db, uint32_t maxrrperset) {
rbtdb->maxrrperset = maxrrperset;
}
@ -402,7 +402,7 @@ index ca71bb9c03..ed5015c2d4 100644
static dns_stats_t *
getrrsetstats(dns_db_t *db) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
@@ -8747,7 +8751,8 @@ static dns_dbmethods_t zone_methods = { attach,
@@ -8751,7 +8755,8 @@ static dns_dbmethods_t zone_methods = { attach,
NULL, /* getservestalerefresh */
setgluecachestats,
adjusthashsize,
@ -412,7 +412,7 @@ index ca71bb9c03..ed5015c2d4 100644
static dns_dbmethods_t cache_methods = { attach,
detach,
@@ -8800,7 +8805,8 @@ static dns_dbmethods_t cache_methods = { attach,
@@ -8804,7 +8809,8 @@ static dns_dbmethods_t cache_methods = { attach,
getservestalerefresh,
NULL,
adjusthashsize,
@ -423,10 +423,10 @@ index ca71bb9c03..ed5015c2d4 100644
isc_result_t
dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c
index 84cd324fb4..77a5834b76 100644
index 282c327..4438091 100644
--- a/lib/dns/sdb.c
+++ b/lib/dns/sdb.c
@@ -1313,7 +1313,8 @@ static dns_dbmethods_t sdb_methods = {
@@ -1320,7 +1320,8 @@ static dns_dbmethods_t sdb_methods = {
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
NULL, /* adjusthashsize */
@ -437,10 +437,10 @@ index 84cd324fb4..77a5834b76 100644
static isc_result_t
diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c
index 60a1d23b3b..418a4a14ee 100644
index 299c7d8..a8556df 100644
--- a/lib/dns/sdlz.c
+++ b/lib/dns/sdlz.c
@@ -1285,7 +1285,8 @@ static dns_dbmethods_t sdlzdb_methods = {
@@ -1293,7 +1293,8 @@ static dns_dbmethods_t sdlzdb_methods = {
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
NULL, /* adjusthashsize */
@ -451,10 +451,10 @@ index 60a1d23b3b..418a4a14ee 100644
/*
diff --git a/lib/dns/view.c b/lib/dns/view.c
index a672aa8bc8..98579f03d9 100644
index 9f5daf7..0de880d 100644
--- a/lib/dns/view.c
+++ b/lib/dns/view.c
@@ -871,6 +871,7 @@ dns_view_setcache(dns_view_t *view, dns_cache_t *cache, bool shared) {
@@ -873,6 +873,7 @@ dns_view_setcache(dns_view_t *view, dns_cache_t *cache, bool shared) {
INSIST(DNS_DB_VALID(view->cachedb));
dns_cache_setmaxrrperset(view->cache, view->maxrrperset);
@ -462,7 +462,7 @@ index a672aa8bc8..98579f03d9 100644
}
bool
@@ -2555,3 +2556,12 @@ dns_view_setmaxrrperset(dns_view_t *view, uint32_t value) {
@@ -2651,3 +2652,12 @@ dns_view_setmaxrrperset(dns_view_t *view, uint32_t value) {
dns_cache_setmaxrrperset(view->cache, value);
}
}
@ -476,10 +476,10 @@ index a672aa8bc8..98579f03d9 100644
+ }
+}
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index 5c8d97ed18..e1fb9ab50b 100644
index 301f440..ae5ef43 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -277,6 +277,7 @@ struct dns_zone {
@@ -308,6 +308,7 @@ struct dns_zone {
uint32_t maxrecords;
uint32_t maxrrperset;
@ -487,7 +487,7 @@ index 5c8d97ed18..e1fb9ab50b 100644
isc_sockaddr_t *masters;
isc_dscp_t *masterdscps;
@@ -9959,6 +9960,7 @@ cleanup:
@@ -10060,6 +10061,7 @@ cleanup:
}
dns_diff_clear(&_sig_diff);
@ -495,7 +495,7 @@ index 5c8d97ed18..e1fb9ab50b 100644
for (i = 0; i < nkeys; i++) {
dst_key_free(&zone_keys[i]);
@@ -12168,6 +12170,16 @@ dns_zone_setmaxrrperset(dns_zone_t *zone, uint32_t val) {
@@ -12319,6 +12321,16 @@ dns_zone_setmaxrrperset(dns_zone_t *zone, uint32_t val) {
}
}
@ -512,36 +512,36 @@ index 5c8d97ed18..e1fb9ab50b 100644
static bool
notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
isc_sockaddr_t *addr, dns_tsigkey_t *key) {
@@ -14573,6 +14585,8 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
@@ -14733,6 +14745,8 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
}
dns_db_settask(stub->db, zone->task);
dns_db_settask(stub->db, zone->task, zone->task);
dns_db_setmaxrrperset(stub->db, zone->maxrrperset);
+ dns_db_setmaxtypepername(stub->db,
+ zone->maxtypepername);
}
result = dns_db_newversion(stub->db, &stub->version);
@@ -17295,6 +17309,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
@@ -17476,6 +17490,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
zone_attachdb(zone, db);
dns_db_settask(zone->db, zone->task);
dns_db_settask(zone->db, zone->task, zone->task);
dns_db_setmaxrrperset(zone->db, zone->maxrrperset);
+ dns_db_setmaxtypepername(zone->db, zone->maxtypepername);
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY);
return (ISC_R_SUCCESS);
@@ -23444,6 +23459,7 @@ dns_zone_makedb(dns_zone_t *zone, dns_db_t **dbp) {
@@ -23659,6 +23674,7 @@ dns_zone_makedb(dns_zone_t *zone, dns_db_t **dbp) {
dns_db_settask(db, zone->task);
dns_db_settask(db, zone->task, zone->task);
dns_db_setmaxrrperset(db, zone->maxrrperset);
+ dns_db_setmaxtypepername(db, zone->maxtypepername);
*dbp = db;
diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c
index dce30537dd..ac9fc2af5e 100644
index ffe22b3..69525dc 100644
--- a/lib/isccfg/namedconf.c
+++ b/lib/isccfg/namedconf.c
@@ -2239,6 +2239,9 @@ static cfg_clausedef_t zone_clauses[] = {
@@ -2244,6 +2244,9 @@ static cfg_clausedef_t zone_clauses[] = {
{ "max-records-per-type", &cfg_type_uint32,
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT },
@ -552,10 +552,10 @@ index dce30537dd..ac9fc2af5e 100644
CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
{ "max-retry-time", &cfg_type_uint32,
diff --git a/lib/ns/update.c b/lib/ns/update.c
index c5ce1eaf09..0e0bdc9c03 100644
index 4e51cdc..d9cea2c 100644
--- a/lib/ns/update.c
+++ b/lib/ns/update.c
@@ -3112,9 +3112,18 @@ update_action(isc_task_t *task, isc_event_t *event) {
@@ -3136,9 +3136,18 @@ update_action(isc_task_t *task, isc_event_t *event) {
dns_diff_clear(&ctx.add_diff);
goto failure;
}
@ -578,5 +578,5 @@ index c5ce1eaf09..0e0bdc9c03 100644
}
} else if (update_class == dns_rdataclass_any) {
--
2.45.2
2.51.1

View File

@ -1,4 +1,4 @@
From c5357835c98b7b028f8a041b6976bb335c9a4056 Mon Sep 17 00:00:00 2001
From aed0e33be79d1d1b133208846d943503c4f2e6a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Fri, 1 Mar 2024 08:26:07 +0100
Subject: [PATCH] Add a limit to the number of RRs in RRSets
@ -83,45 +83,46 @@ smarter:
(cherry picked from commit 57cd34441a1b4ecc9874a4a106c2c95b8d7a3120)
(cherry picked from commit 26c9da5f2857b72077c17e06ac79f068c63782cc)
---
bin/tests/system/resolver/tests.sh | 9 ++-
configure | 2 +-
configure.ac | 2 +-
lib/dns/rbtdb.c | 125 ++++++++++++++++++++++++++++-
lib/dns/rdataslab.c | 12 +++
5 files changed, 144 insertions(+), 6 deletions(-)
bin/tests/system/resolver/tests.sh | 9 ++--
configure | 2 +-
configure.ac | 2 +-
lib/dns/rbtdb.c | 83 +++++++++++++++++++++++++++++-
lib/dns/rdataslab.c | 12 +++++
lib/dns/zone.c | 13 -----
6 files changed, 100 insertions(+), 21 deletions(-)
diff --git a/bin/tests/system/resolver/tests.sh b/bin/tests/system/resolver/tests.sh
index 6c69c1104e..bd997a61a4 100755
index fc05635e31..09fff0dd13 100755
--- a/bin/tests/system/resolver/tests.sh
+++ b/bin/tests/system/resolver/tests.sh
@@ -553,15 +553,20 @@ n=`expr $n + 1`
@@ -596,18 +596,17 @@ n=$((n + 1))
echo_i "check prefetch qtype * (${n})"
ret=0
$DIG $DIGOPTS @10.53.0.5 fetchall.tld any > dig.out.1.${n} || ret=1
-ttl1=`awk '/"A" "short" "ttl"/ { print $2 - 3 }' dig.out.1.${n}`
dig_with_opts @10.53.0.5 fetchall.tld any >dig.out.1.${n} || ret=1
-ttl1=$(awk '/"A" "short" "ttl"/ { print $2 - 3 }' dig.out.1.${n})
+ttl1=$(awk '/^fetchall.tld/ { print $2 - 3; exit }' dig.out.1.${n})
# sleep so we are in prefetch range
sleep ${ttl1:-0}
sleep "${ttl1:-0}"
# trigger prefetch
$DIG $DIGOPTS @10.53.0.5 fetchall.tld any > dig.out.2.${n} || ret=1
-ttl2=`awk '/"A" "short" "ttl"/ { print $2 }' dig.out.2.${n}`
dig_with_opts @10.53.0.5 fetchall.tld any >dig.out.2.${n} || ret=1
-ttl2=$(awk '/"A" "short" "ttl"/ { print $2 }' dig.out.2.${n})
+ttl2=$(awk '/^fetchall.tld/ { print $2; exit }' dig.out.2.${n})
sleep 1
# check that the nameserver is still alive
$DIG $DIGOPTS @10.53.0.5 fetchall.tld any > dig.out.3.${n} || ret=1
-# check that prefetch occurred;
-# note that only one record is prefetched, which is the AAAA record in this case,
+# note that only the first record is prefetched,
+# because of the order of the records in the cache
+$DIG $DIGOPTS @10.53.0.5 fetchall.tld any >dig.out.3.${n} || ret=1
# because of the order of the records in the cache
dig_with_opts @10.53.0.5 fetchall.tld any >dig.out.3.${n} || ret=1
-ttl3=$(awk '/::1/ { print $2 }' dig.out.3.${n})
+ttl3=$(awk '/^fetchall.tld/ { print $2; exit }' dig.out.3.${n})
+test "${ttl3:-0}" -gt "${ttl2:-1}" || ret=1
test "${ttl3:-0}" -gt "${ttl2:-1}" || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
status=$((status + ret))
diff --git a/configure b/configure
index ed2d4869e5..be0f60eaba 100755
index 1b436d63eb..835cd94dff 100755
--- a/configure
+++ b/configure
@@ -12295,7 +12295,7 @@ fi
@@ -12341,7 +12341,7 @@ fi
XTARGETS=
if test "$enable_developer" = "yes"; then :
@ -131,10 +132,10 @@ index ed2d4869e5..be0f60eaba 100755
test "${enable_querytrace+set}" = set || enable_querytrace=yes
test "${with_cmocka+set}" = set || with_cmocka=yes
diff --git a/configure.ac b/configure.ac
index 287de41369..3ff4bdd135 100644
index fb6f172eae..6db42501a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -94,7 +94,7 @@ AC_ARG_ENABLE([developer],
@@ -96,7 +96,7 @@ AC_ARG_ENABLE([developer],
XTARGETS=
AS_IF([test "$enable_developer" = "yes"],
@ -144,34 +145,22 @@ index 287de41369..3ff4bdd135 100644
test "${enable_querytrace+set}" = set || enable_querytrace=yes
test "${with_cmocka+set}" = set || with_cmocka=yes
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index 2707507bd7..e840c0665d 100644
index 3f06545aa1..d4c1829c26 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -967,6 +967,48 @@ set_ttl(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, dns_ttl_t newttl) {
}
}
+static bool
+prio_type(rbtdb_rdatatype_t type) {
+ switch (type) {
+ case dns_rdatatype_soa:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_soa):
+ case dns_rdatatype_a:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_a):
@@ -990,6 +990,8 @@ prio_type(rbtdb_rdatatype_t type) {
case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_soa):
case dns_rdatatype_a:
case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_a):
+ case dns_rdatatype_mx:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_mx):
+ case dns_rdatatype_aaaa:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_aaaa):
+ case dns_rdatatype_nsec:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec):
+ case dns_rdatatype_nsec3:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_nsec3):
+ case dns_rdatatype_ns:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ns):
+ case dns_rdatatype_ds:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ds):
+ case dns_rdatatype_cname:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_cname):
case dns_rdatatype_aaaa:
case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_aaaa):
case dns_rdatatype_nsec:
@@ -1002,6 +1004,22 @@ prio_type(rbtdb_rdatatype_t type) {
case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ds):
case dns_rdatatype_cname:
case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_cname):
+ case dns_rdatatype_dname:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_dname):
+ case dns_rdatatype_svcb:
@ -188,15 +177,10 @@ index 2707507bd7..e840c0665d 100644
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ptr):
+ case dns_rdatatype_naptr:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_naptr):
+ return (true);
+ }
+ return (false);
+}
+
/*%
* These functions allow the heap code to rank the priority of each
* element. It returns true if v1 happens "sooner" than v2.
@@ -6179,6 +6221,30 @@ update_recordsandxfrsize(bool add, rbtdb_version_t *rbtversion,
return (true);
}
return (false);
@@ -6240,6 +6258,30 @@ update_recordsandxfrsize(bool add, rbtdb_version_t *rbtversion,
RWUNLOCK(&rbtversion->rwlock, isc_rwlocktype_write);
}
@ -227,15 +211,16 @@ index 2707507bd7..e840c0665d 100644
/*
* write lock on rbtnode must be held.
*/
@@ -6190,6 +6256,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename,
@@ -6251,7 +6293,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename,
rbtdb_changed_t *changed = NULL;
rdatasetheader_t *topheader = NULL, *topheader_prev = NULL;
rdatasetheader_t *header = NULL, *sigheader = NULL;
- rdatasetheader_t *prioheader = NULL;
+ rdatasetheader_t *prioheader = NULL, *expireheader = NULL;
unsigned char *merged = NULL;
isc_result_t result;
bool header_nx;
@@ -6199,6 +6266,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename,
@@ -6261,6 +6303,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename,
rbtdb_rdatatype_t negtype, sigtype;
dns_trust_t trust;
int idx;
@ -243,35 +228,31 @@ index 2707507bd7..e840c0665d 100644
/*
* Add an rdatasetheader_t to a node.
@@ -6272,6 +6340,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename,
topheader = topheader->next) {
@@ -6336,6 +6379,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename,
{
if (topheader->type == sigtype) {
sigheader = topheader;
+ break;
}
}
negtype = RBTDB_RDATATYPE_VALUE(covers, 0);
@@ -6331,6 +6400,15 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename,
@@ -6398,6 +6442,12 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename,
for (topheader = rbtnode->data; topheader != NULL;
topheader = topheader->next) {
topheader = topheader->next)
{
+ if (IS_CACHE(rbtdb) && ACTIVE(topheader, now)) {
+ ++ntypes;
+ expireheader = topheader;
+ } else if (!IS_CACHE(rbtdb)) {
+ ++ntypes;
+ }
+ if (prio_header(topheader)) {
+ prioheader = topheader;
+ }
if (topheader->type == newheader->type ||
topheader->type == negtype) {
break;
@@ -6712,9 +6790,52 @@ find_header:
if (prio_type(topheader->type)) {
prioheader = topheader;
}
@@ -6755,6 +6805,12 @@ find_header:
/*
* No rdatasets of the given type exist at the node.
*/
- newheader->next = rbtnode->data;
+ if (!IS_CACHE(rbtdb) && overmaxtype(rbtdb, ntypes)) {
+ free_rdataset(rbtdb, rbtdb->common.mctx,
+ newheader);
@ -279,21 +260,12 @@ index 2707507bd7..e840c0665d 100644
+ }
+
newheader->down = NULL;
- rbtnode->data = newheader;
+
+ if (prio_header(newheader)) {
+ /* This is a priority type, prepend it */
+ newheader->next = rbtnode->data;
+ rbtnode->data = newheader;
+ } else if (prioheader != NULL) {
+ /* Append after the priority headers */
+ newheader->next = prioheader->next;
+ prioheader->next = newheader;
+ } else {
+ /* There were no priority headers */
+ newheader->next = rbtnode->data;
+ rbtnode->data = newheader;
+ }
if (prio_type(newheader->type)) {
@@ -6770,6 +6826,31 @@ find_header:
newheader->next = rbtnode->data;
rbtnode->data = newheader;
}
+
+ if (IS_CACHE(rbtdb) && overmaxtype(rbtdb, ntypes)) {
+ if (expireheader == NULL) {
@ -323,10 +295,10 @@ index 2707507bd7..e840c0665d 100644
}
diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c
index 1d5e88f745..dda903819a 100644
index 14c43818b8..d74e84ce4a 100644
--- a/lib/dns/rdataslab.c
+++ b/lib/dns/rdataslab.c
@@ -110,6 +110,10 @@ fillin_offsets(unsigned char *offsetbase, unsigned int *offsettable,
@@ -112,6 +112,10 @@ fillin_offsets(unsigned char *offsetbase, unsigned int *offsettable,
}
#endif /* if DNS_RDATASET_FIXED */
@ -337,7 +309,7 @@ index 1d5e88f745..dda903819a 100644
isc_result_t
dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
isc_region_t *region, unsigned int reservelen) {
@@ -154,6 +158,10 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
@@ -156,6 +160,10 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
return (ISC_R_SUCCESS);
}
@ -348,7 +320,7 @@ index 1d5e88f745..dda903819a 100644
if (nitems > 0xffff) {
return (ISC_R_NOSPACE);
}
@@ -520,6 +528,10 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
@@ -524,6 +532,10 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
#endif /* if DNS_RDATASET_FIXED */
INSIST(ocount > 0 && ncount > 0);
@ -359,6 +331,30 @@ index 1d5e88f745..dda903819a 100644
#if DNS_RDATASET_FIXED
oncount = ncount;
#endif /* if DNS_RDATASET_FIXED */
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index b457095907..53da95a7d7 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -2316,19 +2316,6 @@ zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
isc_result_totext(result));
goto cleanup;
}
- dns_db_settask(db, zone->task, zone->task);
-
- if (zone->type == dns_zone_primary ||
- zone->type == dns_zone_secondary || zone->type == dns_zone_mirror)
- {
- result = dns_db_setgluecachestats(db, zone->gluecachestats);
- if (result == ISC_R_NOTIMPLEMENTED) {
- result = ISC_R_SUCCESS;
- }
- if (result != ISC_R_SUCCESS) {
- goto cleanup;
- }
- }
if (!dns_db_ispersistent(db)) {
if (zone->masterfile != NULL) {
--
2.45.2
2.53.0

View File

@ -1,4 +1,4 @@
From 34e92fc88943beeba76aa4e408951cb46d8cdb53 Mon Sep 17 00:00:00 2001
From ec67f14dc90e17acf08708e53a2166e0554b25ca Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Tue, 16 Jul 2024 19:49:09 +0200
Subject: [PATCH] Resolve CVE-2024-1975
@ -14,15 +14,15 @@ Resolves: CVE-2024-1975
doc/arm/general.rst | 6 +-
doc/arm/reference.rst | 4 +-
doc/arm/security.rst | 4 +-
lib/dns/message.c | 97 ++--------------------------
lib/dns/message.c | 99 ++--------------------------
lib/ns/client.c | 7 ++
8 files changed, 43 insertions(+), 113 deletions(-)
8 files changed, 43 insertions(+), 115 deletions(-)
diff --git a/bin/tests/system/tsiggss/authsock.pl b/bin/tests/system/tsiggss/authsock.pl
index ab3833d..0b231ee 100644
index d629c65..b3888fb 100644
--- a/bin/tests/system/tsiggss/authsock.pl
+++ b/bin/tests/system/tsiggss/authsock.pl
@@ -31,6 +31,10 @@ if (!defined($path)) {
@@ -33,6 +33,10 @@ if (!defined($path)) {
exit(1);
}
@ -33,7 +33,7 @@ index ab3833d..0b231ee 100644
unlink($path);
my $server = IO::Socket::UNIX->new(Local => $path, Type => SOCK_STREAM, Listen => 8) or
die "unable to create socket $path";
@@ -53,6 +57,7 @@ if ($timeout != 0) {
@@ -55,6 +59,7 @@ if ($timeout != 0) {
}
while (my $client = $server->accept()) {
@ -42,26 +42,26 @@ index ab3833d..0b231ee 100644
my ($version, $req_len) = unpack('N N', $buf);
diff --git a/bin/tests/system/tsiggss/tests.sh b/bin/tests/system/tsiggss/tests.sh
index 632bb87..7977e49 100644
index a665703..34b8c89 100644
--- a/bin/tests/system/tsiggss/tests.sh
+++ b/bin/tests/system/tsiggss/tests.sh
@@ -116,7 +116,7 @@ status=$((status+ret))
@@ -116,7 +116,7 @@ status=$((status + ret))
echo_i "testing external update policy (CNAME) with auth sock ($n)"
ret=0
-$PERL ./authsock.pl --type=CNAME --path=ns1/auth.sock --pidfile=authsock.pid --timeout=120 > /dev/null 2>&1 &
-$PERL ./authsock.pl --type=CNAME --path=ns1/auth.sock --pidfile=authsock.pid --timeout=120 >/dev/null 2>&1 &
+$PERL ./authsock.pl --type=CNAME --path=ns1/auth.sock --pidfile=authsock.pid --timeout=120 >authsock.log 2>&1 &
sleep 1
test_update $n testcname.example.nil. CNAME "86400 CNAME testdenied.example.nil" "testdenied" || ret=1
n=$((n+1))
@@ -130,17 +130,19 @@ n=$((n+1))
n=$((n + 1))
@@ -130,17 +130,19 @@ n=$((n + 1))
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
status=$((status + ret))
-echo_i "testing external policy with SIG(0) key ($n)"
+echo_i "testing external policy with unsupported SIG(0) key ($n)"
ret=0
-$NSUPDATE -k ns1/Kkey.example.nil.*.private <<END > /dev/null 2>&1 || ret=1
-$NSUPDATE -k ns1/Kkey.example.nil.*.private <<END >/dev/null 2>&1 || ret=1
+$NSUPDATE -d -k ns1/Kkey.example.nil.*.private <<END >nsupdate.out${n} 2>&1 || true
+debug
server 10.53.0.1 ${PORT}
@ -69,28 +69,28 @@ index 632bb87..7977e49 100644
update add fred.example.nil 120 cname foo.bar.
send
END
output=`$DIG $DIGOPTS +short cname fred.example.nil.`
output=$($DIG $DIGOPTS +short cname fred.example.nil.)
-[ -n "$output" ] || ret=1
-[ $ret -eq 0 ] || echo_i "failed"
+# update must have failed - SIG(0) signer is not supported
+[ -n "$output" ] && ret=1
+grep -F "signer=key.example.nil" authsock.log >/dev/null && ret=1
n=$((n+1))
n=$((n + 1))
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
status=$((status + ret))
diff --git a/bin/tests/system/upforwd/tests.sh b/bin/tests/system/upforwd/tests.sh
index 20fc46f..c8fd54b 100644
index 063e28d..0947166 100644
--- a/bin/tests/system/upforwd/tests.sh
+++ b/bin/tests/system/upforwd/tests.sh
@@ -224,19 +224,22 @@ fi
@@ -262,19 +262,22 @@ if $FEATURETEST --enable-dnstap; then
fi
if test -f keyname
then
- echo_i "checking update forwarding to with sig0 ($n)"
+ echo_i "checking update forwarding to with sig0 (expected to fail) ($n)"
ret=0
keyname=`cat keyname`
- $NSUPDATE -k $keyname.private -- - <<EOF
if test -f keyname; then
- echo_i "checking update forwarding to with sig0 ($n)"
+ echo_i "checking update forwarding to with sig0 (expected to fail) ($n)"
ret=0
keyname=$(cat keyname)
- $NSUPDATE -k $keyname.private -- - <<EOF
- local 10.53.0.1
- server 10.53.0.3 ${PORT}
- zone example2
@ -108,34 +108,34 @@ index 20fc46f..c8fd54b 100644
+ send
EOF
+ } >nsupdate.out.$n 2>&1 && ret=1
$DIG -p ${PORT} unsigned.example2 A @10.53.0.1 > dig.out.ns1.test$n
- grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1
+ grep "status: NOERROR" dig.out.ns1.test$n >/dev/null && ret=1
if [ $ret != 0 ] ; then echo_i "failed"; fi
status=`expr $status + $ret`
n=`expr $n + 1`
$DIG -p ${PORT} unsigned.example2 A @10.53.0.1 >dig.out.ns1.test$n || ret=1
- grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1
+ grep "status: NOERROR" dig.out.ns1.test$n >/dev/null && ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$(expr $status + $ret)
n=$(expr $n + 1)
diff --git a/doc/arm/general.rst b/doc/arm/general.rst
index 225576b..0766dfe 100644
index d7b7c20..59f9e6b 100644
--- a/doc/arm/general.rst
+++ b/doc/arm/general.rst
@@ -534,10 +534,8 @@ than a non-authoritative response. This is considered a feature.
[2] CLASS ANY queries are not supported. This is considered a
feature.
@@ -367,10 +367,8 @@ Notes
.. [#rfc1035_2] CLASS ANY queries are not supported. This is considered a
feature.
-[3] When receiving a query signed with a SIG(0), the server is
-only able to verify the signature if it has the key in its local
-authoritative data; it cannot do recursion or validation to
-retrieve unknown keys.
+[3] Support for SIG(0) message verification was removed
+as part of the mitigation of CVE-2024-1975.
-.. [#rfc2931] When receiving a query signed with a SIG(0), the server is
- only able to verify the signature if it has the key in its local
- authoritative data; it cannot do recursion or validation to
- retrieve unknown keys.
+.. [#rfc2931] Support for SIG(0) message verification was removed
+ as part of the mitigation of CVE-2024-1975.
[4] Compliance is with loading and serving of A6 records only. A6 records were moved
to the experimental category by :rfc:`3363`.
.. [#rfc2874] Compliance is with loading and serving of A6 records only.
A6 records were moved to the experimental category by :rfc:`3363`.
diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst
index d4ee9d2..ad7ff27 100644
index ecc84d4..f982e0a 100644
--- a/doc/arm/reference.rst
+++ b/doc/arm/reference.rst
@@ -5789,7 +5789,7 @@ The ``update-policy`` clause allows more fine-grained control over which
@@ -5900,7 +5900,7 @@ The ``update-policy`` clause allows more fine-grained control over which
updates are allowed. It specifies a set of rules, in which each rule
either grants or denies permission for one or more names in the zone to
be updated by one or more identities. Identity is determined by the key
@ -144,7 +144,7 @@ index d4ee9d2..ad7ff27 100644
cases, ``update-policy`` rules only apply to key-based identities. There
is no way to specify update permissions based on the client source address.
@@ -5846,7 +5846,7 @@ field), and the type of the record to be updated matches the ``types``
@@ -5957,7 +5957,7 @@ field), and the type of the record to be updated matches the ``types``
field. Details for each rule type are described below.
The ``identity`` field must be set to a fully qualified domain name. In
@ -154,10 +154,10 @@ index d4ee9d2..ad7ff27 100644
wildcard, it is subject to DNS wildcard expansion, and the rule may
apply to multiple identities. When a TKEY exchange has been used to
diff --git a/doc/arm/security.rst b/doc/arm/security.rst
index f7c8bd3..e3abfd1 100644
index 817ebd0..92b1668 100644
--- a/doc/arm/security.rst
+++ b/doc/arm/security.rst
@@ -32,7 +32,7 @@ Limiting access to the server by outside parties can help prevent
@@ -83,7 +83,7 @@ Limiting access to the server by outside parties can help prevent
spoofing and denial of service (DoS) attacks against the server.
ACLs match clients on the basis of up to three characteristics: 1) The
@ -166,7 +166,7 @@ index f7c8bd3..e3abfd1 100644
request, if any; and 3) an address prefix encoded in an EDNS
Client-Subnet option, if any.
@@ -73,7 +73,7 @@ and no queries at all from the networks specified in ``bogusnets``.
@@ -124,7 +124,7 @@ and no queries at all from the networks specified in ``bogusnets``.
In addition to network addresses and prefixes, which are matched against
the source address of the DNS request, ACLs may include ``key``
@ -176,10 +176,10 @@ index f7c8bd3..e3abfd1 100644
When BIND 9 is built with GeoIP support, ACLs can also be used for
geographic access restrictions. This is done by specifying an ACL
diff --git a/lib/dns/message.c b/lib/dns/message.c
index 1993b2e..04315bc 100644
index 22aa552..12331ab 100644
--- a/lib/dns/message.c
+++ b/lib/dns/message.c
@@ -3287,109 +3287,24 @@ dns_message_dumpsig(dns_message_t *msg, char *txt1) {
@@ -3301,111 +3301,24 @@ dns_message_dumpsig(dns_message_t *msg, char *txt1) {
isc_result_t
dns_message_checksig(dns_message_t *msg, dns_view_t *view) {
@ -229,14 +229,15 @@ index 1993b2e..04315bc 100644
- return (ISC_R_UNEXPECTEDEND);
- }
-
- result = dns_rdata_tostruct(&rdata, &sig, msg->mctx);
- result = dns_rdata_tostruct(&rdata, &sig, NULL);
- if (result != ISC_R_SUCCESS) {
- return (result);
- }
-
- dns_rdataset_init(&keyset);
- if (view == NULL) {
- return (DNS_R_KEYUNAUTHORIZED);
- result = DNS_R_KEYUNAUTHORIZED;
- goto freesig;
- }
- result = dns_view_simplefind(view, &sig.signer,
- dns_rdatatype_key /* SIG(0) */, 0,
@ -254,7 +255,8 @@ index 1993b2e..04315bc 100644
- result = dns_rdataset_first(&keyset);
- INSIST(result == ISC_R_SUCCESS);
- for (; result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&keyset)) {
- result = dns_rdataset_next(&keyset))
- {
- dst_key_t *key = NULL;
-
- dns_rdata_reset(&rdata);
@ -296,10 +298,10 @@ index 1993b2e..04315bc 100644
}
diff --git a/lib/ns/client.c b/lib/ns/client.c
index 967e21b..87b8a18 100644
index d4ce000..2679a5e 100644
--- a/lib/ns/client.c
+++ b/lib/ns/client.c
@@ -2060,6 +2060,13 @@ ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
@@ -2041,6 +2041,13 @@ ns__client_request(isc_nmhandle_t *handle, isc_result_t eresult,
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
"request is signed by a nonauthoritative key");
@ -314,5 +316,5 @@ index 967e21b..87b8a18 100644
char tsigrcode[64];
isc_buffer_t b;
--
2.45.2
2.51.1

View File

@ -1,4 +1,4 @@
From 39a43add7ad19fc2d83950a9af0c4f8cf580588b Mon Sep 17 00:00:00 2001
From 3f033e9822a08c02cb146c4e996ed6edfbea4636 Mon Sep 17 00:00:00 2001
From: Evan Hunt <each@isc.org>
Date: Mon, 29 Sep 2025 21:46:59 -0700
Subject: [PATCH] Tighten restrictions on caching NS RRsets in authority
@ -34,28 +34,30 @@ ans3 and ans4 servers in the chain system test.
(cherry picked from commit 2e40705c06831988106335ed77db3cf924d431f6)
(cherry picked from commit 33a7db1fe964e55b76b4ac003ecc56cc67028bd9)
---
bin/tests/system/chain/ans3/ans.pl | 129 -----------------
bin/tests/system/chain/ans3/ans.pl | 143 -------------------
bin/tests/system/chain/ans3/ans.py | 217 +++++++++++++++++++++++++++++
bin/tests/system/chain/ans4/ans.py | 58 ++++++--
lib/dns/include/dns/message.h | 10 ++
bin/tests/system/chain/ans4/ans.py | 57 ++++++--
lib/dns/include/dns/message.h | 8 ++
lib/dns/message.c | 12 ++
lib/dns/resolver.c | 114 ++++++++++++---
6 files changed, 380 insertions(+), 160 deletions(-)
lib/dns/resolver.c | 112 ++++++++++++---
6 files changed, 376 insertions(+), 173 deletions(-)
delete mode 100644 bin/tests/system/chain/ans3/ans.pl
create mode 100644 bin/tests/system/chain/ans3/ans.py
diff --git a/bin/tests/system/chain/ans3/ans.pl b/bin/tests/system/chain/ans3/ans.pl
deleted file mode 100644
index 31d22d807b..0000000000
index e42240be63..0000000000
--- a/bin/tests/system/chain/ans3/ans.pl
+++ /dev/null
@@ -1,129 +0,0 @@
@@ -1,143 +0,0 @@
-#!/usr/bin/env perl
-#
-
-# 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
-# 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
@ -72,9 +74,14 @@ index 31d22d807b..0000000000
-print $pidf "$$\n" or die "cannot write pid file: $!";
-$pidf->close or die "cannot close pid file: $!";
-sub rmpid { unlink "ans.pid"; exit 1; };
-sub term { };
-
-$SIG{INT} = \&rmpid;
-$SIG{TERM} = \&rmpid;
-if ($Net::DNS::VERSION > 1.41) {
- $SIG{TERM} = \&term;
-} else {
- $SIG{TERM} = \&rmpid;
-}
-
-my $localaddr = "10.53.0.3";
-
@ -178,7 +185,14 @@ index 31d22d807b..0000000000
- Verbose => $verbose,
-);
-
-$ns->main_loop;
-if ($Net::DNS::VERSION >= 1.42) {
- $ns->start_server();
- select(undef, undef, undef, undef);
- $ns->stop_server();
- unlink "ans.pid";
-} else {
- $ns->main_loop;
-}
diff --git a/bin/tests/system/chain/ans3/ans.py b/bin/tests/system/chain/ans3/ans.py
new file mode 100644
index 0000000000..0a031c1145
@ -403,12 +417,12 @@ index 0000000000..0a031c1145
+ if not running:
+ break
diff --git a/bin/tests/system/chain/ans4/ans.py b/bin/tests/system/chain/ans4/ans.py
index 45d650417f..e4fc15a280 100755
index 839067faa5..66f0193cac 100755
--- a/bin/tests/system/chain/ans4/ans.py
+++ b/bin/tests/system/chain/ans4/ans.py
@@ -276,16 +276,30 @@ except: port=5300
try: ctrlport=int(os.environ['EXTRAPORT1'])
except: ctrlport=5300
@@ -316,16 +316,30 @@ try:
except:
ctrlport = 5300
-query4_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-query4_socket.bind((ip4, port))
@ -442,8 +456,8 @@ index 45d650417f..e4fc15a280 100755
havev6 = False
except:
havev6 = False
@@ -310,9 +324,9 @@ print ("Control channel on %s port %d" % (ip4, ctrlport))
print ("Ctrl-c to quit")
@@ -350,9 +364,9 @@ print("Control channel on %s port %d" % (ip4, ctrlport))
print("Ctrl-c to quit")
if havev6:
- input = [query4_socket, query6_socket, ctrl_socket]
@ -454,13 +468,12 @@ index 45d650417f..e4fc15a280 100755
while running:
try:
@@ -335,13 +349,37 @@ while running:
@@ -375,12 +389,37 @@ while running:
break
ctl_channel(msg)
conn.close()
- if s == query4_socket or s == query6_socket:
- print ("Query received on %s" %
- (ip4 if s == query4_socket else ip6))
- print("Query received on %s" % (ip4 if s == query4_socket else ip6))
+ elif s == query4_udp or s == query6_udp:
+ print("Query received on %s" % (ip4 if s == query4_udp else ip6))
# Handle incoming queries
@ -496,19 +509,10 @@ index 45d650417f..e4fc15a280 100755
if not running:
break
diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h
index 68c13ee6c5..53c96a5827 100644
index ea45742439..f564e1e5ef 100644
--- a/lib/dns/include/dns/message.h
+++ b/lib/dns/include/dns/message.h
@@ -1,6 +1,8 @@
/*
* 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/.
@@ -233,6 +235,7 @@ struct dns_message {
@@ -235,6 +235,7 @@ struct dns_message {
unsigned int cc_bad : 1;
unsigned int tkey : 1;
unsigned int rdclass_set : 1;
@ -516,7 +520,7 @@ index 68c13ee6c5..53c96a5827 100644
unsigned int opt_reserved;
unsigned int sig_reserved;
@@ -1449,4 +1452,11 @@ dns_message_clonebuffer(dns_message_t *msg);
@@ -1451,4 +1452,11 @@ dns_message_clonebuffer(dns_message_t *msg);
* \li msg be a valid message.
*/
@ -529,10 +533,10 @@ index 68c13ee6c5..53c96a5827 100644
+
ISC_LANG_ENDDECLS
diff --git a/lib/dns/message.c b/lib/dns/message.c
index 04315bc6d0..aa434a75f1 100644
index 22aa552f3f..c3f86fdbe0 100644
--- a/lib/dns/message.c
+++ b/lib/dns/message.c
@@ -438,6 +438,7 @@ msginit(dns_message_t *m) {
@@ -442,6 +442,7 @@ msginit(dns_message_t *m) {
m->cc_bad = 0;
m->tkey = 0;
m->rdclass_set = 0;
@ -540,7 +544,7 @@ index 04315bc6d0..aa434a75f1 100644
m->querytsig = NULL;
m->indent.string = "\t";
m->indent.count = 0;
@@ -1717,6 +1718,11 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
@@ -1727,6 +1728,11 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
*/
msg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS;
free_name = false;
@ -552,7 +556,7 @@ index 04315bc6d0..aa434a75f1 100644
}
rdataset = NULL;
@@ -4750,3 +4756,9 @@ dns_message_clonebuffer(dns_message_t *msg) {
@@ -4857,3 +4863,9 @@ dns_message_clonebuffer(dns_message_t *msg) {
msg->free_query = 1;
}
}
@ -563,10 +567,10 @@ index 04315bc6d0..aa434a75f1 100644
+ return msg->has_dname;
+}
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index ad0a1b8102..5973bc1d55 100644
index 0952624689..cf6a55163a 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -751,6 +751,7 @@ typedef struct respctx {
@@ -758,6 +758,7 @@ typedef struct respctx {
bool get_nameservers; /* get a new NS rrset at
* zone cut? */
bool resend; /* resend this query? */
@ -574,28 +578,26 @@ index ad0a1b8102..5973bc1d55 100644
bool nextitem; /* invalid response; keep
* listening for the correct one */
bool truncated; /* response was truncated */
@@ -7155,7 +7156,8 @@ mark_related(dns_name_t *name, dns_rdataset_t *rdataset, bool external,
@@ -7154,7 +7155,8 @@ mark_related(dns_name_t *name, dns_rdataset_t *rdataset, bool external,
* locally served zone.
*/
static inline bool
static bool
-name_external(const dns_name_t *name, dns_rdatatype_t type, fetchctx_t *fctx) {
+name_external(const dns_name_t *name, dns_rdatatype_t type, respctx_t *rctx) {
+ fetchctx_t *fctx = rctx->fctx;
isc_result_t result;
dns_forwarders_t *forwarders = NULL;
dns_fixedname_t fixed, zfixed;
@@ -7167,7 +7169,9 @@ name_external(const dns_name_t *name, dns_rdatatype_t type, fetchctx_t *fctx) {
unsigned int labels;
@@ -7167,7 +7169,7 @@ name_external(const dns_name_t *name, dns_rdatatype_t type, fetchctx_t *fctx) {
dns_namereln_t rel;
- apex = ISFORWARDER(fctx->addrinfo) ? fctx->fwdname : &fctx->domain;
+ apex = (/*ISDUALSTACK(fctx->addrinfo) || */!ISFORWARDER(fctx->addrinfo))
apex = (ISDUALSTACK(fctx->addrinfo) || !ISFORWARDER(fctx->addrinfo))
- ? &fctx->domain
+ ? rctx->ns_name != NULL ? rctx->ns_name : &fctx->domain
+ : fctx->fwdname;
: fctx->fwdname;
/*
* The name is outside the queried namespace.
@@ -7275,7 +7279,7 @@ check_section(void *arg, const dns_name_t *addname, dns_rdatatype_t type,
@@ -7276,7 +7278,7 @@ check_section(void *arg, const dns_name_t *addname, dns_rdatatype_t type,
result = dns_message_findname(rctx->query->rmessage, section, addname,
dns_rdatatype_any, 0, &name, NULL);
if (result == ISC_R_SUCCESS) {
@ -604,7 +606,7 @@ index ad0a1b8102..5973bc1d55 100644
if (type == dns_rdatatype_a) {
for (rdataset = ISC_LIST_HEAD(name->list);
rdataset != NULL;
@@ -7884,6 +7888,47 @@ betterreferral(respctx_t *rctx) {
@@ -7888,6 +7890,47 @@ betterreferral(respctx_t *rctx) {
return (false);
}
@ -652,7 +654,7 @@ index ad0a1b8102..5973bc1d55 100644
/*
* resquery_response():
* Handles responses received in response to iterative queries sent by
@@ -8042,6 +8087,11 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
@@ -8046,6 +8089,11 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
break;
}
@ -664,7 +666,7 @@ index ad0a1b8102..5973bc1d55 100644
/*
* If the message is signed, check the signature. If not, this
* returns success anyway.
@@ -8058,9 +8108,16 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
@@ -8063,9 +8111,16 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
}
/*
@ -683,7 +685,7 @@ index ad0a1b8102..5973bc1d55 100644
/*
* INSIST() that the message comes from the place we sent it to,
* since the dispatch code should ensure this.
@@ -8074,10 +8131,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
@@ -8079,10 +8134,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
* This may be a misconfigured anycast server or an attempt to send
* a spoofed response. Skip if we have a valid tsig.
*/
@ -695,7 +697,7 @@ index ad0a1b8102..5973bc1d55 100644
unsigned char cookie[COOKIE_BUFFER_SIZE];
if (dns_adb_getcookie(fctx->adb, query->addrinfo, cookie,
sizeof(cookie)) > CLIENT_COOKIE_SIZE)
@@ -8103,6 +8157,17 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
@@ -8108,6 +8160,17 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
*/
}
@ -713,7 +715,7 @@ index ad0a1b8102..5973bc1d55 100644
rctx_edns(&rctx);
/*
@@ -8830,8 +8895,8 @@ rctx_answer_positive(respctx_t *rctx) {
@@ -8836,8 +8899,8 @@ rctx_answer_positive(respctx_t *rctx) {
}
/*
@ -724,7 +726,7 @@ index ad0a1b8102..5973bc1d55 100644
*/
rctx_authority_positive(rctx);
@@ -8902,7 +8967,7 @@ rctx_answer_scan(respctx_t *rctx) {
@@ -8909,7 +8972,7 @@ rctx_answer_scan(respctx_t *rctx) {
/*
* Don't accept DNAME from parent namespace.
*/
@ -733,7 +735,7 @@ index ad0a1b8102..5973bc1d55 100644
continue;
}
@@ -9200,14 +9265,14 @@ rctx_answer_dname(respctx_t *rctx) {
@@ -9208,14 +9271,14 @@ rctx_answer_dname(respctx_t *rctx) {
/*
* rctx_authority_positive():
@ -756,7 +758,7 @@ index ad0a1b8102..5973bc1d55 100644
*/
static void
rctx_authority_positive(respctx_t *rctx) {
@@ -9215,6 +9280,11 @@ rctx_authority_positive(respctx_t *rctx) {
@@ -9223,6 +9286,11 @@ rctx_authority_positive(respctx_t *rctx) {
bool done = false;
isc_result_t result;
@ -768,7 +770,7 @@ index ad0a1b8102..5973bc1d55 100644
result = dns_message_firstname(rctx->query->rmessage,
DNS_SECTION_AUTHORITY);
while (!done && result == ISC_R_SUCCESS) {
@@ -9223,7 +9293,9 @@ rctx_authority_positive(respctx_t *rctx) {
@@ -9231,7 +9299,9 @@ rctx_authority_positive(respctx_t *rctx) {
dns_message_currentname(rctx->query->rmessage,
DNS_SECTION_AUTHORITY, &name);
@ -780,5 +782,5 @@ index ad0a1b8102..5973bc1d55 100644
/*
--
2.51.1
2.53.0

View File

@ -0,0 +1,250 @@
From 16c75b53b9f76011ae64378046f66dc0c2ad7526 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 0e636fb6c21a165b1bab67636d6f380f20e8b012)
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 e307735073b207a2e1635703511df55f6583d18e)
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 5828874d13870bce651eb84fdfc95d581f66927c)
---
lib/dns/include/dns/types.h | 1 +
lib/dns/validator.c | 89 ++++++++++++++++++++++++++++---------
2 files changed, 70 insertions(+), 20 deletions(-)
diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h
index 8781875651..8878ac7bd9 100644
--- a/lib/dns/include/dns/types.h
+++ b/lib/dns/include/dns/types.h
@@ -354,6 +354,7 @@ enum {
((x) == dns_trust_additional || (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 e416cc9b5c..d571539a7d 100644
--- a/lib/dns/validator.c
+++ b/lib/dns/validator.c
@@ -249,12 +249,25 @@ exit_check(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;
dns_name_t nsec3name;
@@ -282,7 +295,7 @@ isdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
goto trynsec3;
}
if (result != ISC_R_SUCCESS) {
- return (false);
+ return (ISC_R_NOTFOUND);
}
}
@@ -296,7 +309,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:
/*
@@ -332,6 +345,18 @@ trynsec3:
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);
@@ -343,7 +368,7 @@ trynsec3:
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;
@@ -359,12 +384,12 @@ trynsec3:
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);
}
/*%
@@ -576,8 +601,10 @@ fetch_callback_ds(isc_task_t *task, isc_event_t *event) {
} else if (eresult == DNS_R_SERVFAIL) {
goto unexpected;
} else if (eresult != DNS_R_CNAME &&
- isdelegation(dns_fixedname_name(&devent->foundname),
- &val->frdataset, eresult))
+ isdelegation(val,
+ dns_fixedname_name(&devent->foundname),
+ &val->frdataset, eresult,
+ "fetch_callback_ds") == ISC_R_SUCCESS)
{
/*
* Failed to find a DS while trying to prove
@@ -736,10 +763,13 @@ validator_callback_ds(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,
+ "validator_callback_ds") == ISC_R_SUCCESS)
{
result = markanswer(val, "validator_callback_ds",
"no DS and this is a delegation");
@@ -1433,6 +1463,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:
@@ -2355,6 +2392,17 @@ validate_neg_rrset(dns_validator_t *val, dns_name_t *name,
}
}
+ 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 validator_callback_nsec().
+ */
+ return DNS_R_CONTINUE;
+ }
+
val->currentset = rdataset;
result = create_validator(val, name, rdataset->type, rdataset,
sigrdataset, validator_callback_nsec,
@@ -2464,11 +2512,9 @@ validate_ncache(dns_validator_t *val, bool resume) {
}
result = validate_neg_rrset(val, name, rdataset, sigrdataset);
- if (result == DNS_R_CONTINUE) {
- continue;
+ if (result != DNS_R_CONTINUE) {
+ return (result);
}
-
- return (result);
}
if (result == ISC_R_NOMORE) {
result = ISC_R_SUCCESS;
@@ -2517,7 +2563,8 @@ validate_nx(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)", NULL);
return (ISC_R_SUCCESS);
}
@@ -2553,7 +2600,7 @@ validate_nx(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)", NULL);
return (ISC_R_SUCCESS);
}
@@ -2770,7 +2817,9 @@ seek_ds(dns_validator_t *val, isc_result_t *resp) {
return (ISC_R_COMPLETE);
}
- if (isdelegation(tname, &val->frdataset, result)) {
+ result = isdelegation(val, tname, &val->frdataset, result,
+ "seek_ds");
+ if (result == ISC_R_SUCCESS) {
*resp = markanswer(val, "proveunsecure (4)",
"this is a delegation");
return (ISC_R_COMPLETE);
--
2.53.0

View File

@ -0,0 +1,376 @@
From c824f5e341094edc653f64e730a7471d31f9cc14 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Wed, 18 Mar 2026 00:10:35 +0100
Subject: [PATCH] Fix GSS-API context leak in TKEY negotiation
Reject multi-round GSS-API negotiation (GSS_S_CONTINUE_NEEDED) in
dst_gssapi_acceptctx(). Each call to gss_accept_sec_context()
allocates a context inside the GSS library; without this fix, the
context handle was passed back to process_gsstkey() which did not
store it persistently, leaking it on every incomplete negotiation.
An unauthenticated attacker could exhaust server memory by sending
repeated TKEY queries with GSSAPI tokens, each leaking one GSS
context. The leaked memory is allocated by the GSS library via
malloc(), bypassing BIND's memory accounting.
In practice, Kerberos/SPNEGO (the only mechanism used with BIND)
completes in a single round, so rejecting continuation does not
affect real-world deployments. See RFC 3645 Section 4.1.3.
(cherry picked from commit 3883058bf284de2889e4e3676767e58ad91a0ae3)
(cherry picked from commit 58c646c4b95efcda759cf194a534290eef38135e)
Fix output token and GSS context leaks in TKEY/GSS-API error paths
In dst_gssapi_acceptctx(), rename outtoken to outtokenp (matching BIND
convention for output pointer parameters) and free the allocated output
token buffer on error in the cleanup path.
In process_gsstkey(), route the empty-principal error path through
cleanup via CLEANUP() instead of returning early, so that the output
token, GSS context, and TSIG key are all freed consistently by the
existing cleanup block.
(cherry picked from commit f2240d2d06a1a68b622bd6b00a52c6fe4274426d)
(cherry picked from commit 7eef47ce676672f65b4988b1b5c086c4f30a9b70)
---
lib/dns/gssapictx.c | 124 +++++++++++++++++++----------------
lib/dns/include/dst/gssapi.h | 17 ++---
lib/dns/tkey.c | 52 +++++++--------
3 files changed, 98 insertions(+), 95 deletions(-)
diff --git a/lib/dns/gssapictx.c b/lib/dns/gssapictx.c
index b0c62497a5..2a78169869 100644
--- a/lib/dns/gssapictx.c
+++ b/lib/dns/gssapictx.c
@@ -606,7 +606,14 @@ dst_gssapi_initctx(const dns_name_t *name, isc_buffer_t *intoken,
GSS_SPNEGO_MECHANISM, flags, 0, NULL, gintokenp, NULL,
&gouttoken, &ret_flags, NULL);
- if (gret != GSS_S_COMPLETE && gret != GSS_S_CONTINUE_NEEDED) {
+ switch (gret) {
+ case GSS_S_COMPLETE:
+ result = ISC_R_SUCCESS;
+ break;
+ case GSS_S_CONTINUE_NEEDED:
+ result = DNS_R_CONTINUE;
+ break;
+ default:
gss_err_message(mctx, gret, minor, err_message);
if (err_message != NULL && *err_message != NULL) {
gss_log(3, "Failure initiating security context: %s",
@@ -632,12 +639,6 @@ dst_gssapi_initctx(const dns_name_t *name, isc_buffer_t *intoken,
RETERR(isc_buffer_copyregion(outtoken, &r));
}
- if (gret == GSS_S_COMPLETE) {
- result = ISC_R_SUCCESS;
- } else {
- result = DNS_R_CONTINUE;
- }
-
out:
if (gouttoken.length != 0U) {
(void)gss_release_buffer(&minor, &gouttoken);
@@ -648,7 +649,7 @@ out:
isc_result_t
dst_gssapi_acceptctx(dns_gss_cred_id_t cred, const char *gssapi_keytab,
- isc_region_t *intoken, isc_buffer_t **outtoken,
+ isc_region_t *intoken, isc_buffer_t **outtokenp,
dns_gss_ctx_id_t *ctxout, dns_name_t *principal,
isc_mem_t *mctx) {
isc_region_t r;
@@ -661,16 +662,11 @@ dst_gssapi_acceptctx(dns_gss_cred_id_t cred, const char *gssapi_keytab,
isc_result_t result;
char buf[1024];
- REQUIRE(outtoken != NULL && *outtoken == NULL);
+ REQUIRE(outtokenp != NULL && *outtokenp == NULL);
+ REQUIRE(*ctxout == NULL);
REGION_TO_GBUFFER(*intoken, gintoken);
- if (*ctxout == NULL) {
- context = GSS_C_NO_CONTEXT;
- } else {
- context = *ctxout;
- }
-
if (gssapi_keytab != NULL) {
#if defined(ISC_PLATFORM_GSSAPI_KRB5_HEADER) || defined(WIN32)
gret = gsskrb5_register_acceptor_identity(gssapi_keytab);
@@ -715,8 +711,15 @@ dst_gssapi_acceptctx(dns_gss_cred_id_t cred, const char *gssapi_keytab,
switch (gret) {
case GSS_S_COMPLETE:
- case GSS_S_CONTINUE_NEEDED:
break;
+ /*
+ * RFC 3645 4.1.3: we don't handle GSS_S_CONTINUE_NEEDED
+ * Multi-round GSS-API negotiation is not supported.
+ */
+ case GSS_S_CONTINUE_NEEDED:
+ gss_log(3, "multi-round GSS-API negotiation not supported");
+ (void)gss_delete_sec_context(&minor, &context, NULL);
+ /* FALLTHROUGH */
case GSS_S_DEFECTIVE_TOKEN:
case GSS_S_DEFECTIVE_CREDENTIAL:
case GSS_S_BAD_SIG:
@@ -729,7 +732,7 @@ dst_gssapi_acceptctx(dns_gss_cred_id_t cred, const char *gssapi_keytab,
case GSS_S_BAD_MECH:
case GSS_S_FAILURE:
result = DNS_R_INVALIDTKEY;
- /* fall through */
+ /* FALLTHROUGH */
default:
gss_log(3, "failed gss_accept_sec_context: %s",
gss_error_tostring(gret, minor, buf, sizeof(buf)));
@@ -740,59 +743,70 @@ dst_gssapi_acceptctx(dns_gss_cred_id_t cred, const char *gssapi_keytab,
}
if (gouttoken.length > 0U) {
- isc_buffer_allocate(mctx, outtoken,
+ isc_buffer_allocate(mctx, outtokenp,
(unsigned int)gouttoken.length);
GBUFFER_TO_REGION(gouttoken, r);
- RETERR(isc_buffer_copyregion(*outtoken, &r));
+ result = isc_buffer_copyregion(*outtokenp, &r);
+ if (result != ISC_R_SUCCESS) {
+ goto out;
+ }
(void)gss_release_buffer(&minor, &gouttoken);
}
- if (gret == GSS_S_COMPLETE) {
- gret = gss_display_name(&minor, gname, &gnamebuf, NULL);
- if (gret != GSS_S_COMPLETE) {
- gss_log(3, "failed gss_display_name: %s",
- gss_error_tostring(gret, minor, buf,
- sizeof(buf)));
- RETERR(ISC_R_FAILURE);
- }
+ INSIST(gret == GSS_S_COMPLETE);
- /*
- * Compensate for a bug in Solaris8's implementation
- * of gss_display_name(). Should be harmless in any
- * case, since principal names really should not
- * contain null characters.
- */
- if (gnamebuf.length > 0U &&
- ((char *)gnamebuf.value)[gnamebuf.length - 1] == '\0')
- {
- gnamebuf.length--;
- }
+ gret = gss_display_name(&minor, gname, &gnamebuf, NULL);
+ if (gret != GSS_S_COMPLETE) {
+ gss_log(3, "failed gss_display_name: %s",
+ gss_error_tostring(gret, minor, buf, sizeof(buf)));
+ result = ISC_R_FAILURE;
+ goto out;
+ }
- gss_log(3, "gss-api source name (accept) is %.*s",
- (int)gnamebuf.length, (char *)gnamebuf.value);
+ /*
+ * Compensate for a bug in Solaris8's implementation
+ * of gss_display_name(). Should be harmless in any
+ * case, since principal names really should not
+ * contain null characters.
+ */
+ if (gnamebuf.length > 0U &&
+ ((char *)gnamebuf.value)[gnamebuf.length - 1] == '\0')
+ {
+ gnamebuf.length--;
+ }
- GBUFFER_TO_REGION(gnamebuf, r);
- isc_buffer_init(&namebuf, r.base, r.length);
- isc_buffer_add(&namebuf, r.length);
+ gss_log(3, "gss-api source name (accept) is %.*s", (int)gnamebuf.length,
+ (char *)gnamebuf.value);
- RETERR(dns_name_fromtext(principal, &namebuf, dns_rootname, 0,
- NULL));
+ GBUFFER_TO_REGION(gnamebuf, r);
+ isc_buffer_init(&namebuf, r.base, r.length);
+ isc_buffer_add(&namebuf, r.length);
- if (gnamebuf.length != 0U) {
- gret = gss_release_buffer(&minor, &gnamebuf);
- if (gret != GSS_S_COMPLETE) {
- gss_log(3, "failed gss_release_buffer: %s",
- gss_error_tostring(gret, minor, buf,
- sizeof(buf)));
- }
- }
- } else {
- result = DNS_R_CONTINUE;
+ result = dns_name_fromtext(principal, &namebuf, dns_rootname, 0, NULL);
+ if (result != ISC_R_SUCCESS) {
+ goto out;
}
*ctxout = context;
out:
+ if (result != ISC_R_SUCCESS && *outtokenp != NULL) {
+ isc_buffer_free(outtokenp);
+ }
+
+ if (result != ISC_R_SUCCESS && context != GSS_C_NO_CONTEXT) {
+ (void)gss_delete_sec_context(&minor, &context, NULL);
+ }
+
+ if (gnamebuf.length != 0U) {
+ gret = gss_release_buffer(&minor, &gnamebuf);
+ if (gret != GSS_S_COMPLETE) {
+ gss_log(3, "failed gss_release_buffer: %s",
+ gss_error_tostring(gret, minor, buf,
+ sizeof(buf)));
+ }
+ }
+
if (gname != NULL) {
gret = gss_release_name(&minor, &gname);
if (gret != GSS_S_COMPLETE) {
diff --git a/lib/dns/include/dst/gssapi.h b/lib/dns/include/dst/gssapi.h
index 10f8467aef..92dad43440 100644
--- a/lib/dns/include/dst/gssapi.h
+++ b/lib/dns/include/dst/gssapi.h
@@ -113,20 +113,17 @@ dst_gssapi_acceptctx(dns_gss_cred_id_t cred, const char *gssapi_keytab,
* generated by gss_accept_sec_context() to be sent to the
* initiator
* 'context' is a valid pointer to receive the generated context handle.
- * On the initial call, it should be a pointer to NULL, which
- * will be allocated as a dns_gss_ctx_id_t. Subsequent calls
- * should pass in the handle generated on the first call.
- * Call dst_gssapi_releasecred to delete the context and free
- * the memory.
*
* Requires:
- * 'outtoken' to != NULL && *outtoken == NULL.
+ * 'outtoken' != NULL && *outtoken == NULL.
+ * 'context' != NULL && *context == NULL.
*
* Returns:
- * ISC_R_SUCCESS msg was successfully updated to include the
- * query to be sent
- * DNS_R_CONTINUE transaction still in progress
- * other an error occurred while building the message
+ * ISC_R_SUCCESS msg was successfully updated to include
+ * the query to be sent
+ * DNS_R_INVALIDTKEY an error occurred while accepting the
+ * context
+ * ISC_R_FAILURE other error occurred
*/
isc_result_t
diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c
index b4f12a0831..e7800113d9 100644
--- a/lib/dns/tkey.c
+++ b/lib/dns/tkey.c
@@ -529,19 +529,9 @@ process_gsstkey(dns_message_t *msg, dns_name_t *name, dns_rdata_tkey_t *tkeyin,
return (ISC_R_SUCCESS);
}
- /*
- * XXXDCL need to check for key expiry per 4.1.1
- * XXXDCL need a way to check fully established, perhaps w/key_flags
- */
-
intoken.base = tkeyin->key;
intoken.length = tkeyin->keylen;
- result = dns_tsigkey_find(&tsigkey, name, &tkeyin->algorithm, ring);
- if (result == ISC_R_SUCCESS) {
- gss_ctx = dst_key_getgssctx(tsigkey->key);
- }
-
principal = dns_fixedname_initname(&fixed);
/*
@@ -550,28 +540,27 @@ process_gsstkey(dns_message_t *msg, dns_name_t *name, dns_rdata_tkey_t *tkeyin,
result = dst_gssapi_acceptctx(tctx->gsscred, tctx->gssapi_keytab,
&intoken, &outtoken, &gss_ctx, principal,
tctx->mctx);
- if (result == DNS_R_INVALIDTKEY) {
- if (tsigkey != NULL) {
- dns_tsigkey_detach(&tsigkey);
- }
+ if (result != ISC_R_SUCCESS) {
tkeyout->error = dns_tsigerror_badkey;
- tkey_log("process_gsstkey(): dns_tsigerror_badkey"); /* XXXSRA
- */
- return (ISC_R_SUCCESS);
- }
- if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS) {
+ tkey_log("process_gsstkey(): dns_tsigerror_badkey");
+ result = ISC_R_SUCCESS;
goto failure;
}
+
/*
- * XXXDCL Section 4.1.3: Limit GSS_S_CONTINUE_NEEDED to 10 times.
+ * Multi-round GSS-API negotiation (GSS_S_CONTINUE_NEEDED) is
+ * rejected in dst_gssapi_acceptctx(), so if we reach here the
+ * negotiation is complete and the principal must be set.
*/
isc_stdtime_get(&now);
if (dns_name_countlabels(principal) == 0U) {
- if (tsigkey != NULL) {
- dns_tsigkey_detach(&tsigkey);
- }
+ tkeyout->error = dns_tsigerror_badkey;
+ tkey_log("process_gsstkey(): "
+ "completed context with empty principal");
+ result = ISC_R_SUCCESS;
+ goto failure;
} else if (tsigkey == NULL) {
#ifdef GSSAPI
OM_uint32 gret, minor, lifetime;
@@ -634,6 +623,10 @@ process_gsstkey(dns_message_t *msg, dns_name_t *name, dns_rdata_tkey_t *tkeyin,
return (ISC_R_SUCCESS);
failure:
+ if (dstkey == NULL && gss_ctx != NULL) {
+ dst_gssapi_deletectx(tctx->mctx, &gss_ctx);
+ }
+
if (tsigkey != NULL) {
dns_tsigkey_detach(&tsigkey);
}
@@ -646,10 +639,10 @@ failure:
isc_buffer_free(&outtoken);
}
- tkey_log("process_gsstkey(): %s", isc_result_totext(result)); /* XXXSRA
- */
-
- return (result);
+ if (result != ISC_R_SUCCESS) {
+ tkey_log("process_gsstkey(): %s", isc_result_totext(result));
+ }
+ return result;
}
static isc_result_t
@@ -1558,9 +1551,8 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
NULL));
/*
- * XXXSRA This seems confused. If we got CONTINUE from initctx,
- * the GSS negotiation hasn't completed yet, so we can't sign
- * anything yet.
+ * GSS negotiation is complete (CONTINUE returned earlier).
+ * Create the TSIG key from the established context.
*/
RETERR(dns_tsigkey_createfromkey(
--
2.54.0

View File

@ -0,0 +1,719 @@
From fdadded4959eec655fded3ddfeacec47d2250274 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 | 42 ++++--------
bin/tests/system/checkconf/tests.sh | 14 +++-
.../checkconf/warn-chaos-recursion.conf | 25 ++++++++
bin/tests/system/resolver/tests.sh | 8 ++-
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, 177 insertions(+), 75 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 098e21d0ac..9e33dc6349 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -1932,10 +1932,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,
@@ -4215,6 +4217,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
@@ -4965,34 +4968,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.
*/
@@ -5102,7 +5086,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);
@@ -5201,14 +5186,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 c8f883e38d..34d2aebf24 100644
--- a/bin/tests/system/checkconf/tests.sh
+++ b/bin/tests/system/checkconf/tests.sh
@@ -481,7 +481,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 -ne 0 ]; then
echo_i "failed"
@@ -763,5 +764,16 @@ status=$(expr $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 0000000000..e384533c0a
--- /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 fc05635e31..6e1fdaddfa 100755
--- a/bin/tests/system/resolver/tests.sh
+++ b/bin/tests/system/resolver/tests.sh
@@ -897,10 +897,12 @@ if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((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_with_opts @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=$((status + ret))
diff --git a/bin/tests/system/unknown/tests.sh b/bin/tests/system/unknown/tests.sh
index b14548a039..092ae2d308 100644
--- a/bin/tests/system/unknown/tests.sh
+++ b/bin/tests/system/unknown/tests.sh
@@ -75,8 +75,8 @@ n=$((n + 1))
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"
fi
@@ -87,8 +87,8 @@ n=$((n + 1))
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"
fi
@@ -99,8 +99,8 @@ n=$((n + 1))
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"
fi
diff --git a/lib/bind9/check.c b/lib/bind9/check.c
index ee64543ab8..9935b8a8f3 100644
--- a/lib/bind9/check.c
+++ b/lib/bind9/check.c
@@ -2292,13 +2292,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.
*/
@@ -2878,7 +2882,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 "
@@ -4631,6 +4636,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 6f98feca45..a97239570b 100644
--- a/lib/dns/adb.c
+++ b/lib/dns/adb.c
@@ -926,7 +926,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 22aa552f3f..ba374c4336 100644
--- a/lib/dns/message.c
+++ b/lib/dns/message.c
@@ -1087,6 +1087,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 0952624689..0d7d0735db 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -7367,9 +7367,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 d4ce000be8..b1e1d6c0b9 100644
--- a/lib/ns/client.c
+++ b/lib/ns/client.c
@@ -43,6 +43,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>
@@ -1933,7 +1934,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)
@@ -1954,12 +1957,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;
}
@@ -1998,7 +2038,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;
@@ -2175,6 +2215,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,
@@ -2185,6 +2229,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;
@@ -2276,7 +2324,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) {
@@ -2735,7 +2783,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 4e51cdcb77..2792058099 100644
--- a/lib/ns/update.c
+++ b/lib/ns/update.c
@@ -1294,7 +1294,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
@@ -1438,8 +1441,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;
@@ -1455,7 +1457,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;
}
/*%
@@ -1557,7 +1559,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;
@@ -1565,10 +1566,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,
@@ -1609,13 +1612,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
@@ -2755,9 +2758,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;
@@ -2776,10 +2777,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.
*/
@@ -2800,8 +2800,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 "
@@ -2868,7 +2868,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) {
@@ -2927,10 +2927,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.
*/
@@ -3507,10 +3507,6 @@ common:
dns_db_detach(&db);
}
- if (ssutable != NULL) {
- dns_ssutable_detach(&ssutable);
- }
-
isc_task_detach(&task);
uev->result = result;
if (zone != NULL) {
--
2.55.0

View File

@ -0,0 +1,70 @@
From fb3761d9b1ca804fd6c2acabe42745f9ee79bac0 Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Thu, 18 Jul 2024 19:36:04 +0200
Subject: [PATCH] Do not block start if inline-signing and dyn. updates are not
set
Attempts to modify behaviour done in 9.16.33. It requires explicit
specification of inline-signing yes for any zone, which has specified
dnssec-policy. For primary zones also when allow-update and
update-policy are disabled. Turn it into warning only on RHEL builds,
do not prevent starting of named.
That should roughly emulate error message present on 9.16.23:
'inline-signing;' cannot be set to 'no' if dnssec-policy is also set on
a non-dynamic DNS zone.
But point a link into upstream KB article in any case. This has appeared
only when inline-signing were specified in a zone block. For that case
make it still fatal, but with new message.
https://downloads.isc.org/isc/bind9/9.16.50/doc/arm/html/notes.html#known-issues
Related to upstream commit 30fceec069ae0942749e6aa783f67756e82fcaae.
---
lib/bind9/check.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/lib/bind9/check.c b/lib/bind9/check.c
index ee64543..01c03d3 100644
--- a/lib/bind9/check.c
+++ b/lib/bind9/check.c
@@ -2951,20 +2951,32 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
}
if (has_dnssecpolicy) {
+ /* Red Hat downstream change. Warn only about inline-signing
+ * if inline-signing is not present in zone definition.
+ * But fail hard if present, but disabled, like before. */
if (!ddns && !signing) {
- cfg_obj_log(kasp, logctx, ISC_LOG_ERROR,
- "'inline-signing yes;' must also "
+ const char *verb = "should";
+ int log_lvl = ISC_LOG_WARNING;
+
+ if (res1 == ISC_R_SUCCESS) {
+ verb = "must";
+ log_lvl = ISC_LOG_ERROR;
+ result = ISC_R_FAILURE;
+ }
+
+ cfg_obj_log(kasp, logctx, log_lvl,
+ "'inline-signing yes;' %s also "
"be configured explicitly for "
"zones using dnssec-policy%s. See "
"https://kb.isc.org/docs/"
"dnssec-policy-requires-dynamic-"
"dns-or-inline-signing",
+ verb,
(ztype == CFG_ZONE_PRIMARY)
? " without a configured "
"'allow-update' or "
"'update-policy'"
: "");
- result = ISC_R_FAILURE;
}
}
--
2.45.2

View File

@ -1,40 +0,0 @@
From d249889a9c18df7792ca3cd8d97897e4fb5824b5 Mon Sep 17 00:00:00 2001
From: Aram Sargsyan <aram@isc.org>
Date: Wed, 31 Aug 2022 12:30:38 +0000
Subject: [PATCH] Add mctx attach/detach when creating/destroying a memory pool
This should make sure that the memory context is not destroyed
before the memory pool, which is using the context.
(cherry picked from commit e97c3eea954e055634b72c21325d2611e960ee94)
---
lib/isc/mem.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/isc/mem.c b/lib/isc/mem.c
index f84d300..33ece7a 100644
--- a/lib/isc/mem.c
+++ b/lib/isc/mem.c
@@ -1656,7 +1656,8 @@ isc_mempool_create(isc_mem_t *mctx0, size_t size, isc_mempool_t **mpctxp) {
mpctx->common.impmagic = MEMPOOL_MAGIC;
mpctx->common.magic = ISCAPI_MPOOL_MAGIC;
mpctx->lock = NULL;
- mpctx->mctx = mctx;
+ mpctx->mctx = NULL;
+ isc_mem_attach((isc_mem_t *)mctx, (isc_mem_t **)&mpctx->mctx);
/*
* Mempools are stored as a linked list of element.
*/
@@ -1765,7 +1766,8 @@ isc_mempool_destroy(isc_mempool_t **mpctxp) {
mpctx->common.impmagic = 0;
mpctx->common.magic = 0;
- isc_mem_put((isc_mem_t *)mpctx->mctx, mpctx, sizeof(isc__mempool_t));
+ isc_mem_putanddetach((isc_mem_t **)&mpctx->mctx, mpctx,
+ sizeof(isc__mempool_t));
if (lock != NULL) {
UNLOCK(lock);
--
2.43.2

View File

@ -1,66 +0,0 @@
From 103b09187466b2afbff7e204d166d21e2fbb057c Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Wed, 21 Feb 2024 11:54:27 +0100
Subject: [PATCH] Downstream specific changes related to KeyTrap
Fix for CVE-2023-50387 introduced new additional thread. But because
isc_hp functions were removed from later bind 9.16 release, their
changes did not contain increase of hazard pointers max thread limit.
To prevent obscure memory corruption increase thread max size.
In addition place at least few INSISTs to check this is catched before
random memory overwrites begins. It would be quite difficult to track
without any check.
---
lib/isc/hp.c | 3 +++
lib/isc/managers.c | 5 +++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/lib/isc/hp.c b/lib/isc/hp.c
index 92d160b..5f9bbf7 100644
--- a/lib/isc/hp.c
+++ b/lib/isc/hp.c
@@ -138,6 +138,7 @@ isc_hp_destroy(isc_hp_t *hp) {
void
isc_hp_clear(isc_hp_t *hp) {
+ INSIST(tid() < isc__hp_max_threads);
for (int i = 0; i < hp->max_hps; i++) {
atomic_store_release(&hp->hp[tid()][i], 0);
}
@@ -152,6 +153,7 @@ uintptr_t
isc_hp_protect(isc_hp_t *hp, int ihp, atomic_uintptr_t *atom) {
uintptr_t n = 0;
uintptr_t ret;
+ INSIST(tid() < isc__hp_max_threads);
while ((ret = atomic_load(atom)) != n) {
atomic_store(&hp->hp[tid()][ihp], ret);
n = ret;
@@ -173,6 +175,7 @@ isc_hp_protect_release(isc_hp_t *hp, int ihp, atomic_uintptr_t ptr) {
void
isc_hp_retire(isc_hp_t *hp, uintptr_t ptr) {
+ INSIST(tid() < isc__hp_max_threads);
hp->rl[tid()]->list[hp->rl[tid()]->size++] = ptr;
INSIST(hp->rl[tid()]->size < isc__hp_max_retired);
diff --git a/lib/isc/managers.c b/lib/isc/managers.c
index c39a650..3bdca99 100644
--- a/lib/isc/managers.c
+++ b/lib/isc/managers.c
@@ -25,9 +25,10 @@ isc_managers_create(isc_mem_t *mctx, size_t workers, size_t quantum,
/*
* We have ncpus network threads, ncpus old network threads - make
- * it 4x just to be on the safe side.
+ * it 4x just to be on the safe side. One additional for slow netmgr
+ * thread.
*/
- isc_hp_init(4 * workers);
+ isc_hp_init(5 * workers);
REQUIRE(netmgrp != NULL && *netmgrp == NULL);
isc__netmgr_create(mctx, workers, &netmgr);
--
2.43.2

View File

@ -1,34 +0,0 @@
From beeb4527b25c8d48842bbc78f100b716df118699 Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Tue, 9 Jul 2024 16:06:02 +0200
Subject: [PATCH] Increase even further hazard pointers after KeyTrap
Extends even more change Downstream specific changes related to KeyTrap,
which added safety guards into hazard pointers. Because it seems they
are not still enough. Add fixed base to accomodate common threads like
main app thread and ldap worker threads. Multiply one more, just to be
sure. We do not want to hit maximal limit again.
---
lib/isc/managers.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/isc/managers.c b/lib/isc/managers.c
index 3bdca99..fffff78 100644
--- a/lib/isc/managers.c
+++ b/lib/isc/managers.c
@@ -26,9 +26,10 @@ isc_managers_create(isc_mem_t *mctx, size_t workers, size_t quantum,
/*
* We have ncpus network threads, ncpus old network threads - make
* it 4x just to be on the safe side. One additional for slow netmgr
- * thread.
+ * thread. One extra to be safe. Add base for main application thread
+ * or bind-dyndb-ldap worker threads.
*/
- isc_hp_init(5 * workers);
+ isc_hp_init(6 + 6 * workers);
REQUIRE(netmgrp != NULL && *netmgrp == NULL);
isc__netmgr_create(mctx, workers, &netmgr);
--
2.45.2

View File

@ -1,38 +0,0 @@
diff --git a/CHANGES b/CHANGES
index 2b12128544..42c13c9dbd 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+6173. [bug] Properly process extra "nameserver" lines in
+ resolv.conf otherwise the next line is not properly
+ processed. [GL #4066]
+
--- 9.16.23 released ---
5752. [bug] Fix an assertion failure caused by missing member zones
diff --git a/lib/irs/resconf.c b/lib/irs/resconf.c
index da6066db7b..775f4e86a4 100644
--- a/lib/irs/resconf.c
+++ b/lib/irs/resconf.c
@@ -286,10 +286,6 @@ resconf_parsenameserver(irs_resconf_t *conf, FILE *fp) {
int cp;
isc_result_t result;
- if (conf->numns == RESCONFMAXNAMESERVERS) {
- return (ISC_R_SUCCESS);
- }
-
cp = getword(fp, word, sizeof(word));
if (strlen(word) == 0U) {
return (ISC_R_UNEXPECTEDEND); /* Nothing on line. */
@@ -301,6 +297,10 @@ resconf_parsenameserver(irs_resconf_t *conf, FILE *fp) {
return (ISC_R_UNEXPECTEDTOKEN); /* Extra junk on line. */
}
+ if (conf->numns == RESCONFMAXNAMESERVERS) {
+ return (ISC_R_SUCCESS);
+ }
+
result = add_server(conf->mctx, word, &conf->nameservers);
if (result != ISC_R_SUCCESS) {
return (result);

View File

@ -0,0 +1,34 @@
From ebedaa79b93dfcb4f41169095ae02f59dedb3fa1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Tue, 2 Dec 2025 17:29:59 +0100
Subject: [PATCH] Swap order of tried setuptools providers
Older distutils.core will generate only a single file, not whole
directory. That is needed for upgrade test. For newer distributions,
setuptools should still work.
To keep backward compatibility with 9.16.23, prefer distutils.
---
bin/python/setup.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/bin/python/setup.py b/bin/python/setup.py
index 4440b74..dc96561 100644
--- a/bin/python/setup.py
+++ b/bin/python/setup.py
@@ -10,10 +10,10 @@
# information regarding copyright ownership.
try:
- from setuptools import setup
-except ImportError:
# pylint: disable=deprecated-module
from distutils.core import setup
+except ImportError:
+ from setuptools import setup
setup(
name="isc",
--
2.52.0

View File

@ -0,0 +1,35 @@
From 68c631cf8dc67cb315d738a55a97fff26c0818e7 Mon Sep 17 00:00:00 2001
From: Fedor Vorobev <fvorobev@redhat.com>
Date: Thu, 23 Jul 2026 10:55:42 +0200
Subject: [PATCH] Remove OPENSSL_API_LEVEL < 30000 check from an engine check.
It was added in 5f8ac682c9912aaf564595f73f777672743f56aa upstream
commit, which was a cherry pick from a newer version of bind. As this is
the only instance of OPENSSL_API_LEVEL < 30000 within bind 9.16.50, I
believe it was done in error.
This check was preventing bind from finding the OpenSSL engine for RSA
algorithms. `dnssec-keyfromlabel` would error out with 'no engine'
whenever an RSA algorithm was used.
Resolves: RHEL-213788
---
lib/dns/opensslrsa_link.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c
index 09412c58b5..81ce6cc7cb 100644
--- a/lib/dns/opensslrsa_link.c
+++ b/lib/dns/opensslrsa_link.c
@@ -931,7 +931,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
for (i = 0; i < priv.nelements; i++) {
switch (priv.elements[i].tag) {
-#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
+#if !defined(OPENSSL_NO_ENGINE)
case TAG_RSA_ENGINE:
engine = (char *)priv.elements[i].data;
break;
--
2.55.0

View File

@ -1,216 +0,0 @@
From b1871274cd2c97b63f3b90d608b7f8936d4ff3c5 Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Wed, 24 Aug 2022 12:21:50 +1000
Subject: [PATCH] Have dns_zt_apply lock the zone table
There where a number of places where the zone table should have
been locked, but wasn't, when dns_zt_apply was called.
Added a isc_rwlocktype_t type parameter to dns_zt_apply and adjusted
all calls to using it. Removed locks in callers.
Modified upstream commit for v9_16
---
bin/named/server.c | 12 +++++++-----
bin/named/statschannel.c | 12 +++++++-----
lib/dns/include/dns/zt.h | 3 ++-
lib/dns/tests/zt_test.c | 4 ++--
lib/dns/view.c | 3 ++-
lib/dns/zt.c | 29 ++++++++++++++++++-----------
6 files changed, 38 insertions(+), 25 deletions(-)
diff --git a/bin/named/server.c b/bin/named/server.c
index 860ccae..c2a5887 100644
--- a/bin/named/server.c
+++ b/bin/named/server.c
@@ -9458,7 +9458,8 @@ cleanup:
if (result == ISC_R_SUCCESS && strcmp(view->name, "_bind") != 0)
{
dns_view_setviewrevert(view);
- (void)dns_zt_apply(view->zonetable, false, NULL,
+ (void)dns_zt_apply(view->zonetable,
+ isc_rwlocktype_read, false, NULL,
removed, view);
}
dns_view_detach(&view);
@@ -10901,8 +10902,8 @@ add_view_tolist(struct dumpcontext *dctx, dns_view_t *view) {
ISC_LIST_INIT(vle->zonelist);
ISC_LIST_APPEND(dctx->viewlist, vle, link);
if (dctx->dumpzones) {
- result = dns_zt_apply(view->zonetable, true, NULL,
- add_zone_tolist, dctx);
+ result = dns_zt_apply(view->zonetable, isc_rwlocktype_read,
+ true, NULL, add_zone_tolist, dctx);
}
return (result);
}
@@ -12248,8 +12249,9 @@ named_server_sync(named_server_t *server, isc_lex_t *lex, isc_buffer_t **text) {
for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
view = ISC_LIST_NEXT(view, link))
{
- result = dns_zt_apply(view->zonetable, false, NULL,
- synczone, &cleanup);
+ result = dns_zt_apply(view->zonetable,
+ isc_rwlocktype_none, false,
+ NULL, synczone, &cleanup);
if (result != ISC_R_SUCCESS && tresult == ISC_R_SUCCESS)
{
tresult = result;
diff --git a/bin/named/statschannel.c b/bin/named/statschannel.c
index 8ff2567..832ce93 100644
--- a/bin/named/statschannel.c
+++ b/bin/named/statschannel.c
@@ -2296,8 +2296,9 @@ generatexml(named_server_t *server, uint32_t flags, int *buflen,
if ((flags & STATS_XML_ZONES) != 0) {
TRY0(xmlTextWriterStartElement(writer,
ISC_XMLCHAR "zones"));
- result = dns_zt_apply(view->zonetable, true, NULL,
- zone_xmlrender, writer);
+ result = dns_zt_apply(view->zonetable,
+ isc_rwlocktype_read, true,
+ NULL, zone_xmlrender, writer);
if (result != ISC_R_SUCCESS) {
goto error;
}
@@ -3069,9 +3070,10 @@ generatejson(named_server_t *server, size_t *msglen, const char **msg,
CHECKMEM(za);
if ((flags & STATS_JSON_ZONES) != 0) {
- result = dns_zt_apply(view->zonetable, true,
- NULL, zone_jsonrender,
- za);
+ result = dns_zt_apply(view->zonetable,
+ isc_rwlocktype_read,
+ true, NULL,
+ zone_jsonrender, za);
if (result != ISC_R_SUCCESS) {
goto error;
}
diff --git a/lib/dns/include/dns/zt.h b/lib/dns/include/dns/zt.h
index 4a1b263..1c6c789 100644
--- a/lib/dns/include/dns/zt.h
+++ b/lib/dns/include/dns/zt.h
@@ -168,7 +168,8 @@ dns_zt_freezezones(dns_zt_t *zt, dns_view_t *view, bool freeze);
*/
isc_result_t
-dns_zt_apply(dns_zt_t *zt, bool stop, isc_result_t *sub,
+dns_zt_apply(dns_zt_t *zt, isc_rwlocktype_t lock, bool stop,
+ isc_result_t *sub,
isc_result_t (*action)(dns_zone_t *, void *), void *uap);
/*%<
* Apply a given 'action' to all zone zones in the table.
diff --git a/lib/dns/tests/zt_test.c b/lib/dns/tests/zt_test.c
index 7945a0b..bfacb94 100644
--- a/lib/dns/tests/zt_test.c
+++ b/lib/dns/tests/zt_test.c
@@ -136,8 +136,8 @@ apply(void **state) {
assert_non_null(view->zonetable);
assert_int_equal(nzones, 0);
- result = dns_zt_apply(view->zonetable, false, NULL, count_zone,
- &nzones);
+ result = dns_zt_apply(view->zonetable, isc_rwlocktype_read, false,
+ NULL, count_zone, &nzones);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(nzones, 1);
diff --git a/lib/dns/view.c b/lib/dns/view.c
index 8c7e40a..dcb0f18 100644
--- a/lib/dns/view.c
+++ b/lib/dns/view.c
@@ -704,7 +704,8 @@ dns_view_dialup(dns_view_t *view) {
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(view->zonetable != NULL);
- (void)dns_zt_apply(view->zonetable, false, NULL, dialup, NULL);
+ (void)dns_zt_apply(view->zonetable, isc_rwlocktype_read, false,
+ NULL, dialup, NULL);
}
void
diff --git a/lib/dns/zt.c b/lib/dns/zt.c
index 8ca9cd6..1bfc308 100644
--- a/lib/dns/zt.c
+++ b/lib/dns/zt.c
@@ -223,7 +223,8 @@ flush(dns_zone_t *zone, void *uap) {
static void
zt_destroy(dns_zt_t *zt) {
if (atomic_load_acquire(&zt->flush)) {
- (void)dns_zt_apply(zt, false, NULL, flush, NULL);
+ (void)dns_zt_apply(zt, isc_rwlocktype_none, false, NULL,
+ flush, NULL);
}
dns_rbt_destroy(&zt->table);
isc_rwlock_destroy(&zt->rwlock);
@@ -265,9 +266,8 @@ dns_zt_load(dns_zt_t *zt, bool stop, bool newonly) {
struct zt_load_params params;
REQUIRE(VALID_ZT(zt));
params.newonly = newonly;
- RWLOCK(&zt->rwlock, isc_rwlocktype_read);
- result = dns_zt_apply(zt, stop, NULL, load, &params);
- RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
+ result = dns_zt_apply(zt, isc_rwlocktype_read, stop, NULL, load,
+ &params);
return (result);
}
@@ -338,9 +338,8 @@ dns_zt_asyncload(dns_zt_t *zt, bool newonly, dns_zt_allloaded_t alldone,
zt->loaddone = alldone;
zt->loaddone_arg = arg;
- RWLOCK(&zt->rwlock, isc_rwlocktype_read);
- result = dns_zt_apply(zt, false, NULL, asyncload, zt);
- RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
+ result = dns_zt_apply(zt, isc_rwlocktype_read, false, NULL,
+ asyncload, zt);
/*
* Have all the loads completed?
@@ -386,9 +385,8 @@ dns_zt_freezezones(dns_zt_t *zt, dns_view_t *view, bool freeze) {
REQUIRE(VALID_ZT(zt));
- RWLOCK(&zt->rwlock, isc_rwlocktype_read);
- result = dns_zt_apply(zt, false, &tresult, freezezones, &params);
- RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
+ result = dns_zt_apply(zt, isc_rwlocktype_read, false, &tresult,
+ freezezones, &params);
if (tresult == ISC_R_NOTFOUND) {
tresult = ISC_R_SUCCESS;
}
@@ -522,7 +520,8 @@ dns_zt_setviewrevert(dns_zt_t *zt) {
}
isc_result_t
-dns_zt_apply(dns_zt_t *zt, bool stop, isc_result_t *sub,
+dns_zt_apply(dns_zt_t *zt, isc_rwlocktype_t lock, bool stop,
+ isc_result_t *sub,
isc_result_t (*action)(dns_zone_t *, void *), void *uap) {
dns_rbtnode_t *node;
dns_rbtnodechain_t chain;
@@ -532,6 +531,10 @@ dns_zt_apply(dns_zt_t *zt, bool stop, isc_result_t *sub,
REQUIRE(VALID_ZT(zt));
REQUIRE(action != NULL);
+ if (lock != isc_rwlocktype_none) {
+ RWLOCK(&zt->rwlock, lock);
+ }
+
dns_rbtnodechain_init(&chain);
result = dns_rbtnodechain_first(&chain, zt->table, NULL, NULL);
if (result == ISC_R_NOTFOUND) {
@@ -568,6 +571,10 @@ cleanup:
*sub = tresult;
}
+ if (lock != isc_rwlocktype_none) {
+ RWUNLOCK(&zt->rwlock, lock);
+ }
+
return (result);
}
--
2.39.2

View File

@ -1,31 +0,0 @@
From 606fc6d4aa8e8884f53f53e72dc1bd7babf37a47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Mon, 16 Jan 2023 11:06:48 +0000
Subject: [PATCH] Merge branch 'feature/main/zt-rwlock.h' into 'main'
Include isc_rwlocktype_t type definition in zt.h
See merge request isc-projects/bind9!7376
(cherry picked from commit d7bcdf8bd6c5395726f708535120ce9a97eaa935)
395d6fca Include isc_rwlocktype_t type definition in zt.h
---
lib/dns/include/dns/zt.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/dns/include/dns/zt.h b/lib/dns/include/dns/zt.h
index 189092bc3b..2964fc971f 100644
--- a/lib/dns/include/dns/zt.h
+++ b/lib/dns/include/dns/zt.h
@@ -19,6 +19,7 @@
#include <stdbool.h>
#include <isc/lang.h>
+#include <isc/rwlock.h>
#include <dns/types.h>
--
2.39.0

View File

@ -1,33 +0,0 @@
From 7cc9fd1870e5264abd885ed2c419034945121d0f Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Mon, 19 Feb 2024 22:13:52 +0100
Subject: [PATCH] Define variants to empty values
DNSSEC_VARIANT and NAMED_VARIANT are special Red Hat modifications to
allow testing or alternative rebuilds, with support for pkcs11 or sdb.
But undefined value breaks some tests, so define them to empty values.
That means normal build variant.
Required to pass upstream test suite cds test correctly.
---
bin/tests/system/conf.sh.in | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in
index 7b2b309..c2d6526 100644
--- a/bin/tests/system/conf.sh.in
+++ b/bin/tests/system/conf.sh.in
@@ -24,6 +24,10 @@ TMPDIR=${TMPDIR:-/tmp}
# This is not the windows build.
CYGWIN=""
+# RH specific, allow variants testing
+: ${DNSSEC_VARIANT:=}
+: ${NAMED_VARIANT:=}
+
# Load common values shared between windows and unix/linux.
. $TOP/bin/tests/system/conf.sh.common
--
2.43.2

View File

@ -1,53 +0,0 @@
From c532af966a7328f0e518273bc1f6051bb9d9e995 Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Thu, 12 Oct 2023 10:19:38 +1100
Subject: [PATCH] Update b.root-servers.net IP addresses
This covers both root hints and the default primaries for the root
zone mirror. The official change date is Nov 27, 2023.
(cherry picked from commit 2ca2f7e9852a3d6e93f065c01ea4679f723688f7)
---
bin/named/config.c | 4 ++--
lib/dns/rootns.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/bin/named/config.c b/bin/named/config.c
index 8c6f90c..c37015f 100644
--- a/bin/named/config.c
+++ b/bin/named/config.c
@@ -292,14 +292,14 @@ view \"_bind\" chaos {\n\
"# END MANAGED KEYS\n\
\n\
primaries " DEFAULT_IANA_ROOT_ZONE_PRIMARIES " {\n\
- 2001:500:200::b; # b.root-servers.net\n\
+ 2801:1b8:10::b; # b.root-servers.net\n\
2001:500:2::c; # c.root-servers.net\n\
2001:500:2f::f; # f.root-servers.net\n\
2001:500:12::d0d; # g.root-servers.net\n\
2001:7fd::1; # k.root-servers.net\n\
2620:0:2830:202::132; # xfr.cjr.dns.icann.org\n\
2620:0:2d0:202::132; # xfr.lax.dns.icann.org\n\
- 199.9.14.201; # b.root-servers.net\n\
+ 170.247.170.2; # b.root-servers.net\n\
192.33.4.12; # c.root-servers.net\n\
192.5.5.241; # f.root-servers.net\n\
192.112.36.4; # g.root-servers.net\n\
diff --git a/lib/dns/rootns.c b/lib/dns/rootns.c
index 885c2fb..b06d247 100644
--- a/lib/dns/rootns.c
+++ b/lib/dns/rootns.c
@@ -52,8 +52,8 @@ static char root_ns[] =
". 518400 IN NS M.ROOT-SERVERS.NET.\n"
"A.ROOT-SERVERS.NET. 3600000 IN A 198.41.0.4\n"
"A.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:BA3E::2:30\n"
- "B.ROOT-SERVERS.NET. 3600000 IN A 199.9.14.201\n"
- "B.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:200::b\n"
+ "B.ROOT-SERVERS.NET. 3600000 IN A 170.247.170.2\n"
+ "B.ROOT-SERVERS.NET. 3600000 IN AAAA 2801:1b8:10::b\n"
"C.ROOT-SERVERS.NET. 3600000 IN A 192.33.4.12\n"
"C.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2::c\n"
"D.ROOT-SERVERS.NET. 3600000 IN A 199.7.91.13\n"
--
2.43.0

View File

@ -1,17 +0,0 @@
-----BEGIN PGP SIGNATURE-----
Comment: GPGTools - https://gpgtools.org
iQIzBAABAgAdFiEEqtu6UHTxQC97adVrxbTukxqfnf0FAmGKhMcACgkQxbTukxqf
nf1EbQ//YXsBbMtyI3c0MoleSi5zwzcpCTZTWTFHqH5WUiruLMDF453j/Fn2zaSC
WuaUnhN61dR+BVtX+D2Y8GiVQFICo5X1nJj0jb/TcflXFq7YLWUAO0NPwPkBL1J4
/PA0YCp1zYcvBXIxTKaU7AcBxlKmcGLdZcgCyGU6NSKaOJSxHOWXM460uD/crskB
iSPEbMevN9TTJs9webztJNKH/3BuNkOD9SFb6JlUIQqwKx1v8rosgdI7BvgGMZqy
s+10+GlIRFFvsX2XkX8BnjDlQ1QdzDOAoyCU+Se9rXDqu+zZf1VN4ReUCSDuPYf9
z+GW1EbMxuZzEKrEIJvhnVNNiHqtKVaK6IIUX5bHqgPLEx87HxJMOPmbyBc1kDAe
0WCmsITaq62WvKOG8Ho8wLrlG4AAO5+A7xit4bJ4XUtLiqyt+9FUIeEFY9nZb/6O
OXK9eBMZHZ++r52RtA+GYZllkNRpzwnULOdR/9svVQuc10/MjnRoFqInzLlqwfwm
2q6r372oWn8+MUvjQVBgzprn5BvY+HDo2gNEYEi5QyR3ql2dX/Qz7iUdUfhRvMNL
FdPt3B3kktfOV98p/imrIwLwVVWwKBlphntkRxLtSZBs3nbo27F/ND54fixC2eCa
epB6FF5IquzQ/MOiz4uql3YexNDQQ+7N2IGPJVMwO2ILAyZDNOQ=
=pVtf
-----END PGP SIGNATURE-----

View File

@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEcGtsKGIOdvkdEfffUQpkKgbFLOwFAmYP/t0ACgkQUQpkKgbF
LOzyew/9HC8SiGcokr7K7inFoW3ftPkOL2yKVcsA345uxMF8Tf9q1s5GVAZSRFTA
WsunUb5iz//5s7QGXvSf05xLRgY5kKhLd0YywW4jscy8YssQvXol3ZK6VEhA5uVe
7mHJu8+00DiHv4gBXmJMS/+przeykNTZk/u10cIeanUgWKYqt/uMGYrycttsiRaI
wob7DSEwK0qu7zX6pKPEKVwzchdLK9O9aXr23SJaoDAn7UqKRN+s4b7pEPOqjDaF
liGp74AZagGji7Me5rESS8NkfQmiZ/bgcwYrUC/mWDA/K4ClCFKTUZQ6Lfnwlxjo
263myX3tAHuZ5LruLsCRFiRrSiknoUQDwEcx/Z2eZBYjpXwcaKnavT9UUbnzN+jI
QZcDypRvzYNPneqDor9ak3/MJWoDqdoEOkTbxjQQXy3j9Pj4CZsjp4lRCEcmIQoA
8nkQ3dFcKkjJg//N5GCk0m7LlBbZYLaxDyRLa/doYYXd9t2HXMsFN6aPiQCRV+sY
xrT9mHDJHwjyIqTh0ufPkLIBJdsqDaloSsFayL6WzFWCTOUNGkMkgnZxqLQeLQ4y
JV/XW0q0At4GM4VqrFx9I3YbEdXpcfF6KdfijLmYGY29JPB0Tz5tN58wl94E1gtq
A155o0v14/2r8gTb0y3X3dbXUCMGvVXHhLEEgTDgElhUDBXzc9k=
=syDr
-----END PGP SIGNATURE-----

View File

@ -1,4 +1,4 @@
From cc01143082bc688a371a7378ef284c898eedc9df Mon Sep 17 00:00:00 2001
From 1e3d6c2862cb7911fdd01b9d69a8599b462b797c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Tue, 7 Jan 2025 15:22:40 +0100
Subject: [PATCH] Isolate using the -T noaa flag only for part of the resolver
@ -14,48 +14,55 @@ system test.
(cherry picked from commit e51d4d3b88af00d6667f2055087ebfc47fb3107c)
---
bin/tests/system/resolver/ns4/named.noaa | 5 -----
bin/tests/system/resolver/tests.sh | 8 ++++++++
2 files changed, 8 insertions(+), 5 deletions(-)
bin/tests/system/resolver/ns4/named.noaa | 12 ------------
bin/tests/system/resolver/tests.sh | 8 ++++++++
2 files changed, 8 insertions(+), 12 deletions(-)
delete mode 100644 bin/tests/system/resolver/ns4/named.noaa
diff --git a/bin/tests/system/resolver/ns4/named.noaa b/bin/tests/system/resolver/ns4/named.noaa
deleted file mode 100644
index 3b121ad..0000000
index be78cc2c94..0000000000
--- a/bin/tests/system/resolver/ns4/named.noaa
+++ /dev/null
@@ -1,5 +0,0 @@
@@ -1,12 +0,0 @@
-Copyright (C) Internet Systems Consortium, Inc. ("ISC")
-
-See COPYRIGHT in the source root or https://isc.org/copyright.html for terms.
-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.
-
-Add -T noaa.
diff --git a/bin/tests/system/resolver/tests.sh b/bin/tests/system/resolver/tests.sh
index 711ee05..2eae16f 100755
index d9121d9ae5..29562c2db0 100755
--- a/bin/tests/system/resolver/tests.sh
+++ b/bin/tests/system/resolver/tests.sh
@@ -289,6 +289,10 @@ done
@@ -309,6 +309,10 @@ done
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
status=$((status + ret))
+stop_server resolver ns4
+stop_server ns4
+touch ns4/named.noaa
+start_server --noclean --restart --port ${PORT} resolver ns4 || ret=1
+start_server --noclean --restart --port ${PORT} ns4 || ret=1
+
n=`expr $n + 1`
n=$((n + 1))
echo_i "RT21594 regression test check setup ($n)"
ret=0
@@ -325,6 +329,10 @@ grep "status: NXDOMAIN" dig.ns5.out.${n} > /dev/null || ret=1
@@ -345,6 +349,10 @@ grep "status: NXDOMAIN" dig.ns5.out.${n} >/dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
status=$((status + ret))
+stop_server resolver ns4
+stop_server ns4
+rm ns4/named.noaa
+start_server --noclean --restart --port ${PORT} resolver ns4 || ret=1
+start_server --noclean --restart --port ${PORT} ns4 || ret=1
+
n=`expr $n + 1`
n=$((n + 1))
echo_i "check that replacement of additional data by a negative cache no data entry clears the additional RRSIGs ($n)"
ret=0
--
2.48.1
2.53.0

View File

@ -1,4 +1,4 @@
From b095854ee885dd5960cb54e7fbefb962498e9fdb Mon Sep 17 00:00:00 2001
From 0f9d817ca87207f2695560645e12478477d345a5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Thu, 14 Nov 2024 10:37:29 +0100
Subject: [PATCH] Limit the additional processing for large RDATA sets
@ -22,23 +22,23 @@ PatchNumber: 47
5 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/bin/tests/system/additional/tests.sh b/bin/tests/system/additional/tests.sh
index 025f11f..846c800 100644
index 3701790..4281238 100644
--- a/bin/tests/system/additional/tests.sh
+++ b/bin/tests/system/additional/tests.sh
@@ -260,7 +260,7 @@ n=`expr $n + 1`
@@ -278,7 +278,7 @@ n=$(expr $n + 1)
echo_i "testing with 'minimal-any no;' ($n)"
ret=0
$DIG $DIGOPTS -t ANY www.rt.example @10.53.0.1 > dig.out.$n || ret=1
-grep "ANSWER: 3, AUTHORITY: 2, ADDITIONAL: 2" dig.out.$n > /dev/null || ret=1
$DIG $DIGOPTS -t ANY www.rt.example @10.53.0.1 >dig.out.$n || ret=1
-grep "ANSWER: 3, AUTHORITY: 2, ADDITIONAL: 2" dig.out.$n >/dev/null || ret=1
+grep "ANSWER: 3, AUTHORITY: 2, ADDITIONAL: 1" dig.out.$n > /dev/null || ret=1
if [ $ret -eq 1 ] ; then
echo_i "failed"; status=$((status+1))
fi
if [ $ret -eq 1 ]; then
echo_i "failed"
status=$((status + 1))
diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h
index f2585ef..54ad7b2 100644
index de3f638..85c081e 100644
--- a/lib/dns/include/dns/rdataset.h
+++ b/lib/dns/include/dns/rdataset.h
@@ -53,6 +53,8 @@
@@ -55,6 +55,8 @@
#include <dns/rdatastruct.h>
#include <dns/types.h>
@ -47,7 +47,7 @@ index f2585ef..54ad7b2 100644
ISC_LANG_BEGINDECLS
typedef enum {
@@ -458,13 +460,23 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
@@ -465,13 +467,23 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
*\li If a call to dns_rdata_additionaldata() is not successful, the
* result returned will be the result of dns_rdataset_additionaldata().
*
@ -72,10 +72,10 @@ index f2585ef..54ad7b2 100644
dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
dns_rdataset_t *neg, dns_rdataset_t *negsig);
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index ed5015c..7586e2a 100644
index c2cd63e..b1efa0b 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -10626,7 +10626,7 @@ no_glue:
@@ -10632,7 +10632,7 @@ no_glue:
maybe_rehash_gluetable(rbtversion);
idx = hash_32(hash, rbtversion->glue_table_bits);
@ -85,10 +85,10 @@ index ed5015c..7586e2a 100644
cur = isc_mem_get(rbtdb->common.mctx, sizeof(*cur));
diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c
index bf9e7af..ffe6163 100644
index 221d7f8..0f83d1f 100644
--- a/lib/dns/rdataset.c
+++ b/lib/dns/rdataset.c
@@ -27,6 +27,7 @@
@@ -29,6 +29,7 @@
#include <dns/ncache.h>
#include <dns/rdata.h>
#include <dns/rdataset.h>
@ -96,7 +96,7 @@ index bf9e7af..ffe6163 100644
static const char *trustnames[] = {
"none", "pending-additional",
@@ -577,6 +578,12 @@ dns_rdataset_towire(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
@@ -579,6 +580,12 @@ dns_rdataset_towire(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
isc_result_t
dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
dns_additionaldatafunc_t add, void *arg) {
@ -109,7 +109,7 @@ index bf9e7af..ffe6163 100644
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_result_t result;
@@ -588,6 +595,10 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
@@ -590,6 +597,10 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
REQUIRE(DNS_RDATASET_VALID(rdataset));
REQUIRE((rdataset->attributes & DNS_RDATASETATTR_QUESTION) == 0);
@ -121,10 +121,10 @@ index bf9e7af..ffe6163 100644
if (result != ISC_R_SUCCESS) {
return (result);
diff --git a/lib/ns/query.c b/lib/ns/query.c
index f7b3f78..5bc2908 100644
index ec9bf5b..b31857c 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -2030,8 +2030,9 @@ addname:
@@ -2047,8 +2047,9 @@ addname:
* This cannot go more than MAX_RESTARTS levels deep.
*/
if (trdataset != NULL && dns_rdatatype_followadditional(type)) {
@ -136,7 +136,7 @@ index f7b3f78..5bc2908 100644
}
cleanup:
@@ -2122,7 +2123,8 @@ regular:
@@ -2139,7 +2140,8 @@ regular:
* Add other additional data if needed.
* We don't care if dns_rdataset_additionaldata() fails.
*/
@ -146,7 +146,7 @@ index f7b3f78..5bc2908 100644
CTRACE(ISC_LOG_DEBUG(3), "query_additional: done");
}
@@ -2148,7 +2150,8 @@ query_addrrset(query_ctx_t *qctx, dns_name_t **namep,
@@ -2165,7 +2167,8 @@ query_addrrset(query_ctx_t *qctx, dns_name_t **namep,
* To the current response for 'client', add the answer RRset
* '*rdatasetp' and an optional signature set '*sigrdatasetp', with
* owner name '*namep', to section 'section', unless they are
@ -156,7 +156,7 @@ index f7b3f78..5bc2908 100644
*
* If 'dbuf' is not NULL, then '*namep' is the name whose data is
* stored in 'dbuf'. In this case, query_addrrset() guarantees that
@@ -2203,7 +2206,9 @@ query_addrrset(query_ctx_t *qctx, dns_name_t **namep,
@@ -2220,7 +2223,9 @@ query_addrrset(query_ctx_t *qctx, dns_name_t **namep,
*/
query_addtoname(mname, rdataset);
query_setorder(qctx, mname, rdataset);
@ -168,5 +168,5 @@ index f7b3f78..5bc2908 100644
/*
* Note: we only add SIGs if we've added the type they cover, so
--
2.48.1
2.51.1

View File

@ -1,4 +1,4 @@
From 11f35bdef6f070412cb2c1c65d9537b82ea38c8a Mon Sep 17 00:00:00 2001
From 77105c4738a07c48d2cf52fc1fcb1c7b2eb50661 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Tue, 16 Sep 2025 11:46:03 +0200
Subject: [PATCH] Fix expectations on idna system test
@ -16,65 +16,68 @@ bind 9.16 version.
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/bin/tests/system/idna/tests.sh b/bin/tests/system/idna/tests.sh
index a04012a..5541b94 100644
index 8c2826f..5b8ddd1 100644
--- a/bin/tests/system/idna/tests.sh
+++ b/bin/tests/system/idna/tests.sh
@@ -185,7 +185,7 @@ idna_enabled_test() {
# Note that ASCII characters are converted to lower-case.
@@ -187,7 +187,7 @@ idna_enabled_test() {
# Note that ASCII characters are converted to lower-case.
text="Checking valid non-ASCII label"
- idna_test "$text" "" "München" "M\195\188nchen."
+ idna_test "$text" "" "München" "xn--mnchen-3ya."
idna_test "$text" "+noidnin +noidnout" "München" "M\195\188nchen."
idna_test "$text" "+noidnin +idnout" "München" "M\195\188nchen."
idna_test "$text" "+idnin +noidnout" "München" "xn--mnchen-3ya."
@@ -210,7 +210,7 @@ idna_enabled_test() {
# for the valid U-label.
text="Checking valid non-ASCII label"
- idna_test "$text" "" "München" "M\195\188nchen."
+ idna_test "$text" "" "München" "xn--mnchen-3ya."
idna_test "$text" "+noidnin +noidnout" "München" "M\195\188nchen."
idna_test "$text" "+noidnin +idnout" "München" "M\195\188nchen."
idna_test "$text" "+idnin +noidnout" "München" "xn--mnchen-3ya."
@@ -211,7 +211,7 @@ idna_enabled_test() {
# for the valid U-label.
text="Checking that non-transitional IDNA processing is used"
- idna_test "$text" "" "faß.de" "fa\195\159.de."
+ idna_test "$text" "" "faß.de" "xn--fa-hia.de."
idna_test "$text" "+noidnin +noidnout" "faß.de" "fa\195\159.de."
idna_test "$text" "+noidnin +idnout" "faß.de" "fa\195\159.de."
idna_test "$text" "+idnin +noidnout" "faß.de" "xn--fa-hia.de."
@@ -220,7 +220,7 @@ idna_enabled_test() {
# onto the Greek sigma character ("σ") in IDNA2003.
text="Checking that non-transitional IDNA processing is used"
- idna_test "$text" "" "faß.de" "fa\195\159.de."
+ idna_test "$text" "" "faß.de" "xn--fa-hia.de."
idna_test "$text" "+noidnin +noidnout" "faß.de" "fa\195\159.de."
idna_test "$text" "+noidnin +idnout" "faß.de" "fa\195\159.de."
idna_test "$text" "+idnin +noidnout" "faß.de" "xn--fa-hia.de."
@@ -221,7 +221,7 @@ idna_enabled_test() {
# onto the Greek sigma character ("σ") in IDNA2003.
text="Second check that non-transitional IDNA processing is used"
- idna_test "$text" "" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
+ idna_test "$text" "" "βόλος.com" "xn--nxasmm1c.com."
idna_test "$text" "+noidnin +noidnout" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
idna_test "$text" "+noidnin +idnout" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
idna_test "$text" "+idnin +noidnout" "βόλος.com" "xn--nxasmm1c.com."
@@ -284,7 +284,7 @@ idna_enabled_test() {
idna_test "$text" "" "xn--xx" "xn--xx."
idna_test "$text" "+noidnin +noidnout" "xn--xx" "xn--xx."
idna_fail "$text" "+noidnin +idnout" "xn--xx"
- idna_fail "$text" "+idnin +noidnout" "xn--xx"
+ idna_test "$text" "+idnin +noidnout" "xn--xx" "xn--xx."
idna_fail "$text" "+idnin +idnout" "xn--xx"
text="Second check that non-transitional IDNA processing is used"
- idna_test "$text" "" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
+ idna_test "$text" "" "βόλος.com" "xn--nxasmm1c.com."
idna_test "$text" "+noidnin +noidnout" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
idna_test "$text" "+noidnin +idnout" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
idna_test "$text" "+idnin +noidnout" "βόλος.com" "xn--nxasmm1c.com."
@@ -281,7 +281,7 @@ idna_enabled_test() {
idna_test "$text" "" "xn--xx" "xn--xx."
idna_test "$text" "+noidnin +noidnout" "xn--xx" "xn--xx."
idna_fail "$text" "+noidnin +idnout" "xn--xx"
- idna_fail "$text" "+idnin +noidnout" "xn--xx"
+ idna_test "$text" "+idnin +noidnout" "xn--xx" "xn--xx."
idna_fail "$text" "+idnin +idnout" "xn--xx"
# Fake A-label - the string does not translate to anything.
@@ -293,7 +293,7 @@ idna_enabled_test() {
idna_test "$text" "" "xn--ahahah" "xn--ahahah."
idna_test "$text" "+noidnin +noidnout" "xn--ahahah" "xn--ahahah."
idna_fail "$text" "+noidnin +idnout" "xn--ahahah"
- idna_fail "$text" "+idnin +noidnout" "xn--ahahah"
+ idna_test "$text" "+idnin +noidnout" "xn--ahahah" "xn--ahahah."
idna_fail "$text" "+idnin +idnout" "xn--ahahah"
# Fake A-label - the string does not translate to anything.
@@ -290,7 +290,7 @@ idna_enabled_test() {
idna_test "$text" "" "xn--ahahah" "xn--ahahah."
idna_test "$text" "+noidnin +noidnout" "xn--ahahah" "xn--ahahah."
idna_fail "$text" "+noidnin +idnout" "xn--ahahah"
- idna_fail "$text" "+idnin +noidnout" "xn--ahahah"
+ idna_test "$text" "+idnin +noidnout" "xn--ahahah" "xn--ahahah."
idna_fail "$text" "+idnin +idnout" "xn--ahahah"
# Too long a label. The punycode string is too long (at 64 characters).
@@ -326,8 +326,8 @@ idna_enabled_test() {
idna_test "$text" "" "√.com" "\226\136\154.com."
idna_test "$text" "+noidnin +noidnout" "√.com" "\226\136\154.com."
idna_test "$text" "+noidnin +idnout" "√.com" "\226\136\154.com."
- idna_fail "$text" "+idnin +noidnout" "√.com"
- idna_fail "$text" "+idnin +idnout" "√.com"
+ idna_test "$text" "+idnin +noidnout" "√.com" "\226\136\154.com."
+ idna_test "$text" "+idnin +idnout" "√.com" "\226\136\154.com."
# Too long a label. The punycode string is too long (at 64 characters).
@@ -317,11 +317,11 @@ idna_enabled_test() {
# The +[no]idnout options should not have any effect on the test.
# Tests of a valid unicode string but an invalid U-label (output)
#
text="Checking invalid input U-label"
- idna_test "$text" "" "√.com" "\226\136\154.com."
+ idna_test "$text" "" "√.com" "xn--19g.com."
idna_test "$text" "+noidnin +noidnout" "√.com" "\226\136\154.com."
idna_test "$text" "+noidnin +idnout" "√.com" "\226\136\154.com."
idna_test "$text" "+idnin +noidnout" "√.com" "xn--19g.com."
- idna_test "$text" "+idnin +idnout" "√.com" "√.com."
+ idna_test "$text" "+idnin +idnout" "√.com" "√.com."
# Tests of a valid unicode string but an invalid U-label (output)
#
--
2.51.0
2.51.1

View File

@ -1,4 +1,4 @@
From d023241c7e2921926be8bd1784424eefba2a3c54 Mon Sep 17 00:00:00 2001
From cd5e88407380c5ced9a51736f0c2d679d053e188 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Wed, 6 Nov 2024 21:29:47 +0100
Subject: [PATCH] Allow always IDN input in dig
@ -37,10 +37,10 @@ Signed-off-by: Petr Menšík <pemensik@redhat.com>
2 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/bin/dig/dig.rst b/bin/dig/dig.rst
index a1d7cfe..85acde1 100644
index d27b1fd..3a9f9c6 100644
--- a/bin/dig/dig.rst
+++ b/bin/dig/dig.rst
@@ -358,9 +358,9 @@ abbreviation is unambiguous; for example, ``+cd`` is equivalent to
@@ -348,9 +348,9 @@ abbreviation is unambiguous; for example, ``+cd`` is equivalent to
This option processes [or does not process] IDN domain names on input. This requires
``IDN SUPPORT`` to have been enabled at compile time.
@ -54,10 +54,10 @@ index a1d7cfe..85acde1 100644
``+[no]idnout``
This option converts [or does not convert] puny code on output. This requires
diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c
index 7e88b6b..fbd5ad9 100644
index ac7e1fb..9555e63 100644
--- a/bin/dig/dighost.c
+++ b/bin/dig/dighost.c
@@ -620,6 +620,9 @@ clone_server_list(dig_serverlist_t src, dig_serverlist_t *dest) {
@@ -622,6 +622,9 @@ clone_server_list(dig_serverlist_t src, dig_serverlist_t *dest) {
dig_lookup_t *
make_empty_lookup(void) {
dig_lookup_t *looknew;
@ -67,7 +67,7 @@ index 7e88b6b..fbd5ad9 100644
debug("make_empty_lookup()");
@@ -671,8 +674,8 @@ make_empty_lookup(void) {
@@ -673,8 +676,8 @@ make_empty_lookup(void) {
looknew->qr = false;
looknew->accept_reply_unexpected_src = false;
#ifdef HAVE_LIBIDN2
@ -78,9 +78,9 @@ index 7e88b6b..fbd5ad9 100644
#else /* ifdef HAVE_LIBIDN2 */
looknew->idnin = false;
looknew->idnout = false;
@@ -4493,8 +4496,16 @@ idn_locale_to_ace(const char *src, char *dst, size_t dstlen) {
*/
res = idn2_to_ascii_lz(src, &ascii_src, IDN2_NONTRANSITIONAL);
@@ -4497,8 +4500,16 @@ idn_locale_to_ace(const char *src, char *dst, size_t dstlen) {
res = idn2_to_ascii_lz(src, &ascii_src, IDN2_TRANSITIONAL);
}
if (res != IDN2_OK) {
- fatal("'%s' is not a legal IDNA2008 name (%s), use +noidnin",
- src, idn2_strerror(res));
@ -98,5 +98,5 @@ index 7e88b6b..fbd5ad9 100644
/*
--
2.50.1
2.51.1

View File

@ -0,0 +1,173 @@
diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c
index ac7e1fb55b..9f1a05ea10 100644
--- a/bin/dig/dighost.c
+++ b/bin/dig/dighost.c
@@ -1571,6 +1571,31 @@ check_if_done(void) {
}
}
+
+/*%
+ * Check if we're done with all the queries in the lookup, except for
+ * the `except_q` query (can be NULL if no exception is required).
+ * Expects `l` to be a valid and locked lookup.
+ */
+static bool
+check_if_queries_done(dig_lookup_t *l, dig_query_t *except_q) {
+ dig_query_t *q = ISC_LIST_HEAD(l->q);
+
+ debug("check_if_queries_done(%p)", l);
+
+ while (q != NULL) {
+ if (!q->started || q->waiting_connect || q->waiting_senddone || q->pending_free) {
+ if (!q->canceled && q != except_q) {
+ debug("there is a pending query %p", q);
+ return (false);
+ }
+ }
+ q = ISC_LIST_NEXT(q, link);
+ }
+
+ return (true);
+}
+
/*%
* Clear out a query when we're done with it. WARNING: This routine
* WILL invalidate the query pointer.
@@ -2557,12 +2582,13 @@ setup_lookup(dig_lookup_t *lookup) {
query->waiting_senddone = false;
query->pending_free = false;
query->recv_made = false;
- query->first_pass = true;
+ query->started = false;
query->first_soa_rcvd = false;
query->second_rr_rcvd = false;
query->first_repeat_rcvd = false;
query->warn_id = true;
query->timedout = false;
+ query->canceled = false;
query->first_rr_serial = 0;
query->second_rr_serial = 0;
query->servname = serv->servername;
@@ -2660,6 +2686,7 @@ cancel_lookup(dig_lookup_t *lookup) {
while (query != NULL) {
REQUIRE(DIG_VALID_QUERY(query));
next = ISC_LIST_NEXT(query, link);
+ query->canceled = true;
if (query->sock != NULL) {
isc_socket_cancel(query->sock, global_task,
ISC_SOCKCANCEL_ALL);
@@ -2902,6 +2929,12 @@ send_udp(dig_query_t *query) {
return;
}
+ query->started = true;
+ if (atomic_load(&cancel_now)) {
+ return;
+ }
+ INSIST(!free_now);
+
result = isc_socket_create(socketmgr,
isc_sockaddr_pf(&query->sockaddr),
isc_sockettype_udp, &query->sock);
@@ -3028,6 +3061,10 @@ connect_timeout(isc_task_t *task, isc_event_t *event) {
clear_query(query);
}
}
+ if (check_if_queries_done(l, query)) {
+ cancel_lookup(l);
+ check_next_lookup(l);
+ }
UNLOCK_LOOKUP;
return;
}
@@ -3283,6 +3320,14 @@ connect_done(isc_task_t *task, isc_event_t *event) {
query = sevent->ev_arg;
REQUIRE(DIG_VALID_QUERY(query));
+ query->started = true;
+
+ if (atomic_load(&cancel_now)) {
+ return;
+ }
+
+ INSIST(!free_now);
+
INSIST(query->waiting_connect);
query->waiting_connect = false;
@@ -4004,6 +4049,9 @@ recv_done(isc_task_t *task, isc_event_t *event) {
: "recursion not available",
query->servname);
clear_query(query);
+ if (check_if_queries_done(l, query)) {
+ cancel_lookup(l);
+ }
check_next_lookup(l);
dns_message_detach(&msg);
isc_event_free(&event);
@@ -4129,7 +4177,12 @@ recv_done(isc_task_t *task, isc_event_t *event) {
l->trace_root = false;
usesearch = false;
} else {
+ /*
+ * This is a query in the followup lookup
+ */
dighost_printmessage(query, &b, msg, true);
+
+ docancel = check_if_queries_done(l, query);
}
}
}
@@ -4309,6 +4362,7 @@ cancel_all(void) {
nq = ISC_LIST_NEXT(q, link);
debug("canceling pending query %p, belonging to %p", q,
current_lookup);
+ q->canceled = true;
if (q->sock != NULL) {
isc_socket_cancel(q->sock, NULL,
ISC_SOCKCANCEL_ALL);
@@ -4322,6 +4376,7 @@ cancel_all(void) {
nq = ISC_LIST_NEXT(q, clink);
debug("canceling connecting query %p, belonging to %p",
q, current_lookup);
+ q->canceled = true;
if (q->sock != NULL) {
isc_socket_cancel(q->sock, NULL,
ISC_SOCKCANCEL_ALL);
diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h
index 8bf9613db3..d7eb49963c 100644
--- a/bin/dig/include/dig/dig.h
+++ b/bin/dig/include/dig/dig.h
@@ -168,9 +168,9 @@ struct dig_lookup {
struct dig_query {
unsigned int magic;
dig_lookup_t *lookup;
- bool waiting_connect, pending_free, waiting_senddone, first_pass,
+ bool waiting_connect, pending_free, waiting_senddone, started,
first_soa_rcvd, second_rr_rcvd, first_repeat_rcvd, recv_made,
- warn_id, timedout;
+ warn_id, timedout, canceled;
uint32_t first_rr_serial;
uint32_t second_rr_serial;
uint32_t msg_count;
diff --git a/bin/tests/system/digdelv/tests.sh b/bin/tests/system/digdelv/tests.sh
index fd7b383608..13044f4102 100644
--- a/bin/tests/system/digdelv/tests.sh
+++ b/bin/tests/system/digdelv/tests.sh
@@ -1040,6 +1040,15 @@ if [ -x "$DIG" ]; then
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
+ # See [GL #3248] for more information
+ n=$((n+1))
+ echo_i "check that dig correctly refuses to use a server with a IPv4 mapped IPv6 address after failing with a regular IP address ($n)"
+ ret=0
+ dig_with_opts +nomapped @10.53.0.8 @::ffff:10.53.0.8 a.example > dig.out.test$n 2>&1 || ret=1
+ grep -F ";; Skipping mapped address" dig.out.test$n > /dev/null || ret=1
+ grep -F ";; No acceptable nameservers" dig.out.test$n > /dev/null || ret=1
+ if [ $ret -ne 0 ]; then echo_i "failed"; fi
+ status=$((status+ret))
else
echo_i "$DIG is needed, so skipping these dig tests"
fi

View File

@ -0,0 +1,31 @@
From e4b0698dc5e98b951050299c28be94514427688b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Tue, 18 Jun 2024 08:56:18 +0200
Subject: [PATCH] Use LC_ALL to override all system locales
The system tests were overriding the local locale by setting LANG to C.
This does not override the locale in case there are individual LC_<*>
variables like LC_CTYPE explicitly set.
Use LC_ALL=C instead which is the proper way of overriding all currently
set locales.
---
bin/tests/system/conf.sh.common | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bin/tests/system/conf.sh.common b/bin/tests/system/conf.sh.common
index a91c0d9f4e..2b0bc20896 100644
--- a/bin/tests/system/conf.sh.common
+++ b/bin/tests/system/conf.sh.common
@@ -20,7 +20,7 @@ testsock6() {
fi
}
-export LANG=C
+export LC_ALL=C
. ${TOP}/version
--
2.53.0

View File

@ -0,0 +1,97 @@
diff --git a/lib/dns/keymgr.c b/lib/dns/keymgr.c
index 6c04682004..8eda1535a0 100644
--- a/lib/dns/keymgr.c
+++ b/lib/dns/keymgr.c
@@ -1154,19 +1154,18 @@ static bool
keymgr_transition_allowed(dns_dnsseckeylist_t *keyring, dns_dnsseckey_t *key,
int type, dst_key_state_t next_state,
bool secure_to_insecure) {
+ bool rule1a, rule1b, rule2a, rule2b, rule3a, rule3b;
+ rule1a = keymgr_have_ds(keyring, key, type, NA, secure_to_insecure);
+ rule1b = keymgr_have_ds(keyring, key, type, next_state, secure_to_insecure);
+ rule2a = keymgr_have_dnskey(keyring, key, type, NA);
+ rule2b = keymgr_have_dnskey(keyring, key, type, next_state);
+ rule3a = keymgr_have_rrsig(keyring, key, type, NA);
+ rule3b = keymgr_have_rrsig(keyring, key, type, next_state);
+
/* Debug logging. */
if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(1))) {
- bool rule1a, rule1b, rule2a, rule2b, rule3a, rule3b;
char keystr[DST_KEY_FORMATSIZE];
dst_key_format(key->key, keystr, sizeof(keystr));
- rule1a = keymgr_have_ds(keyring, key, type, NA,
- secure_to_insecure);
- rule1b = keymgr_have_ds(keyring, key, type, next_state,
- secure_to_insecure);
- rule2a = keymgr_have_dnskey(keyring, key, type, NA);
- rule2b = keymgr_have_dnskey(keyring, key, type, next_state);
- rule3a = keymgr_have_rrsig(keyring, key, type, NA);
- rule3b = keymgr_have_rrsig(keyring, key, type, next_state);
isc_log_write(
dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_DNSSEC,
ISC_LOG_DEBUG(1),
@@ -1179,30 +1178,40 @@ keymgr_transition_allowed(dns_dnsseckeylist_t *keyring, dns_dnsseckey_t *key,
rule3a ? "true" : "false", rule3b ? "true" : "false");
}
- return (
- /*
- * Rule 1: There must be a DS at all times.
- * First check the current situation: if the rule check fails,
- * we allow the transition to attempt to move us out of the
- * invalid state. If the rule check passes, also check if
- * the next state is also still a valid situation.
- */
- (!keymgr_have_ds(keyring, key, type, NA, secure_to_insecure) ||
- keymgr_have_ds(keyring, key, type, next_state,
- secure_to_insecure)) &&
- /*
- * Rule 2: There must be a DNSKEY at all times. Again, first
- * check the current situation, then assess the next state.
- */
- (!keymgr_have_dnskey(keyring, key, type, NA) ||
- keymgr_have_dnskey(keyring, key, type, next_state)) &&
- /*
- * Rule 3: There must be RRSIG records at all times. Again,
- * first check the current situation, then assess the next
- * state.
- */
- (!keymgr_have_rrsig(keyring, key, type, NA) ||
- keymgr_have_rrsig(keyring, key, type, next_state)));
+ /*
+ * Rule checking:
+ * First check the current situation: if the rule check fails,
+ * we allow the transition to attempt to move us out of the
+ * invalid state. If the rule check passes, also check if
+ * the next state is also still a valid situation.
+ */
+ char keystr2[DST_KEY_FORMATSIZE];
+ dst_key_format(key->key, keystr2, sizeof(keystr2));
+
+ /*
+ * Rule 1: There must be a DS at all times.
+ */
+ if (!rule1a && !rule1b && next_state == UNRETENTIVE) {
+ return false;
+ }
+ /*
+ * Rule 2: There must be a DNSKEY at all times. Again, first
+ * check the current situation, then assess the next state.
+ */
+ if (!rule2a && !rule2b && next_state == UNRETENTIVE) {
+ return false;
+ }
+ /*
+ * Rule 3: There must be RRSIG records at all times. Again,
+ * first check the current situation, then assess the next
+ * state.
+ */
+ if (!rule3a && !rule3b && next_state == UNRETENTIVE) {
+ return false;
+ }
+
+ return (!rule1a || rule1b) && (!rule2a || rule2b) &&
+ (!rule3a || rule3b);
}
/*

View File

@ -0,0 +1,92 @@
diff --git a/bin/tests/system/serve-stale/ns1/stale.test.db b/bin/tests/system/serve-stale/ns1/stale.test.db
index d389e7c6a6..128fb25a10 100644
--- a/bin/tests/system/serve-stale/ns1/stale.test.db
+++ b/bin/tests/system/serve-stale/ns1/stale.test.db
@@ -17,3 +17,11 @@ cname1.stale.test. 1 CNAME a1.stale.test.
a1.stale.test. 1 A 192.0.2.1
cname2.stale.test. 1 CNAME a2.stale.test.
a2.stale.test. 300 A 192.0.2.2
+
+cname-a1 1 CNAME cname-a2
+cname-a2 300 CNAME cname-a3
+cname-a3 300 A 192.0.2.1
+
+cname-b1 300 CNAME cname-b2
+cname-b2 1 CNAME cname-b3
+cname-b3 1 A 192.0.2.2
diff --git a/bin/tests/system/serve-stale/tests.sh b/bin/tests/system/serve-stale/tests.sh
index 0ae32f22c1..925e5086eb 100755
--- a/bin/tests/system/serve-stale/tests.sh
+++ b/bin/tests/system/serve-stale/tests.sh
@@ -2163,6 +2163,71 @@ if [ $ret != 0 ]; then
fi
status=$((status + ret))
+# New CNAME scenario (GL #5243)
+n=$((n + 1))
+echo_i "prime cache cname-a1.stale.test A (stale-answer-client-timeout 0) ($n)"
+ret=0
+$DIG -p ${PORT} @10.53.0.3 cname-a1.stale.test A >dig.out.test$n || ret=1
+grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
+grep "ANSWER: 3," dig.out.test$n >/dev/null || ret=1
+grep "cname-a1\.stale\.test\..*1.*IN.*CNAME.*cname-a2\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-a2\.stale\.test\..*300.*IN.*CNAME.*cname-a3\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-a3\.stale\.test\..*300.*IN.*A.*192\.0\.2\.1" dig.out.test$n >/dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+
+n=$((n + 1))
+echo_i "prime cache cname-b1.stale.test A (stale-answer-client-timeout 0) ($n)"
+ret=0
+$DIG -p ${PORT} @10.53.0.3 cname-b1.stale.test A >dig.out.test$n || ret=1
+grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
+grep "ANSWER: 3," dig.out.test$n >/dev/null || ret=1
+grep "cname-b1\.stale\.test\..*300.*IN.*CNAME.*cname-b2\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-b2\.stale\.test\..*1.*IN.*CNAME.*cname-b3\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-b3\.stale\.test\..*1.*IN.*A.*192\.0\.2\.2" dig.out.test$n >/dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+
+# Allow RRset to become stale.
+sleep 1
+
+n=$((n + 1))
+ret=0
+echo_i "check stale cname-a1.stale.test A comes from cache (stale-answer-client-timeout 0) ($n)"
+nextpart ns3/named.run >/dev/null
+$DIG -p ${PORT} @10.53.0.3 cname-a1.stale.test A >dig.out.test$n || ret=1
+wait_for_log 5 "cname-a1.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
+# Other records in chain are still good, so do not attempt a refresh
+grep "cname-a2.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run && ret=1
+grep "cname-a3.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run && ret=1
+# Check answer
+grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
+grep "ANSWER: 3," dig.out.test$n >/dev/null || ret=1
+grep "cname-a1\.stale\.test\..*3.*IN.*CNAME.*cname-a2\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-a2\.stale\.test\..*29[0-9].*IN.*CNAME.*cname-a3\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-a3\.stale\.test\..*29[0-9].*IN.*A.*192\.0\.2\.1" dig.out.test$n >/dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+
+n=$((n + 1))
+ret=0
+echo_i "check stale cname-b1.stale.test A comes from cache (stale-answer-client-timeout 0) ($n)"
+nextpart ns3/named.run >/dev/null
+$DIG -p ${PORT} @10.53.0.3 cname-b1.stale.test A >dig.out.test$n || ret=1
+wait_for_log 5 "cname-b2.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
+# The next one in the chain (cname-b3.stale.test) is likely not logged because
+# there is already a refresh in progress. And the first record in the chain is
+# still good, so do not attempt a refresh.
+grep "cname-b1.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run && ret=1
+# Check answer
+grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
+grep "ANSWER: 3," dig.out.test$n >/dev/null || ret=1
+grep "cname-b1\.stale\.test\..*29[0-9].*IN.*CNAME.*cname-b2\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-b2\.stale\.test\..*3.*IN.*CNAME.*cname-b3\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-b3\.stale\.test\..*3.*IN.*A.*192\.0\.2\.2" dig.out.test$n >/dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+
####################################################################
# Test for stale-answer-client-timeout 0 and stale-refresh-time 4. #
####################################################################

View File

@ -0,0 +1,707 @@
diff --git a/bin/tests/system/serve-stale/tests.sh b/bin/tests/system/serve-stale/tests.sh
index d767769ad8..0ae32f22c1 100755
--- a/bin/tests/system/serve-stale/tests.sh
+++ b/bin/tests/system/serve-stale/tests.sh
@@ -1965,7 +1965,7 @@ ret=0
echo_i "check stale nodata.example TXT comes from cache (stale-answer-client-timeout 0) ($n)"
nextpart ns3/named.run >/dev/null
$DIG -p ${PORT} @10.53.0.3 nodata.example TXT >dig.out.test$n || ret=1
-wait_for_log 5 "nodata.example stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
+wait_for_log 5 "nodata.example TXT stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
grep "example\..*3.*IN.*SOA" dig.out.test$n >/dev/null || ret=1
@@ -1977,7 +1977,7 @@ ret=0
echo_i "check stale data.example TXT comes from cache (stale-answer-client-timeout 0) ($n)"
nextpart ns3/named.run >/dev/null
$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
-wait_for_log 5 "data.example stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
+wait_for_log 5 "data.example TXT stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
@@ -2105,7 +2105,7 @@ ret=0
echo_i "check stale cname1.stale.test A comes from cache (stale-answer-client-timeout 0) ($n)"
nextpart ns3/named.run >/dev/null
$DIG -p ${PORT} @10.53.0.3 cname1.stale.test A >dig.out.test$n || ret=1
-wait_for_log 5 "cname1.stale.test stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
+wait_for_log 5 "cname1.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
grep "ANSWER: 2," dig.out.test$n >/dev/null || ret=1
grep "cname1\.stale\.test\..*3.*IN.*CNAME.*a1\.stale\.test\." dig.out.test$n >/dev/null || ret=1
@@ -2143,7 +2143,7 @@ ret=0
echo_i "check stale cname2.stale.test A comes from cache (stale-answer-client-timeout 0) ($n)"
nextpart ns3/named.run >/dev/null
$DIG -p ${PORT} @10.53.0.3 cname2.stale.test A >dig.out.test$n || ret=1
-wait_for_log 5 "cname2.stale.test stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
+wait_for_log 5 "cname2.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
grep "ANSWER: 2," dig.out.test$n >/dev/null || ret=1
grep "cname2\.stale\.test\..*3.*IN.*CNAME.*a2\.stale\.test\." dig.out.test$n >/dev/null || ret=1
@@ -2219,7 +2219,7 @@ ret=0
echo_i "check stale data.example TXT comes from cache (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)"
nextpart ns3/named.run >/dev/null
$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
-wait_for_log 5 "data.example stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
+wait_for_log 5 "data.example TXT stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
@@ -2262,7 +2262,7 @@ ret=0
echo_i "check stale data.example TXT comes from cache (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)"
nextpart ns3/named.run >/dev/null
$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
-wait_for_log 5 "data.example stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
+wait_for_log 5 "data.example TXT stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
@@ -2273,7 +2273,7 @@ status=$((status + ret))
n=$((n + 1))
ret=0
echo_i "wait until resolver query times out, activating stale-refresh-time"
-wait_for_log 15 "data.example resolver failure, stale answer used" ns3/named.run || ret=1
+wait_for_log 15 "data.example/TXT stale refresh failed: timed out" ns3/named.run || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
@@ -2322,7 +2322,7 @@ n=$((n + 1))
ret=0
echo_i "check stale data.example TXT comes from cache (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)"
$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
-wait_for_log 5 "data.example stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
+wait_for_log 5 "data.example TXT stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h
index de3f638f89..38d1d65ed2 100644
--- a/lib/dns/include/dns/rdataset.h
+++ b/lib/dns/include/dns/rdataset.h
@@ -193,7 +193,7 @@ struct dns_rdataset {
#define DNS_RDATASETATTR_STALE 0x01000000
#define DNS_RDATASETATTR_ANCIENT 0x02000000
#define DNS_RDATASETATTR_STALE_WINDOW 0x04000000
-#define DNS_RDATASETATTR_STALE_ADDED 0x08000000
+#define DNS_RDATASETATTR_KEEPCASE 0x10000000
/*%
* _OMITDNSSEC:
diff --git a/lib/ns/include/ns/client.h b/lib/ns/include/ns/client.h
index d1e2fde407..a50332e656 100644
--- a/lib/ns/include/ns/client.h
+++ b/lib/ns/include/ns/client.h
@@ -192,6 +192,7 @@ struct ns_client {
(query, update, notify) */
isc_nmhandle_t *fetchhandle; /* Waiting for recursive fetch */
isc_nmhandle_t *prefetchhandle; /* Waiting for prefetch / rpzfetch */
+ isc_nmhandle_t *stalerefreshhandle;
isc_nmhandle_t *updatehandle; /* Waiting for update callback */
unsigned char *tcpbuf;
dns_message_t *message;
diff --git a/lib/ns/include/ns/query.h b/lib/ns/include/ns/query.h
index be0dadd509..9c96c45138 100644
--- a/lib/ns/include/ns/query.h
+++ b/lib/ns/include/ns/query.h
@@ -68,6 +68,7 @@ struct ns_query {
isc_mutex_t fetchlock;
dns_fetch_t *fetch;
dns_fetch_t *prefetch;
+ dns_fetch_t *stalerefresh;
dns_rpz_st_t *rpz_st;
isc_bufferlist_t namebufs;
ISC_LIST(ns_dbversion_t) activeversions;
@@ -118,7 +119,6 @@ struct ns_query {
#define NS_QUERYATTR_RRL_CHECKED 0x010000
#define NS_QUERYATTR_REDIRECT 0x020000
#define NS_QUERYATTR_ANSWERED 0x040000
-#define NS_QUERYATTR_STALEOK 0x080000
#define NS_QUERYATTR_STALEPENDING 0x100000
typedef struct query_ctx query_ctx_t;
@@ -147,7 +147,6 @@ struct query_ctx {
bool authoritative; /* authoritative query? */
bool want_restart; /* CNAME chain or other
* restart needed */
- bool refresh_rrset; /* stale RRset refresh needed */
bool need_wildcardproof; /* wildcard proof needed */
bool nxrewrite; /* negative answer from RPZ */
bool findcoveringnsec; /* lookup covering NSEC */
diff --git a/lib/ns/query.c b/lib/ns/query.c
index 1290c308af..4ea63caf37 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -142,9 +142,6 @@
#define QUERY_STALEPENDING(q) \
(((q)->attributes & NS_QUERYATTR_STALEPENDING) != 0)
-/*% Does the query allow stale data in the response? */
-#define QUERY_STALEOK(q) (((q)->attributes & NS_QUERYATTR_STALEOK) != 0)
-
/*% Does the query wants to check for stale RRset due to a timeout? */
#define QUERY_STALETIMEOUT(q) (((q)->dboptions & DNS_DBFIND_STALETIMEOUT) != 0)
@@ -242,6 +239,15 @@ static void
log_noexistnodata(void *val, int level, const char *fmt, ...)
ISC_FORMAT_PRINTF(3, 4);
+static isc_result_t
+qctx_prepare_buffers(query_ctx_t *qctx, isc_buffer_t *buffer);
+
+static void
+qctx_freedata(query_ctx_t *qctx);
+
+static void
+qctx_destroy(query_ctx_t *qctx);
+
/*
* Return the hooktable in use with 'qctx', or if there isn't one
* set, return the default hooktable.
@@ -497,9 +503,6 @@ query_addwildcardproof(query_ctx_t *qctx, bool ispositive, bool nodata);
static void
query_addauth(query_ctx_t *qctx);
-static void
-query_clear_stale(ns_client_t *client);
-
/*
* Increment query statistics counters.
*/
@@ -801,6 +804,7 @@ ns_query_init(ns_client_t *client) {
client->query.fetch = NULL;
client->query.prefetch = NULL;
+ client->query.stalerefresh = NULL;
client->query.authdb = NULL;
client->query.authzone = NULL;
client->query.authdbset = false;
@@ -2186,10 +2190,6 @@ query_addrrset(query_ctx_t *qctx, dns_name_t **namep,
if ((rdataset->attributes & DNS_RDATASETATTR_REQUIRED) != 0) {
mrdataset->attributes |= DNS_RDATASETATTR_REQUIRED;
}
- if ((rdataset->attributes & DNS_RDATASETATTR_STALE_ADDED) != 0)
- {
- mrdataset->attributes |= DNS_RDATASETATTR_STALE_ADDED;
- }
return;
} else if (result == DNS_R_NXDOMAIN) {
/*
@@ -2475,6 +2475,85 @@ free_devent(ns_client_t *client, isc_event_t **eventp,
isc_event_free(eventp);
}
+static void
+stale_refresh_aftermath(ns_client_t *client, isc_result_t result) {
+ dns_db_t *db = NULL;
+ unsigned int dboptions;
+ isc_buffer_t buffer;
+ query_ctx_t qctx;
+ dns_clientinfomethods_t cm;
+ dns_clientinfo_t ci;
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char typebuf[DNS_RDATATYPE_FORMATSIZE];
+
+ /*
+ * If refreshing a stale RRset failed, we need to set the
+ * stale-refresh-time window, so that on future requests for this
+ * RRset the stale entry may be used immediately.
+ */
+ switch (result) {
+ case ISC_R_SUCCESS:
+ case DNS_R_GLUE:
+ case DNS_R_ZONECUT:
+ case ISC_R_NOTFOUND:
+ case DNS_R_DELEGATION:
+ case DNS_R_EMPTYNAME:
+ case DNS_R_NXRRSET:
+ case DNS_R_EMPTYWILD:
+ case DNS_R_NXDOMAIN:
+ case DNS_R_COVERINGNSEC:
+ case DNS_R_NCACHENXDOMAIN:
+ case DNS_R_NCACHENXRRSET:
+ case DNS_R_CNAME:
+ case DNS_R_DNAME:
+ break;
+ default:
+ dns_name_format(client->query.qname, namebuf, sizeof(namebuf));
+ dns_rdatatype_format(client->query.qtype, typebuf,
+ sizeof(typebuf));
+ ns_client_log(client, NS_LOGCATEGORY_SERVE_STALE,
+ NS_LOGMODULE_QUERY, ISC_LOG_NOTICE,
+ "%s/%s stale refresh failed: timed out", namebuf,
+ typebuf);
+
+ /*
+ * Set up a short lived query context, solely to set the
+ * last refresh failure time on the RRset in the cache
+ * database, starting the stale-refresh-time window for it.
+ * This is a condensed form of query_lookup().
+ */
+ isc_stdtime_get(&client->now);
+ client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK;
+ qctx_init(client, NULL, 0, &qctx);
+
+ dns_clientinfomethods_init(&cm, ns_client_sourceip);
+ dns_clientinfo_init(&ci, qctx.client, HAVEECS(qctx.client) ? &qctx.client->ecs : NULL, NULL);
+
+ result = qctx_prepare_buffers(&qctx, &buffer);
+ if (result != ISC_R_SUCCESS) {
+ goto cleanup;
+ }
+
+ dboptions = qctx.client->query.dboptions;
+ dboptions |= DNS_DBFIND_STALEOK;
+ dboptions |= DNS_DBFIND_STALESTART;
+
+ dns_db_attach(qctx.client->view->cachedb, &db);
+ (void)dns_db_findext(db, qctx.client->query.qname, NULL,
+ qctx.client->query.qtype, dboptions,
+ qctx.client->now, &qctx.node, qctx.fname,
+ &cm, &ci, qctx.rdataset, qctx.sigrdataset);
+ if (qctx.node != NULL) {
+ dns_db_detachnode(db, &qctx.node);
+ }
+ dns_db_detach(&db);
+
+ cleanup:
+ qctx_freedata(&qctx);
+ qctx_destroy(&qctx);
+ }
+}
+
static void
prefetch_done(isc_task_t *task, isc_event_t *event) {
dns_fetchevent_t *devent = (dns_fetchevent_t *)event;
@@ -2509,6 +2588,133 @@ prefetch_done(isc_task_t *task, isc_event_t *event) {
isc_nmhandle_detach(&client->prefetchhandle);
}
+static void
+refresh_done(isc_task_t *task, isc_event_t *event) {
+ dns_fetchevent_t *devent = (dns_fetchevent_t *)event;
+ ns_client_t *client;
+
+ UNUSED(task);
+
+ REQUIRE(event->ev_type == DNS_EVENT_FETCHDONE);
+ client = devent->ev_arg;
+ REQUIRE(NS_CLIENT_VALID(client));
+ REQUIRE(task == client->task);
+
+ CTRACE(ISC_LOG_DEBUG(3), "refresh_done");
+
+ LOCK(&client->query.fetchlock);
+ if (client->query.stalerefresh != NULL) {
+ INSIST(devent->fetch == client->query.stalerefresh);
+ client->query.stalerefresh = NULL;
+ }
+ UNLOCK(&client->query.fetchlock);
+
+ stale_refresh_aftermath(client, devent->result);
+
+ if (client->recursionquota != NULL) {
+ isc_quota_detach(&client->recursionquota);
+ ns_stats_decrement(client->sctx->nsstats,
+ ns_statscounter_recursclients);
+ }
+
+ free_devent(client, &event, &devent);
+ isc_nmhandle_detach(&client->stalerefreshhandle);
+}
+
+static void
+query_stale_refresh(ns_client_t *client, dns_name_t *qname,
+ dns_rdataset_t *rdataset) {
+ isc_result_t result;
+ isc_sockaddr_t *peeraddr;
+ dns_rdataset_t *tmprdataset;
+ unsigned int options;
+
+ CTRACE(ISC_LOG_DEBUG(3), "query_stale_refresh");
+
+ bool stale_refresh_window = false;
+ bool stale_rrset = true;
+
+ if (rdataset != NULL) {
+ stale_refresh_window =
+ (STALE_WINDOW(rdataset) &&
+ (client->query.dboptions & DNS_DBFIND_STALEENABLED) != 0);
+ stale_rrset = STALE(rdataset);
+ }
+
+ if (client->query.stalerefresh != NULL ||
+ (client->query.dboptions & DNS_DBFIND_STALETIMEOUT) == 0 ||
+ !stale_rrset || stale_refresh_window)
+ {
+ return;
+ }
+
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char typebuf[DNS_RDATATYPE_FORMATSIZE];
+ dns_name_format(qname, namebuf, sizeof(namebuf));
+ dns_rdatatype_format(client->query.qtype, typebuf, sizeof(typebuf));
+ isc_log_write(ns_lctx, NS_LOGCATEGORY_SERVE_STALE, NS_LOGMODULE_QUERY,
+ ISC_LOG_INFO,
+ "%s %s stale answer used, an attempt "
+ "to refresh the RRset will still be "
+ "made",
+ namebuf, typebuf);
+
+ client->query.dboptions &= ~(DNS_DBFIND_STALETIMEOUT |
+ DNS_DBFIND_STALEOK |
+ DNS_DBFIND_STALEENABLED);
+
+ if (client->recursionquota == NULL) {
+ result = isc_quota_attach(&client->sctx->recursionquota,
+ &client->recursionquota);
+ switch (result) {
+ case ISC_R_SUCCESS:
+ ns_stats_increment(client->sctx->nsstats,
+ ns_statscounter_recursclients);
+ break;
+ case ISC_R_SOFTQUOTA:
+ isc_quota_detach(&client->recursionquota);
+ FALLTHROUGH;
+ default:
+ return;
+ }
+ }
+
+ tmprdataset = ns_client_newrdataset(client);
+ if (tmprdataset == NULL) {
+ return;
+ }
+
+ if (!TCP(client)) {
+ peeraddr = &client->peeraddr;
+ } else {
+ peeraddr = NULL;
+ }
+
+ isc_nmhandle_attach(client->handle, &client->stalerefreshhandle);
+ options = client->query.fetchoptions;
+ result = dns_resolver_createfetch(
+ client->view->resolver, qname, client->query.qtype, NULL, NULL, NULL,
+ peeraddr, client->message->id, options, 0, NULL, client->task,
+ refresh_done, client, tmprdataset, NULL,
+ &client->query.stalerefresh);
+ if (result != ISC_R_SUCCESS) {
+ ns_client_putrdataset(client, &tmprdataset);
+ isc_nmhandle_detach(&client->stalerefreshhandle);
+ }
+}
+
+static void
+query_stale_refresh_ncache(ns_client_t *client) {
+ dns_name_t *qname;
+
+ if (client->query.origqname != NULL) {
+ qname = client->query.origqname;
+ } else {
+ qname = client->query.qname;
+ }
+ query_stale_refresh(client, qname, NULL);
+}
+
static void
query_prefetch(ns_client_t *client, dns_name_t *qname,
dns_rdataset_t *rdataset) {
@@ -2524,6 +2730,7 @@ query_prefetch(ns_client_t *client, dns_name_t *qname,
rdataset->ttl > client->view->prefetch_trigger ||
(rdataset->attributes & DNS_RDATASETATTR_PREFETCH) == 0)
{
+ query_stale_refresh(client, qname, rdataset);
return;
}
@@ -2568,6 +2775,7 @@ query_prefetch(ns_client_t *client, dns_name_t *qname,
dns_rdataset_clearprefetch(rdataset);
ns_stats_increment(client->sctx->nsstats, ns_statscounter_prefetch);
+ return;
}
static void
@@ -5696,55 +5904,6 @@ error:
return (ISC_R_NOMEMORY);
}
-/*
- * Setup a new query context for resolving a query.
- *
- * This function is only called if both these conditions are met:
- * 1. BIND is configured with stale-answer-client-timeout 0.
- * 2. A stale RRset is found in cache during initial query
- * database lookup.
- *
- * We continue with this function for refreshing/resolving an RRset
- * after answering a client with stale data.
- */
-static void
-query_refresh_rrset(query_ctx_t *orig_qctx) {
- isc_buffer_t buffer;
- query_ctx_t qctx;
-
- REQUIRE(orig_qctx != NULL);
- REQUIRE(orig_qctx->client != NULL);
-
- qctx_copy(orig_qctx, &qctx);
- qctx.client->query.dboptions &= ~(DNS_DBFIND_STALETIMEOUT |
- DNS_DBFIND_STALEOK |
- DNS_DBFIND_STALEENABLED);
- qctx.client->nodetach = false;
-
- /*
- * We'll need some resources...
- */
- if (qctx_prepare_buffers(&qctx, &buffer) != ISC_R_SUCCESS) {
- dns_db_detach(&qctx.db);
- qctx_destroy(&qctx);
- return;
- }
-
- /*
- * Pretend we didn't find anything in cache.
- */
- (void)query_gotanswer(&qctx, ISC_R_NOTFOUND);
-
- if (qctx.fname != NULL) {
- ns_client_releasename(qctx.client, &qctx.fname);
- }
- if (qctx.rdataset != NULL) {
- ns_client_putrdataset(qctx.client, &qctx.rdataset);
- }
-
- qctx_destroy(&qctx);
-}
-
/*%
* Depending on the db lookup result, we can respond to the
* client this stale answer.
@@ -5814,7 +5973,7 @@ query_lookup(query_ctx_t *qctx) {
rpzqname = qctx->client->query.qname;
}
- if ((qctx->options & DNS_GETDB_STALEFIRST) != 0) {
+ if ((qctx->options & DNS_GETDB_STALEFIRST) != 0 && !qctx->is_zone) {
/*
* If DNS_GETDB_STALEFIRST is set, it means that a stale
* RRset may be returned as part of this lookup. An attempt
@@ -5824,19 +5983,19 @@ query_lookup(query_ctx_t *qctx) {
qctx->client->query.dboptions |= DNS_DBFIND_STALETIMEOUT;
}
- dboptions = qctx->client->query.dboptions;
- if (!qctx->is_zone && qctx->findcoveringnsec &&
- (qctx->type != dns_rdatatype_null || !dns_name_istat(rpzqname)))
- {
- dboptions |= DNS_DBFIND_COVERINGNSEC;
- }
-
(void)dns_db_getservestalerefresh(qctx->client->view->cachedb,
&stale_refresh);
if (stale_refresh > 0 &&
dns_view_staleanswerenabled(qctx->client->view))
{
- dboptions |= DNS_DBFIND_STALEENABLED;
+ qctx->client->query.dboptions |= DNS_DBFIND_STALEENABLED;
+ }
+
+ dboptions = qctx->client->query.dboptions;
+ if (!qctx->is_zone && qctx->findcoveringnsec &&
+ (qctx->type != dns_rdatatype_null || !dns_name_istat(rpzqname)))
+ {
+ dboptions |= DNS_DBFIND_COVERINGNSEC;
}
result = dns_db_findext(qctx->db, rpzqname, qctx->version, qctx->type,
@@ -5971,20 +6130,7 @@ query_lookup(query_ctx_t *qctx) {
* Immediately return the stale answer, start a
* resolver fetch to refresh the data in cache.
*/
- isc_log_write(
- ns_lctx, NS_LOGCATEGORY_SERVE_STALE,
- NS_LOGMODULE_QUERY, ISC_LOG_INFO,
- "%s stale answer used, an attempt to "
- "refresh the RRset will still be made",
- namebuf);
-
- qctx->refresh_rrset = STALE(qctx->rdataset);
-
- /*
- * If we are refreshing the RRSet, we must not
- * detach from the client in query_send().
- */
- qctx->client->nodetach = qctx->refresh_rrset;
+ qctx->client->nodetach = false;
}
} else {
/*
@@ -6014,76 +6160,12 @@ query_lookup(query_ctx_t *qctx) {
}
}
- if (stale_timeout && (answer_found || stale_found)) {
- /*
- * Mark RRsets that we are adding to the client message on a
- * lookup during 'stale-answer-client-timeout', so we can
- * clean it up if needed when we resume from recursion.
- */
- qctx->client->query.attributes |= NS_QUERYATTR_STALEOK;
- qctx->rdataset->attributes |= DNS_RDATASETATTR_STALE_ADDED;
- }
-
result = query_gotanswer(qctx, result);
cleanup:
return (result);
}
-/*
- * Clear all rdatasets from the message that are in the given section and
- * that have the 'attr' attribute set.
- */
-static void
-message_clearrdataset(dns_message_t *msg, unsigned int attr) {
- unsigned int i;
- dns_name_t *name, *next_name;
- dns_rdataset_t *rds, *next_rds;
-
- /*
- * Clean up name lists by calling the rdataset disassociate function.
- */
- for (i = DNS_SECTION_ANSWER; i < DNS_SECTION_MAX; i++) {
- name = ISC_LIST_HEAD(msg->sections[i]);
- while (name != NULL) {
- next_name = ISC_LIST_NEXT(name, link);
-
- rds = ISC_LIST_HEAD(name->list);
- while (rds != NULL) {
- next_rds = ISC_LIST_NEXT(rds, link);
- if ((rds->attributes & attr) != attr) {
- rds = next_rds;
- continue;
- }
- ISC_LIST_UNLINK(name->list, rds, link);
- INSIST(dns_rdataset_isassociated(rds));
- dns_rdataset_disassociate(rds);
- isc_mempool_put(msg->rdspool, rds);
- rds = next_rds;
- }
-
- if (ISC_LIST_EMPTY(name->list)) {
- ISC_LIST_UNLINK(msg->sections[i], name, link);
- if (dns_name_dynamic(name)) {
- dns_name_free(name, msg->mctx);
- }
- isc_mempool_put(msg->namepool, name);
- }
-
- name = next_name;
- }
- }
-}
-
-/*
- * Clear any rdatasets from the client's message that were added on a lookup
- * due to a client timeout.
- */
-static void
-query_clear_stale(ns_client_t *client) {
- message_clearrdataset(client->message, DNS_RDATASETATTR_STALE_ADDED);
-}
-
/*
* Create a new query context with the sole intent of looking up for a stale
* RRset in cache. If an entry is found, we mark the original query as
@@ -6163,6 +6245,7 @@ fetch_callback(isc_task_t *task, isc_event_t *event) {
}
client->query.fetchoptions &= ~DNS_FETCHOPT_TRYSTALE_ONTIMEOUT;
client->query.dboptions &= ~DNS_DBFIND_STALETIMEOUT;
+ client->query.dboptions &= ~DNS_DBFIND_STALEENABLED;
client->nodetach = false;
LOCK(&client->query.fetchlock);
@@ -7303,14 +7386,6 @@ query_usestale(query_ctx_t *qctx, isc_result_t result) {
return (false);
}
- if (qctx->refresh_rrset) {
- /*
- * This is a refreshing query, we have already prioritized
- * stale data, so don't enable serve-stale again.
- */
- return (false);
- }
-
if (result == DNS_R_DUPLICATE || result == DNS_R_DROP ||
result == ISC_R_ALREADYRUNNING)
{
@@ -7842,24 +7917,6 @@ query_addanswer(query_ctx_t *qctx) {
CALL_HOOK(NS_QUERY_ADDANSWER_BEGIN, qctx);
- /*
- * On normal lookups, clear any rdatasets that were added on a
- * lookup due to stale-answer-client-timeout. Do not clear if we
- * are going to refresh the RRset, because the stale contents are
- * prioritized.
- */
- if (QUERY_STALEOK(&qctx->client->query) &&
- !QUERY_STALETIMEOUT(&qctx->client->query) && !qctx->refresh_rrset)
- {
- CCTRACE(ISC_LOG_DEBUG(3), "query_clear_stale");
- query_clear_stale(qctx->client);
- /*
- * We can clear the attribute to prevent redundant clearing
- * in subsequent lookups.
- */
- qctx->client->query.attributes &= ~NS_QUERYATTR_STALEOK;
- }
-
if (qctx->dns64) {
result = query_dns64(qctx);
qctx->noqname = NULL;
@@ -7893,9 +7950,7 @@ query_addanswer(query_ctx_t *qctx) {
query_filter64(qctx);
ns_client_putrdataset(qctx->client, &qctx->rdataset);
} else {
- if (!qctx->is_zone && RECURSIONOK(qctx->client) &&
- !QUERY_STALETIMEOUT(&qctx->client->query))
- {
+ if (!qctx->is_zone && RECURSIONOK(qctx->client)) {
query_prefetch(qctx->client, qctx->fname,
qctx->rdataset);
}
@@ -10138,6 +10193,10 @@ query_ncache(query_ctx_t *qctx, isc_result_t result) {
}
}
+ if (!qctx->is_zone && RECURSIONOK(qctx->client)) {
+ query_stale_refresh_ncache(qctx->client);
+ }
+
return (query_nodata(qctx, result));
cleanup:
@@ -11589,20 +11648,6 @@ ns_query_done(query_ctx_t *qctx) {
nodetach = qctx->client->nodetach;
query_send(qctx->client);
- if (qctx->refresh_rrset) {
- /*
- * If we reached this point then it means that we have found a
- * stale RRset entry in cache and BIND is configured to allow
- * queries to be answered with stale data if no active RRset
- * is available, i.e. "stale-anwer-client-timeout 0". But, we
- * still need to refresh the RRset. To prevent adding duplicate
- * RRsets, clear the RRsets from the message before doing the
- * refresh.
- */
- message_clearrdataset(qctx->client->message, 0);
- query_refresh_rrset(qctx);
- }
-
if (!nodetach) {
qctx->detach_client = true;
}

View File

@ -1,534 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
=fX+D
-----END PGP PUBLIC KEY BLOCK-----
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
4xcYgqlVpv15O7VrD+I=
=Uugw
-----END PGP PUBLIC KEY BLOCK-----

175
SOURCES/isc-keyblock.asc Normal file
View File

@ -0,0 +1,175 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
=NX7P
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -53,8 +53,8 @@
Summary: The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) server
Name: bind
License: MPLv2.0
Version: 9.16.23
Release: 40%{?dist}
Version: 9.16.50
Release: 5%{?dist}
Epoch: 32
Url: https://www.isc.org/downloads/bind/
#
@ -62,7 +62,7 @@ Source0: https://downloads.isc.org/isc/bind9/%{version}/bind-%{version}.tar.xz
Source1: named.sysconfig
Source2: https://downloads.isc.org/isc/bind9/%{version}/bind-%{version}.tar.xz.asc
Source3: named.logrotate
Source4: https://downloads.isc.org/isc/pgpkeys/codesign2021.txt
Source4: https://www.isc.org/docs/isc-keyblock.asc
Source16: named.conf
# Refresh by command: dig @a.root-servers.net. +tcp +norec
# or from URL
@ -100,64 +100,13 @@ Patch135:bind-9.14-config-pkcs11.patch
# Fedora specific patch to distribute native-pkcs#11 functionality
Patch136:bind-9.10-dist-native-pkcs11.patch
# Do not use isc-pkcs11.
Patch149:bind-9.11-kyua-pkcs11.patch
Patch137:bind-9.11-kyua-pkcs11.patch
# Patch 138-139 reserved for pkcs11
Patch157:bind-9.11-fips-tests.patch
Patch164:bind-9.11-rh1666814.patch
Patch170:bind-9.11-feature-test-named.patch
Patch171:bind-9.11-tests-variants.patch
# https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/5987
Patch172:bind-9.16-CVE-2022-0396.patch
Patch173:bind-9.16-CVE-2021-25220.patch
Patch174:bind-9.16-CVE-2021-25220-test.patch
Patch175:bind-9.16-CVE-2022-3080.patch
Patch176:bind-9.16-CVE-2022-38177.patch
Patch177:bind-9.16-CVE-2022-38178.patch
# https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/6793
# https://gitlab.isc.org/isc-projects/bind9/commit/bf2ea6d8525bfd96a84dad221ba9e004adb710a8
Patch178:bind-9.16-CVE-2022-2795.patch
# https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/6695
Patch179:bind-9.16-rh2101712.patch
# https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/7376
Patch181:bind-9.16-rh2133889.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/82185f4f80d2fa39a4569f6740cb360ffff8f5c4
Patch182: bind-9.16-CVE-2022-3094-1.patch
Patch183: bind-9.16-CVE-2022-3094-2.patch
Patch184: bind-9.16-CVE-2022-3094-3.patch
Patch185: bind-9.16-CVE-2022-3094-test.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/ea79385990c564eb478c286c089ea7ed15520690
Patch186: bind-9.16-CVE-2022-3736.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/b4a65aaea19762a3712932aa2270e8a833fbde22
Patch187: bind-9.16-CVE-2022-3924.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/f1d9e9ee3859976f403914d20ad2a10855343702
Patch188: bind-9.16-CVE-2023-2828.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/dd7dde5743715dc0dec2defbb92b1a8637977bf9
Patch189: bind-9.16-CVE-2023-2911-1.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/0101e28f91fb36b6a16a0049d3b3e2b7846f23f0
Patch190: bind-9.16-CVE-2023-2911-2.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/c003c5bc3c68f3e513654b6689e1f60280d14844
Patch191: bind-9.16-CVE-2023-2911-3.patch
Patch192: bind-9.16-CVE-2023-3341.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/8924adca613ca9daea63786563cce6fdbd742c56
Patch193: bind-9.16-update-b.root-servers.net.patch
Patch194: bind-9.16-CVE-2023-4408.patch
Patch195: bind-9.16-CVE-2023-5517.patch
Patch196: bind-9.16-CVE-2023-5679.patch
Patch197: bind-9.16-CVE-2023-6516.patch
Patch198: bind-9.16-CVE-2023-50387.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/f493a8394102b0aeb101d5dc2f963004c8741175
Patch199: bind-9.16-CVE-2023-4408-test1.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/b9c10a194da3358204f5ba7d91e55332db435614
Patch200: bind-9.16-CVE-2023-4408-test2.patch
# Downstream only change, fixes patch 171
Patch201: bind-9.16-system-test-cds.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/32779aba8a0a5f852c611f44ecbeab5aab633e34
Patch202: bind-9.16-isc-mempool-attach.patch
# Downstream only change, complements patch 198
Patch203: bind-9.16-isc_hp-CVE-2023-50387.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/1237d73cd1120b146ee699bbae7b2fe837cf2f98
Patch204: bind-9.16-CVE-2023-6516-test.patch
Patch205: bind-9.16-isc_hp-additional.patch
# Downstream, make error only warning
Patch165: bind-9.16-RH-inline-signing.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/26c9da5f2857b72077c17e06ac79f068c63782cc
# https://gitlab.isc.org/isc-projects/bind9/commit/c5ebda6deb0997dc520b26fa0639891459de5cb6
# https://gitlab.isc.org/isc-projects/bind9/commit/d56d2a32b861e81c2aaaabd309c4c58b629ede32
@ -174,8 +123,6 @@ Patch211: bind-9.16-CVE-2024-1737-records-test.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/3f1826f2f78792e95f56da7af3a35c46b4d6d9af
Patch212: bind-9.16-CVE-2024-1737-types.patch
Patch213: bind-9.16-CVE-2024-1737-types-test.patch
# backport issue fix
Patch214: bind-9.16-CVE-2024-1737-records-test2.patch
# https://gitlab.isc.org/isc-projects/bind9/-/commit/c6e6a7af8ac6b575dd3657b0f5cf4248d734c2b0
Patch215: bind-9.18-CVE-2024-11187-pre-test.patch
Patch216: bind-9.18-CVE-2024-11187.patch
@ -199,8 +146,27 @@ Patch224: bind-9.16-CVE-2025-40780.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/50479358efdf432d690415131b74b5df158a9d69
# https://gitlab.isc.org/isc-projects/bind9/commit/33a7db1fe964e55b76b4ac003ecc56cc67028bd9
Patch225: bind-9.16-CVE-2025-40778.patch
# https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/7942
Patch226: bind-9.16-properly-process-extra-nameserver-lines.patch
# https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/11329
Patch227: bind-9.20-robust-key-rollovers.patch
# https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/6057
# https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/6068
Patch228: bind-9.18-fix-dig-hanging-issue.patch
# https://gitlab.isc.org/isc-projects/bind9/-/commit/a5e8d2354385d4f42a58113b16960d85ec306b09
Patch229: bind-9.16-CVE-2026-1519.patch
# https://gitlab.isc.org/isc-projects/bind9/-/commit/7f04d7104304fdc6b858c41bb44ad151b2c3e1b7
Patch230: bind-9.16-CVE-2026-3039.patch
# https://gitlab.isc.org/isc-projects/bind9/-/commit/ec2c98181115bd5f6c7087fcc74d816490d4312e
# https://gitlab.isc.org/isc-projects/bind9/-/commit/e5abd37cb2330af1fbfeba68eb32f2873390226d
Patch231: bind-9.16-CVE-2026-5946.patch
# downstream only. Do not conflict on upgrade, egg-info should be a file
Patch232: bind-9.16-python-isc-distutils.patch
# https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/10767
Patch233: bind-9.20-stale-cname.patch
Patch234: bind-9.20-stale-cname-tests.patch
# https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/9236
Patch235: bind-9.18-fix-qmin-test.patch
# Downstream only. RHEL-213998.
Patch236: bind-9.16-remove-openssl-api-level-check-for-engine.patch
%{?systemd_ordering}
# https://fedoraproject.org/wiki/Changes/RPMSuportForSystemdSysusers
@ -497,18 +463,16 @@ in HTML and PDF format.
%autosetup -N
# Common patches
%autopatch -p1 -m 1 -M 134
# PKCS11 patches 135 136 and 149 are applied later.
%autopatch -p1 -m 150
%autopatch -p1 -m 0 -M 134
%autopatch -p1 -m 140
%if %{with PKCS11}
%autopatch -p1 135
%autopatch -p1 -m 135 -M 135
cp -r bin/named{,-pkcs11}
cp -r bin/dnssec{,-pkcs11}
cp -r lib/dns{,-pkcs11}
cp -r lib/ns{,-pkcs11}
%autopatch -p1 136
%autopatch -p1 149
%autopatch -p1 -m 136 -M 139
%endif
# Sparc and s390 arches need to use -fPIE
@ -1260,11 +1224,44 @@ fi;
%endif
%changelog
* Thu Jul 23 2026 Fedor Vorobev <fvorobev@redhat.com> - 32:9.16.50-5
- Remove compile-time OpenSSL API version check that was preventing
bind from fetching the engine for RSA algorithms. (RHEL-213788)
* Mon Jul 20 2026 Fedor Vorobev <fvorobev@redhat.com> - 32:9.16.50-4
- Fix uninitialized boolean in dig/host downstream patch that was
leading to incorrectly canceled queries in certain scenarios. (RHEL-212648)
* Tue Jul 7 2026 Fedor Vorobev <fvorobev@redhat.com> - 32:9.16.50-3
- Added CNAME chain bugfixes from v9.18.
- Fixed masterformat, reclimit, resolver, and qmin tests.
* Tue Jul 7 2026 Petr Menšík <pemensik@redhat.com> - 32:9.16.50-2
- Use the distutils for python, for backward compatibility
* Tue Jul 7 2026 Petr Menšík <pemensik@redhat.com> - 32:9.16.50-1
- Update to 9.16.50 (RHEL-6454)
- Allow starting without inline-signing and dnssec-policy
* Mon May 25 2026 Petr Menšík <pemensik@redhat.com> - 32:9.16.23-44
- Fix GSS-API resource leak (CVE-2026-3039)
- Invalid handling of CLASS != IN (CVE-2026-5946)
* Fri Mar 27 2026 Petr Menšík <pemensik@redhat.com> - 32:9.16.23-43
- Prevent Denial of Service via maliciously crafted DNSSEC-validated zone
(CVE-2026-1519)
* Thu Feb 12 2026 Fedor Vorobev <fvorobev@redhat.com> - 32:9.16.23-42
- Backport fix of dig/nslookup hanging issue (RHEL-29712)
* Thu Jan 29 2026 Fedor Vorobev <fvorobev@redhat.com> - 32:9.16.23-41
- Backport fix for manual DNSSEC key rollovers. (RHEL-12487)
* Wed Jan 28 2026 Petr Menšík <pemensik@redhat.com> - 32:9.16.23-40
- Add forgotten _libdir/named into bind-chroot tmpfiles (RHEL-135629)
* Thu Jan 22 2026 Fedor Vorobev <fvorobev@redhat.com> - 32:9.16.23-39
- Backport fix for nameserver line processing. (RHEL-79714)
- Backport fix for nameserver line processing. (RHEL-79714)
* Fri Dec 12 2025 Petr Menšík <pemensik@redhat.com> - 32:9.16.23-38
- Add sysusers named user creation (RHEL-132053)