Import from CS git

This commit is contained in:
eabdullin 2024-08-14 16:13:40 +00:00
parent 5305e59705
commit 6b1486c1d8
10 changed files with 11805 additions and 10 deletions

View File

@ -1,4 +1,4 @@
From e645046202006750f87531e21e3ff7c26fba3466 Mon Sep 17 00:00:00 2001
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
@ -6,16 +6,27 @@ 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 | 12 +++++++++++-
bin/named/Makefile.in | 14 ++++++++++++--
bin/tests/system/conf.sh.in | 2 +-
2 files changed, 12 insertions(+), 2 deletions(-)
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/bin/named/Makefile.in b/bin/named/Makefile.in
index 37053a7..ed9add2 100644
index debb906adc..dd894fe934 100644
--- a/bin/named/Makefile.in
+++ b/bin/named/Makefile.in
@@ -91,7 +91,7 @@ NOSYMLIBS = ${NSLIBS} ${DNSLIBS} ${BIND9LIBS} \
@@ -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
@ -24,7 +35,7 @@ index 37053a7..ed9add2 100644
GEOIP2LINKOBJS = geoip.@O@
@@ -154,6 +154,16 @@ named@EXEEXT@: ${OBJS} ${DEPLIBS}
@@ -156,6 +156,16 @@ named@EXEEXT@: ${OBJS} ${DEPLIBS}
export BASEOBJS="${OBJS} ${UOBJS}"; \
${FINALBUILDCMD}
@ -42,10 +53,10 @@ index 37053a7..ed9add2 100644
rm -f ${TARGETS} ${OBJS}
diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in
index 7934930..e84fde2 100644
index 9a61622143..f69c5be334 100644
--- a/bin/tests/system/conf.sh.in
+++ b/bin/tests/system/conf.sh.in
@@ -37,7 +37,7 @@ DELV=$TOP/bin/delv/delv
@@ -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
@ -55,5 +66,5 @@ index 7934930..e84fde2 100644
HOST=$TOP/bin/dig/host
IMPORTKEY=$TOP/bin/dnssec/dnssec-importkey
--
2.26.2
2.45.2

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,582 @@
From a1c95d5fa479ac722f0cf758c494a37ffe1508c0 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
Previously, the number of RR types for a single owner name was limited
only by the maximum number of the types (64k). As the data structure
that holds the RR types for the database node is just a linked list, and
there are places where we just walk through the whole list (again and
again), adding a large number of RR types for a single owner named with
would slow down processing of such name (database node).
Add a configurable limit to cap the number of the RR types for a single
owner. This is enforced at the database (rbtdb, qpzone, qpcache) level
and configured with new max-types-per-name configuration option that
can be configured globally, per-view and per-zone.
(cherry picked from commit 00d16211d6368b99f070c1182d8c76b3798ca1db)
(cherry picked from commit 89f1779bc28b27adbd00325b974ede7a683f8632)
fix a memory leak that could occur when signing
when signatures were not added because of too many types already
existing at a node, the diff was not being cleaned up; this led to
a memory leak being reported at shutdown.
(cherry picked from commit 2825bdb1ae5be801e7ed603ba2455ed9a308f1f7)
(cherry picked from commit a080317de0efb7f6ffa12415a863729d416007d5)
Be smarter about refusing to add many RR types to the database
Instead of outright refusing to add new RR types to the cache, be a bit
smarter:
1. If the new header type is in our priority list, we always add either
positive or negative entry at the beginning of the list.
2. If the new header type is negative entry, and we are over the limit,
we mark it as ancient immediately, so it gets evicted from the cache
as soon as possible.
3. Otherwise add the new header after the priority headers (or at the
head of the list).
4. If we are over the limit, evict the last entry on the normal header
list.
(cherry picked from commit 57cd34441a1b4ecc9874a4a106c2c95b8d7a3120)
(cherry picked from commit 92a680a3ef708281267e4fd7b1e62b57c929447b)
Log error when update fails
The new "too many records" error can make an update fail without the
error being logged. This commit fixes that.
(cherry picked from commit 558923e5405894cf976d102f0d246a28bdbb400c)
(cherry picked from commit d72adf4b927d83a2a0ff8e431b911ec1df7aeb88)
---
bin/named/config.c | 1 +
bin/named/server.c | 9 +++++++++
bin/named/zoneconf.c | 8 ++++++++
bin/tests/system/dyndb/driver/db.c | 3 ++-
doc/arm/reference.rst | 12 ++++++++++++
lib/dns/cache.c | 12 ++++++++++++
lib/dns/db.c | 9 +++++++++
lib/dns/dnsrps.c | 3 ++-
lib/dns/ecdb.c | 3 ++-
lib/dns/include/dns/cache.h | 6 ++++++
lib/dns/include/dns/db.h | 11 +++++++++++
lib/dns/include/dns/view.h | 7 +++++++
lib/dns/include/dns/zone.h | 13 +++++++++++++
lib/dns/rbtdb.c | 28 +++++++++++++++++-----------
lib/dns/sdb.c | 3 ++-
lib/dns/sdlz.c | 3 ++-
lib/dns/view.c | 10 ++++++++++
lib/dns/zone.c | 16 ++++++++++++++++
lib/isccfg/namedconf.c | 3 +++
lib/ns/update.c | 15 ++++++++++++---
20 files changed, 156 insertions(+), 19 deletions(-)
diff --git a/bin/named/config.c b/bin/named/config.c
index 9cba6f588b..c9888ada65 100644
--- a/bin/named/config.c
+++ b/bin/named/config.c
@@ -218,6 +218,7 @@ options {\n\
max-records-per-type 100;\n\
max-refresh-time 2419200; /* 4 weeks */\n\
max-retry-time 1209600; /* 2 weeks */\n\
+ max-types-per-name 100;\n\
max-transfer-idle-in 60;\n\
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
--- 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,
INSIST(result == ISC_R_SUCCESS);
dns_view_setmaxrrperset(view, cfg_obj_asuint32(obj));
+ /*
+ * This is used for the cache and also as a default value
+ * for zone databases.
+ */
+ obj = NULL;
+ result = named_config_get(maps, "max-types-per-name", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ dns_view_setmaxtypepername(view, cfg_obj_asuint32(obj));
+
obj = NULL;
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
--- 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,
dns_zone_setmaxrrperset(zone, 0);
}
+ obj = NULL;
+ result = named_config_get(maps, "max-types-per-name", &obj);
+ INSIST(result == ISC_R_SUCCESS && obj != NULL);
+ dns_zone_setmaxtypepername(mayberaw, cfg_obj_asuint32(obj));
+ if (zone != mayberaw) {
+ dns_zone_setmaxtypepername(zone, 0);
+ }
+
if (raw != NULL && filename != NULL) {
#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
--- 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 = {
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
NULL, /* adjusthashsize */
- NULL /* setmaxrrperset */
+ NULL, /* setmaxrrperset */
+ NULL /* setmaxtypepername */
};
/* Auxiliary driver functions. */
diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst
index b1983ef30d..a8a3c7911d 100644
--- a/doc/arm/reference.rst
+++ b/doc/arm/reference.rst
@@ -2902,6 +2902,18 @@ system.
a failure. If set to 0, there is no cap on RRset size. The default is
100.
+``max-types-per-name``
+ This sets the maximum number of resource record types that can be stored
+ for a single owner name in a database. When configured in ``options``
+ or ``view``, it controls the cache database, and also sets
+ the default value for zone databases, which can be overridden by setting
+ it at the ``zone`` level
+
+ If set to a positive value, any attempt to cache or to add to a zone an owner
+ name with more than the specified number of resource record types will result
+ in a failure. If set to 0, there is no cap on RR types number. The default is
+ 100.
+
``recursive-clients``
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
--- a/lib/dns/cache.c
+++ b/lib/dns/cache.c
@@ -150,6 +150,7 @@ struct dns_cache {
/* Access to the on-disk cache file is also locked by 'filelock'. */
uint32_t maxrrperset;
+ uint32_t maxtypepername;
};
/***
@@ -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);
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) {
}
}
+void
+dns_cache_setmaxtypepername(dns_cache_t *cache, uint32_t value) {
+ REQUIRE(VALID_CACHE(cache));
+
+ cache->maxtypepername = value;
+ if (cache->db != NULL) {
+ dns_db_setmaxtypepername(cache->db, value);
+ }
+}
+
/*
* 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
--- a/lib/dns/db.c
+++ b/lib/dns/db.c
@@ -1131,3 +1131,12 @@ dns_db_setmaxrrperset(dns_db_t *db, uint32_t value) {
(db->methods->setmaxrrperset)(db, value);
}
}
+
+void
+dns_db_setmaxtypepername(dns_db_t *db, uint32_t value) {
+ REQUIRE(DNS_DB_VALID(db));
+
+ if (db->methods->setmaxtypepername != NULL) {
+ (db->methods->setmaxtypepername)(db, value);
+ }
+}
diff --git a/lib/dns/dnsrps.c b/lib/dns/dnsrps.c
index 539090d1bd..e1a1b21a8b 100644
--- a/lib/dns/dnsrps.c
+++ b/lib/dns/dnsrps.c
@@ -971,7 +971,8 @@ static dns_dbmethods_t rpsdb_db_methods = {
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
NULL, /* adjusthashsize */
- NULL /* setmaxrrperset */
+ NULL, /* setmaxrrperset */
+ NULL /* setmaxtypepername */
};
static dns_rdatasetmethods_t rpsdb_rdataset_methods = {
diff --git a/lib/dns/ecdb.c b/lib/dns/ecdb.c
index bab5da5503..27d03b4e3a 100644
--- a/lib/dns/ecdb.c
+++ b/lib/dns/ecdb.c
@@ -560,7 +560,8 @@ static dns_dbmethods_t ecdb_methods = {
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
NULL, /* adjusthashsize */
- NULL /* setmaxrrperset */
+ NULL, /* setmaxrrperset */
+ NULL /* setmaxtypepername */
};
static isc_result_t
diff --git a/lib/dns/include/dns/cache.h b/lib/dns/include/dns/cache.h
index 3fa2a891e0..72de21600a 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);
* Set the maximum resource records per RRSet that can be cached.
*/
+void
+dns_cache_setmaxtypepername(dns_cache_t *cache, uint32_t value);
+/*%<
+ * Set the maximum resource record types per owner name that can be cached.
+ */
+
#ifdef HAVE_LIBXML2
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
--- a/lib/dns/include/dns/db.h
+++ b/lib/dns/include/dns/db.h
@@ -183,6 +183,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);
* is nonzero, then any subsequent attempt to add an rdataset with
* more than 'value' RRs will return ISC_R_NOSPACE.
*/
+
+void
+dns_db_setmaxtypepername(dns_db_t *db, uint32_t value);
+/*%<
+ * Set the maximum permissible number of RR types per owner name.
+ *
+ * If 'value' is nonzero, then any subsequent attempt to add an rdataset with a
+ * RR type that would exceed the number of already stored RR types will return
+ * ISC_R_NOSPACE.
+ */
ISC_LANG_ENDDECLS
#endif /* DNS_DB_H */
diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h
index 0d502f4dd2..0a72f58e98 100644
--- a/lib/dns/include/dns/view.h
+++ b/lib/dns/include/dns/view.h
@@ -187,6 +187,7 @@ struct dns_view {
uint32_t fail_ttl;
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);
* Set the maximum resource records per RRSet that can be cached.
*/
+void
+dns_view_setmaxtypepername(dns_view_t *view, uint32_t value);
+/*%<
+ * Set the maximum resource record types per owner name that can be cached.
+ */
+
ISC_LANG_ENDDECLS
#endif /* DNS_VIEW_H */
diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h
index e902043357..6fca11f3fd 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);
*\li void
*/
+void
+dns_zone_setmaxtypepername(dns_zone_t *zone, uint32_t maxtypepername);
+/*%<
+ * Sets the maximum number of resource record types per owner name
+ * permitted in a zone. 0 implies unlimited.
+ *
+ * Requires:
+ *\li 'zone' to be valid initialised zone.
+ *
+ * Returns:
+ *\li void
+ */
+
void
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
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -483,6 +483,7 @@ struct dns_rbtdb {
rbtdb_serial_t least_serial;
rbtdb_serial_t next_serial;
uint32_t maxrrperset;
+ uint32_t maxtypepername;
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,
RWUNLOCK(&rbtversion->rwlock, isc_rwlocktype_write);
}
-#ifndef DNS_RBTDB_MAX_RTYPES
-#define DNS_RBTDB_MAX_RTYPES 100
-#endif /* DNS_RBTDB_MAX_RTYPES */
-
static bool
overmaxtype(dns_rbtdb_t *rbtdb, uint32_t ntypes) {
- UNUSED(rbtdb);
-
- if (DNS_RBTDB_MAX_RTYPES == 0) {
+ if (rbtdb->maxtypepername == 0) {
return (false);
}
- return (ntypes >= DNS_RBTDB_MAX_RTYPES);
+ return (ntypes >= rbtdb->maxtypepername);
}
static bool
@@ -6794,7 +6789,7 @@ find_header:
if (!IS_CACHE(rbtdb) && overmaxtype(rbtdb, ntypes)) {
free_rdataset(rbtdb, rbtdb->common.mctx,
newheader);
- return (ISC_R_QUOTA);
+ return (DNS_R_TOOMANYRECORDS);
}
newheader->down = NULL;
@@ -8623,6 +8618,15 @@ setmaxrrperset(dns_db_t *db, uint32_t maxrrperset) {
rbtdb->maxrrperset = maxrrperset;
}
+static void
+setmaxtypepername(dns_db_t *db, uint32_t maxtypepername) {
+ dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
+
+ REQUIRE(VALID_RBTDB(rbtdb));
+
+ rbtdb->maxtypepername = maxtypepername;
+}
+
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,
NULL, /* getservestalerefresh */
setgluecachestats,
adjusthashsize,
- setmaxrrperset };
+ setmaxrrperset,
+ setmaxtypepername };
static dns_dbmethods_t cache_methods = { attach,
detach,
@@ -8800,7 +8805,8 @@ static dns_dbmethods_t cache_methods = { attach,
getservestalerefresh,
NULL,
adjusthashsize,
- setmaxrrperset };
+ setmaxrrperset,
+ setmaxtypepername };
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
--- a/lib/dns/sdb.c
+++ b/lib/dns/sdb.c
@@ -1313,7 +1313,8 @@ static dns_dbmethods_t sdb_methods = {
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
NULL, /* adjusthashsize */
- NULL /* setmaxrrperset */
+ NULL, /* setmaxrrperset */
+ NULL /* setmaxtypepername */
};
static isc_result_t
diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c
index 60a1d23b3b..418a4a14ee 100644
--- a/lib/dns/sdlz.c
+++ b/lib/dns/sdlz.c
@@ -1285,7 +1285,8 @@ static dns_dbmethods_t sdlzdb_methods = {
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
NULL, /* adjusthashsize */
- NULL /* setmaxrrperset */
+ NULL, /* setmaxrrperset */
+ NULL /* setmaxtypepername */
};
/*
diff --git a/lib/dns/view.c b/lib/dns/view.c
index a672aa8bc8..98579f03d9 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) {
INSIST(DNS_DB_VALID(view->cachedb));
dns_cache_setmaxrrperset(view->cache, view->maxrrperset);
+ dns_cache_setmaxtypepername(view->cache, view->maxtypepername);
}
bool
@@ -2555,3 +2556,12 @@ dns_view_setmaxrrperset(dns_view_t *view, uint32_t value) {
dns_cache_setmaxrrperset(view->cache, value);
}
}
+
+void
+dns_view_setmaxtypepername(dns_view_t *view, uint32_t value) {
+ REQUIRE(DNS_VIEW_VALID(view));
+ view->maxtypepername = value;
+ if (view->cache != NULL) {
+ dns_cache_setmaxtypepername(view->cache, value);
+ }
+}
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index 5c8d97ed18..e1fb9ab50b 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -277,6 +277,7 @@ struct dns_zone {
uint32_t maxrecords;
uint32_t maxrrperset;
+ uint32_t maxtypepername;
isc_sockaddr_t *masters;
isc_dscp_t *masterdscps;
@@ -9959,6 +9960,7 @@ cleanup:
}
dns_diff_clear(&_sig_diff);
+ dns_diff_clear(&post_diff);
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) {
}
}
+void
+dns_zone_setmaxtypepername(dns_zone_t *zone, uint32_t val) {
+ REQUIRE(DNS_ZONE_VALID(zone));
+
+ zone->maxtypepername = val;
+ if (zone->db != NULL) {
+ dns_db_setmaxtypepername(zone->db, val);
+ }
+}
+
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) {
}
dns_db_settask(stub->db, 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) {
zone_attachdb(zone, db);
dns_db_settask(zone->db, 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) {
dns_db_settask(db, 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
--- a/lib/isccfg/namedconf.c
+++ b/lib/isccfg/namedconf.c
@@ -2239,6 +2239,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 },
+ { "max-types-per-name", &cfg_type_uint32,
+ CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
+ CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT },
{ "max-refresh-time", &cfg_type_uint32,
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
--- a/lib/ns/update.c
+++ b/lib/ns/update.c
@@ -3112,9 +3112,18 @@ update_action(isc_task_t *task, isc_event_t *event) {
dns_diff_clear(&ctx.add_diff);
goto failure;
}
- CHECK(update_one_rr(db, ver, &diff,
- DNS_DIFFOP_ADD,
- name, ttl, &rdata));
+ result = update_one_rr(
+ db, ver, &diff, DNS_DIFFOP_ADD,
+ name, ttl, &rdata);
+ if (result != ISC_R_SUCCESS) {
+ update_log(client, zone,
+ LOGLEVEL_PROTOCOL,
+ "adding an RR "
+ "failed: %s",
+ isc_result_totext(
+ result));
+ goto failure;
+ }
}
}
} else if (update_class == dns_rdataclass_any) {
--
2.45.2

View File

@ -0,0 +1,364 @@
From c5357835c98b7b028f8a041b6976bb335c9a4056 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
Previously, the number of RRs in the RRSets were internally unlimited.
As the data structure that holds the RRs is just a linked list, and
there are places where we just walk through all of the RRs, adding an
RRSet with huge number of RRs inside would slow down processing of said
RRSets.
The fix for end-of-life branches make the limit compile-time only for
simplicity and the limit can be changed at the compile time by adding
following define to CFLAGS:
-DDNS_RDATASET_MAX_RECORDS=<limit>
(cherry picked from commit c5c4d00c38530390c9e1ae4c98b65fbbadfe9e5e)
(cherry picked from commit fdabf4b9570a60688f9f7d1e88d885f7a3718bca)
Add a limit to the number of RR types for single name
Previously, the number of RR types for a single owner name was limited
only by the maximum number of the types (64k). As the data structure
that holds the RR types for the database node is just a linked list, and
there are places where we just walk through the whole list (again and
again), adding a large number of RR types for a single owner named with
would slow down processing of such name (database node).
Add a hard-coded limit (100) to cap the number of the RR types for a single
owner. The limit can be changed at the compile time by adding following
define to CFLAGS:
-DDNS_RBTDB_MAX_RTYPES=<limit>
(cherry picked from commit dfcadc2085c8844b5836aff2b5ea51fb60c34868)
Optimize the slabheader placement for certain RRTypes
Mark the infrastructure RRTypes as "priority" types and place them at
the beginning of the rdataslab header data graph. The non-priority
types either go right after the priority types (if any).
(cherry picked from commit 3ac482be7fd058d284e89873021339579fad0615)
(cherry picked from commit 8ef414a7f38a04cfc11df44adaedaf3126fa3878)
Expand the list of the priority types
Add HTTPS, SVCB, SRV, PTR, NAPTR, DNSKEY and TXT records to the list of
the priority types that are put at the beginning of the slabheader list
for faster access and to avoid eviction when there are more types than
the max-types-per-name limit.
(cherry picked from commit b27c6bcce894786a8e082eafd59eccbf6f2731cb)
(cherry picked from commit d56d2a32b861e81c2aaaabd309c4c58b629ede32)
Make the resolver qtype ANY test order agnostic
Instead of relying on a specific order of the RR types in the databases
pick the first RR type as returned from the cache.
(cherry picked from commit 58f660cf2b800963fa649bc9823a626009db3a7e)
(cherry picked from commit c5ebda6deb0997dc520b26fa0639891459de5cb6)
Be smarter about refusing to add many RR types to the database
Instead of outright refusing to add new RR types to the cache, be a bit
smarter:
1. If the new header type is in our priority list, we always add either
positive or negative entry at the beginning of the list.
2. If the new header type is negative entry, and we are over the limit,
we mark it as ancient immediately, so it gets evicted from the cache
as soon as possible.
3. Otherwise add the new header after the priority headers (or at the
head of the list).
4. If we are over the limit, evict the last entry on the normal header
list.
(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(-)
diff --git a/bin/tests/system/resolver/tests.sh b/bin/tests/system/resolver/tests.sh
index 6c69c1104e..bd997a61a4 100755
--- a/bin/tests/system/resolver/tests.sh
+++ b/bin/tests/system/resolver/tests.sh
@@ -553,15 +553,20 @@ n=`expr $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}`
+ttl1=$(awk '/^fetchall.tld/ { print $2 - 3; exit }' dig.out.1.${n})
# sleep so we are in prefetch range
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}`
+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
+# 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
+ttl3=$(awk '/^fetchall.tld/ { print $2; exit }' dig.out.3.${n})
+test "${ttl3:-0}" -gt "${ttl2:-1}" || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=`expr $status + $ret`
diff --git a/configure b/configure
index ed2d4869e5..be0f60eaba 100755
--- a/configure
+++ b/configure
@@ -12295,7 +12295,7 @@ fi
XTARGETS=
if test "$enable_developer" = "yes"; then :
- STD_CDEFINES="$STD_CDEFINES -DISC_MEM_DEFAULTFILL=1 -DISC_LIST_CHECKINIT=1"
+ STD_CDEFINES="$STD_CDEFINES -DISC_MEM_DEFAULTFILL=1 -DISC_LIST_CHECKINIT=1 -DDNS_RDATASET_MAX_RECORDS=5000 -DDNS_RBTDB_MAX_RTYPES=5000"
test "${enable_fixed_rrset+set}" = set || enable_fixed_rrset=yes
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
--- a/configure.ac
+++ b/configure.ac
@@ -94,7 +94,7 @@ AC_ARG_ENABLE([developer],
XTARGETS=
AS_IF([test "$enable_developer" = "yes"],
- [STD_CDEFINES="$STD_CDEFINES -DISC_MEM_DEFAULTFILL=1 -DISC_LIST_CHECKINIT=1"
+ [STD_CDEFINES="$STD_CDEFINES -DISC_MEM_DEFAULTFILL=1 -DISC_LIST_CHECKINIT=1 -DDNS_RDATASET_MAX_RECORDS=5000 -DDNS_RBTDB_MAX_RTYPES=5000"
test "${enable_fixed_rrset+set}" = set || enable_fixed_rrset=yes
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
--- 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):
+ 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_dname:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_dname):
+ case dns_rdatatype_svcb:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_svcb):
+ case dns_rdatatype_https:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_https):
+ case dns_rdatatype_dnskey:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_dnskey):
+ case dns_rdatatype_srv:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_srv):
+ case dns_rdatatype_txt:
+ case RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_txt):
+ case dns_rdatatype_ptr:
+ 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,
RWUNLOCK(&rbtversion->rwlock, isc_rwlocktype_write);
}
+#ifndef DNS_RBTDB_MAX_RTYPES
+#define DNS_RBTDB_MAX_RTYPES 100
+#endif /* DNS_RBTDB_MAX_RTYPES */
+
+static bool
+overmaxtype(dns_rbtdb_t *rbtdb, uint32_t ntypes) {
+ UNUSED(rbtdb);
+
+ if (DNS_RBTDB_MAX_RTYPES == 0) {
+ return (false);
+ }
+
+ return (ntypes >= DNS_RBTDB_MAX_RTYPES);
+}
+
+static bool
+prio_header(rdatasetheader_t *header) {
+ if (NEGATIVE(header) && prio_type(RBTDB_RDATATYPE_EXT(header->type))) {
+ return (true);
+ }
+
+ return (prio_type(header->type));
+}
+
/*
* 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,
rbtdb_changed_t *changed = NULL;
rdatasetheader_t *topheader = NULL, *topheader_prev = NULL;
rdatasetheader_t *header = NULL, *sigheader = 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,
rbtdb_rdatatype_t negtype, sigtype;
dns_trust_t trust;
int idx;
+ uint32_t ntypes = 0;
/*
* 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) {
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,
for (topheader = rbtnode->data; topheader != NULL;
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:
/*
* 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);
+ return (ISC_R_QUOTA);
+ }
+
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 (IS_CACHE(rbtdb) && overmaxtype(rbtdb, ntypes)) {
+ if (expireheader == NULL) {
+ expireheader = newheader;
+ }
+ if (NEGATIVE(newheader) &&
+ !prio_header(newheader))
+ {
+ /*
+ * Add the new non-priority negative
+ * header to the database only
+ * temporarily.
+ */
+ expireheader = newheader;
+ }
+
+ set_ttl(rbtdb, expireheader, 0);
+ mark_header_ancient(rbtdb, expireheader);
+ /*
+ * FIXME: In theory, we should mark the RRSIG
+ * and the header at the same time, but there is
+ * no direct link between those two header, so
+ * we would have to check the whole list again.
+ */
+ }
}
}
diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c
index 1d5e88f745..dda903819a 100644
--- a/lib/dns/rdataslab.c
+++ b/lib/dns/rdataslab.c
@@ -110,6 +110,10 @@ fillin_offsets(unsigned char *offsetbase, unsigned int *offsettable,
}
#endif /* if DNS_RDATASET_FIXED */
+#ifndef DNS_RDATASET_MAX_RECORDS
+#define DNS_RDATASET_MAX_RECORDS 100
+#endif /* DNS_RDATASET_MAX_RECORDS */
+
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,
return (ISC_R_SUCCESS);
}
+ if (nitems > DNS_RDATASET_MAX_RECORDS) {
+ return (DNS_R_TOOMANYRECORDS);
+ }
+
if (nitems > 0xffff) {
return (ISC_R_NOSPACE);
}
@@ -520,6 +528,10 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
#endif /* if DNS_RDATASET_FIXED */
INSIST(ocount > 0 && ncount > 0);
+ if (ocount + ncount > DNS_RDATASET_MAX_RECORDS) {
+ return (DNS_R_TOOMANYRECORDS);
+ }
+
#if DNS_RDATASET_FIXED
oncount = ncount;
#endif /* if DNS_RDATASET_FIXED */
--
2.45.2

View File

@ -0,0 +1,318 @@
From 34e92fc88943beeba76aa4e408951cb46d8cdb53 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
6404. [security] Remove SIG(0) support from named as a countermeasure
for CVE-2024-1975. [GL #4480]
Resolves: CVE-2024-1975
---
bin/tests/system/tsiggss/authsock.pl | 5 ++
bin/tests/system/tsiggss/tests.sh | 12 ++--
bin/tests/system/upforwd/tests.sh | 21 +++---
doc/arm/general.rst | 6 +-
doc/arm/reference.rst | 4 +-
doc/arm/security.rst | 4 +-
lib/dns/message.c | 97 ++--------------------------
lib/ns/client.c | 7 ++
8 files changed, 43 insertions(+), 113 deletions(-)
diff --git a/bin/tests/system/tsiggss/authsock.pl b/bin/tests/system/tsiggss/authsock.pl
index ab3833d..0b231ee 100644
--- a/bin/tests/system/tsiggss/authsock.pl
+++ b/bin/tests/system/tsiggss/authsock.pl
@@ -31,6 +31,10 @@ if (!defined($path)) {
exit(1);
}
+# Enable output autoflush so that it's not lost when the parent sends TERM.
+select STDOUT;
+$| = 1;
+
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) {
}
while (my $client = $server->accept()) {
+ printf("accept()\n");
$client->recv(my $buf, 8, 0);
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
--- a/bin/tests/system/tsiggss/tests.sh
+++ b/bin/tests/system/tsiggss/tests.sh
@@ -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 >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))
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
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 -d -k ns1/Kkey.example.nil.*.private <<END >nsupdate.out${n} 2>&1 || true
+debug
server 10.53.0.1 ${PORT}
zone example.nil
update add fred.example.nil 120 cname foo.bar.
send
END
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))
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status+ret))
diff --git a/bin/tests/system/upforwd/tests.sh b/bin/tests/system/upforwd/tests.sh
index 20fc46f..c8fd54b 100644
--- a/bin/tests/system/upforwd/tests.sh
+++ b/bin/tests/system/upforwd/tests.sh
@@ -224,19 +224,22 @@ 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
- local 10.53.0.1
- server 10.53.0.3 ${PORT}
- zone example2
- update add unsigned.example2. 600 A 10.10.10.1
- update add unsigned.example2. 600 TXT Foo
- send
+ # SIG(0) is removed, update is expected to fail.
+ {
+ $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
+ update add unsigned.example2. 600 TXT Foo
+ 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`
diff --git a/doc/arm/general.rst b/doc/arm/general.rst
index 225576b..0766dfe 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.
-[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.
[4] 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
--- 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
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
-that signed the update request, using either TSIG or SIG(0). In most
+that signed the update request, using either TSIG. In most
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``
field. Details for each rule type are described below.
The ``identity`` field must be set to a fully qualified domain name. In
-most cases, this represents the name of the TSIG or SIG(0) key that
+most cases, this represents the name of the TSIG key that
must be used to sign the update request. If the specified name is a
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
--- 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
spoofing and denial of service (DoS) attacks against the server.
ACLs match clients on the basis of up to three characteristics: 1) The
-client's IP address; 2) the TSIG or SIG(0) key that was used to sign the
+client's IP address; 2) the TSIG key that was used to sign the
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``.
In addition to network addresses and prefixes, which are matched against
the source address of the DNS request, ACLs may include ``key``
-elements, which specify the name of a TSIG or SIG(0) key.
+elements, which specify the name of a TSIG key.
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
--- a/lib/dns/message.c
+++ b/lib/dns/message.c
@@ -3287,109 +3287,24 @@ dns_message_dumpsig(dns_message_t *msg, char *txt1) {
isc_result_t
dns_message_checksig(dns_message_t *msg, dns_view_t *view) {
- isc_buffer_t b, msgb;
+ isc_buffer_t msgb;
REQUIRE(DNS_MESSAGE_VALID(msg));
- if (msg->tsigkey == NULL && msg->tsig == NULL && msg->sig0 == NULL) {
+ if (msg->tsigkey == NULL && msg->tsig == NULL) {
return (ISC_R_SUCCESS);
}
INSIST(msg->saved.base != NULL);
isc_buffer_init(&msgb, msg->saved.base, msg->saved.length);
isc_buffer_add(&msgb, msg->saved.length);
- if (msg->tsigkey != NULL || msg->tsig != NULL) {
#ifdef SKAN_MSG_DEBUG
- dns_message_dumpsig(msg, "dns_message_checksig#1");
+ dns_message_dumpsig(msg, "dns_message_checksig#1");
#endif /* ifdef SKAN_MSG_DEBUG */
- if (view != NULL) {
- return (dns_view_checksig(view, &msgb, msg));
- } else {
- return (dns_tsig_verify(&msgb, msg, NULL, NULL));
- }
+ if (view != NULL) {
+ return (dns_view_checksig(view, &msgb, msg));
} else {
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdata_sig_t sig;
- dns_rdataset_t keyset;
- isc_result_t result;
-
- result = dns_rdataset_first(msg->sig0);
- INSIST(result == ISC_R_SUCCESS);
- dns_rdataset_current(msg->sig0, &rdata);
-
- /*
- * This can occur when the message is a dynamic update, since
- * the rdata length checking is relaxed. This should not
- * happen in a well-formed message, since the SIG(0) is only
- * looked for in the additional section, and the dynamic update
- * meta-records are in the prerequisite and update sections.
- */
- if (rdata.length == 0) {
- return (ISC_R_UNEXPECTEDEND);
- }
-
- result = dns_rdata_tostruct(&rdata, &sig, msg->mctx);
- if (result != ISC_R_SUCCESS) {
- return (result);
- }
-
- dns_rdataset_init(&keyset);
- if (view == NULL) {
- return (DNS_R_KEYUNAUTHORIZED);
- }
- result = dns_view_simplefind(view, &sig.signer,
- dns_rdatatype_key /* SIG(0) */, 0,
- 0, false, &keyset, NULL);
-
- if (result != ISC_R_SUCCESS) {
- /* XXXBEW Should possibly create a fetch here */
- result = DNS_R_KEYUNAUTHORIZED;
- goto freesig;
- } else if (keyset.trust < dns_trust_secure) {
- /* XXXBEW Should call a validator here */
- result = DNS_R_KEYUNAUTHORIZED;
- goto freesig;
- }
- result = dns_rdataset_first(&keyset);
- INSIST(result == ISC_R_SUCCESS);
- for (; result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&keyset)) {
- dst_key_t *key = NULL;
-
- dns_rdata_reset(&rdata);
- dns_rdataset_current(&keyset, &rdata);
- isc_buffer_init(&b, rdata.data, rdata.length);
- isc_buffer_add(&b, rdata.length);
-
- result = dst_key_fromdns(&sig.signer, rdata.rdclass, &b,
- view->mctx, &key);
- if (result != ISC_R_SUCCESS) {
- continue;
- }
- if (dst_key_alg(key) != sig.algorithm ||
- dst_key_id(key) != sig.keyid ||
- !(dst_key_proto(key) == DNS_KEYPROTO_DNSSEC ||
- dst_key_proto(key) == DNS_KEYPROTO_ANY))
- {
- dst_key_free(&key);
- continue;
- }
- result = dns_dnssec_verifymessage(&msgb, msg, key);
- dst_key_free(&key);
- if (result == ISC_R_SUCCESS) {
- break;
- }
- }
- if (result == ISC_R_NOMORE) {
- result = DNS_R_KEYUNAUTHORIZED;
- }
-
- freesig:
- if (dns_rdataset_isassociated(&keyset)) {
- dns_rdataset_disassociate(&keyset);
- }
- dns_rdata_freestruct(&sig);
- return (result);
+ return (dns_tsig_verify(&msgb, msg, NULL, NULL));
}
}
diff --git a/lib/ns/client.c b/lib/ns/client.c
index 967e21b..87b8a18 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,
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
"request is signed by a nonauthoritative key");
+ } else if (result == DNS_R_NOTVERIFIEDYET &&
+ client->message->sig0 != NULL)
+ {
+ ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
+ NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
+ "request has a SIG(0) signature but its support "
+ "was removed (CVE-2024-1975)");
} else {
char tsigrcode[64];
isc_buffer_t b;
--
2.45.2

View File

@ -0,0 +1,29 @@
From 274463c5b71db87a615694889da23837ba48db9a Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Tue, 16 Jul 2024 19:49:26 +0200
Subject: [PATCH] Resolve CVE-2024-4076
6403. [security] qctx-zversion was not being cleared when it should have
been leading to an assertion failure if it needed to be
reused. (CVE-2024-4076) [GL #4507]
Resolves: CVE-2024-4076
---
lib/ns/query.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/ns/query.c b/lib/ns/query.c
index 537d332..be4cbb6 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -5325,6 +5325,7 @@ qctx_freedata(query_ctx_t *qctx) {
ns_client_releasename(qctx->client, &qctx->zfname);
dns_db_detachnode(qctx->zdb, &qctx->znode);
dns_db_detach(&qctx->zdb);
+ qctx->zversion = NULL;
}
if (qctx->event != NULL && !qctx->client->nodetach) {
--
2.45.2

View File

@ -33,6 +33,9 @@
%{_libdir}/bind %{_libdir}/named %{_datadir}/GeoIP /proc/sys/net/ipv4
%global selinuxbooleans named_write_master_zones=1
# BIND 9.16 does not work with fortify 3 level, make builds work on Fedora
%global _fortify_level 2
## The order of libs is important. See lib/Makefile.in for details
%define bind_export_libs isc dns isccfg irs
%{!?_export_dir:%global _export_dir /bind9-export/}
@ -57,7 +60,7 @@ Summary: The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) serv
Name: bind9.16
License: MPLv2.0
Version: 9.16.23
Release: 0.19%{?dist}
Release: 0.22%{?dist}
Epoch: 32
Url: https://www.isc.org/downloads/bind/
#
@ -146,6 +149,24 @@ Patch202: bind-9.16-isc-mempool-attach.patch
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-CVE-2024-1975.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
# https://gitlab.isc.org/isc-projects/bind9/commit/dfcadc2085c8844b5836aff2b5ea51fb60c34868
# https://gitlab.isc.org/isc-projects/bind9/commit/fdabf4b9570a60688f9f7d1e88d885f7a3718bca
# https://gitlab.isc.org/isc-projects/bind9/commit/8ef414a7f38a04cfc11df44adaedaf3126fa3878
Patch206: bind-9.16-CVE-2024-1737.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/a61be8eef0ee0ca8fd8036ccb61c6f9b728158ce
Patch207: bind-9.18-CVE-2024-4076.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/2f2f0a900b9baf5e6eba02a82e2fe9e967dc1760
Patch209: bind-9.16-CVE-2024-1737-records.patch
Patch210: bind-9.16-CVE-2024-1737-records-test.patch
# https://gitlab.isc.org/isc-projects/bind9/commit/3f1826f2f78792e95f56da7af3a35c46b4d6d9af
Patch211: bind-9.16-CVE-2024-1737-types.patch
Patch212: bind-9.16-CVE-2024-1737-types-test.patch
# backport issue fix
Patch213: bind-9.16-CVE-2024-1737-records-test2.patch
%{?systemd_ordering}
Requires: coreutils
@ -471,6 +492,14 @@ in HTML and PDF format.
%patch202 -p1 -b .mempool-attach
%patch203 -p1 -b .isc_hp-CVE-2023-50387
%patch204 -p1 -b .CVE-2023-6516-test
%patch205 -p1 -b .CVE-2024-1975
%patch206 -p1 -b .CVE-2024-1737
%patch207 -p1 -b .CVE-2024-4076
%patch209 -p1 -b .CVE-2024-1737-records
%patch210 -p1 -b .CVE-2024-1737-records-test
%patch211 -p1 -b .CVE-2024-1737-types
%patch212 -p1 -b .CVE-2024-1737-types-test
%patch213 -p1 -b .CVE-2024-1737-records-test2
%if %{with PKCS11}
%patch135 -p1 -b .config-pkcs11
@ -1195,6 +1224,19 @@ fi;
%endif
%changelog
* Fri Aug 09 2024 Petr Menšík <pemensik@redhat.com> - 32:9.16.23-0.22
- Minor fix of reclimit test backport (CVE-2024-1737)
* Wed Aug 07 2024 Petr Menšík <pemensik@redhat.com> - 32:9.16.23-0.21
- Backport addition of max-records-per-type and max-records-per-type options
(CVE-2024-1737)
* Thu Jul 18 2024 Petr Menšík <pemensik@redhat.com> - 32:9.16.23-0.20
- Resolve CVE-2024-1975
- Resolve CVE-2024-1737
- Resolve CVE-2024-4076
- Add ability to change runtime limits for max types and records per name
* Wed May 15 2024 Petr Menšík <pemensik@redhat.com> - 32:9.16.23-0.19
- Add few more explicit conflicts with bind subpackages (RHEL-2208)