[9.18] [CVE-2024-11187] sec: usr: Limit the additional processing for large RDATA sets
When answering queries, don't add data to the additional section if the answer has more than 13 names in the RDATA. This limits the number of lookups into the database(s) during a single client query, reducing query processing load. Vulnerability: CVE-2024-11187 Resolves: RHEL-76889
This commit is contained in:
parent
433bab66ec
commit
642b920266
68
bind-9.18-CVE-2024-11187-pre-test.patch
Normal file
68
bind-9.18-CVE-2024-11187-pre-test.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From cd48dcb0f87f8bed8138cbc4635a6a46f3148620 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
|
||||
test
|
||||
|
||||
Instead of running the whole resolver/ns4 server with -T noaa flag,
|
||||
use it only for the part where it is actually needed. The -T noaa
|
||||
could interfere with other parts of the test because the answers don't
|
||||
have the authoritative-answer bit set, and we could have false
|
||||
positives (or false negatives) in the test because the authoritative
|
||||
server doesn't follow the DNS protocol for all the tests in the resolver
|
||||
system test.
|
||||
|
||||
(cherry picked from commit e51d4d3b88af00d6667f2055087ebfc47fb3107c)
|
||||
---
|
||||
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 be78cc2c949..00000000000
|
||||
--- a/bin/tests/system/resolver/ns4/named.noaa
|
||||
+++ /dev/null
|
||||
@@ -1,12 +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 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 982ff9761be..23b42f728cd 100755
|
||||
--- a/bin/tests/system/resolver/tests.sh
|
||||
+++ b/bin/tests/system/resolver/tests.sh
|
||||
@@ -322,6 +322,10 @@ done
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
|
||||
+stop_server ns4
|
||||
+touch ns4/named.noaa
|
||||
+start_server --noclean --restart --port ${PORT} ns4 || ret=1
|
||||
+
|
||||
n=$((n + 1))
|
||||
echo_i "RT21594 regression test check setup ($n)"
|
||||
ret=0
|
||||
@@ -358,6 +362,10 @@ grep "status: NXDOMAIN" dig.ns5.out.${n} >/dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
|
||||
+stop_server ns4
|
||||
+rm ns4/named.noaa
|
||||
+start_server --noclean --restart --port ${PORT} ns4 || ret=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
|
||||
|
||||
226
bind-9.18-CVE-2024-11187.patch
Normal file
226
bind-9.18-CVE-2024-11187.patch
Normal file
@ -0,0 +1,226 @@
|
||||
From 7ded6b358ced23bb6214c7309cff0850b7d1b77d 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
|
||||
|
||||
When answering queries, don't add data to the additional section if
|
||||
the answer has more than 13 names in the RDATA. This limits the
|
||||
number of lookups into the database(s) during a single client query,
|
||||
reducing query processing load.
|
||||
|
||||
Also, don't append any additional data to type=ANY queries. The
|
||||
answer to ANY is already big enough.
|
||||
|
||||
(cherry picked from commit a1982cf1bb95c818aa7b58988b5611dec80f2408)
|
||||
---
|
||||
bin/tests/system/additional/tests.sh | 2 +-
|
||||
lib/dns/include/dns/rdataset.h | 10 +++++++++-
|
||||
lib/dns/rbtdb.c | 2 +-
|
||||
lib/dns/rdataset.c | 7 ++++++-
|
||||
lib/dns/resolver.c | 19 ++++++++++++-------
|
||||
lib/ns/query.c | 12 ++++++++----
|
||||
6 files changed, 37 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/bin/tests/system/additional/tests.sh b/bin/tests/system/additional/tests.sh
|
||||
index 193c9f9..e1b0cfb 100644
|
||||
--- a/bin/tests/system/additional/tests.sh
|
||||
+++ b/bin/tests/system/additional/tests.sh
|
||||
@@ -279,7 +279,7 @@ n=$((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
|
||||
+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))
|
||||
diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h
|
||||
index f63591c..b28686a 100644
|
||||
--- a/lib/dns/include/dns/rdataset.h
|
||||
+++ b/lib/dns/include/dns/rdataset.h
|
||||
@@ -54,6 +54,8 @@
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
+#define DNS_RDATASET_MAXADDITIONAL 13
|
||||
+
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
typedef enum {
|
||||
@@ -453,7 +455,8 @@ dns_rdataset_towirepartial(dns_rdataset_t *rdataset,
|
||||
isc_result_t
|
||||
dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
|
||||
const dns_name_t *owner_name,
|
||||
- dns_additionaldatafunc_t add, void *arg);
|
||||
+ dns_additionaldatafunc_t add, void *arg,
|
||||
+ size_t limit);
|
||||
/*%<
|
||||
* For each rdata in rdataset, call 'add' for each name and type in the
|
||||
* rdata which is subject to additional section processing.
|
||||
@@ -472,10 +475,15 @@ 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().
|
||||
*
|
||||
+ *\li If 'limit' is non-zero and the number of the rdatasets is larger
|
||||
+ * than 'limit', no additional data will be processed.
|
||||
+ *
|
||||
* Returns:
|
||||
*
|
||||
*\li #ISC_R_SUCCESS
|
||||
*
|
||||
+ *\li #DNS_R_TOOMANYRECORDS in case rdataset count is larger than 'limit'
|
||||
+ *
|
||||
*\li Any error that dns_rdata_additionaldata() can return.
|
||||
*/
|
||||
|
||||
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
|
||||
index 5c2f0b2..c4db047 100644
|
||||
--- a/lib/dns/rbtdb.c
|
||||
+++ b/lib/dns/rbtdb.c
|
||||
@@ -10317,7 +10317,7 @@ no_glue:
|
||||
idx = hash_32(hash, rbtversion->glue_table_bits);
|
||||
|
||||
(void)dns_rdataset_additionaldata(rdataset, dns_rootname,
|
||||
- glue_nsdname_cb, &ctx);
|
||||
+ glue_nsdname_cb, &ctx, 0);
|
||||
|
||||
cur = isc_mem_get(rbtdb->common.mctx, sizeof(*cur));
|
||||
|
||||
diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c
|
||||
index 4d48203..0b450a9 100644
|
||||
--- a/lib/dns/rdataset.c
|
||||
+++ b/lib/dns/rdataset.c
|
||||
@@ -577,7 +577,8 @@ dns_rdataset_towire(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
|
||||
isc_result_t
|
||||
dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
|
||||
const dns_name_t *owner_name,
|
||||
- dns_additionaldatafunc_t add, void *arg) {
|
||||
+ dns_additionaldatafunc_t add, void *arg,
|
||||
+ size_t limit) {
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
isc_result_t result;
|
||||
|
||||
@@ -589,6 +590,10 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
|
||||
REQUIRE(DNS_RDATASET_VALID(rdataset));
|
||||
REQUIRE((rdataset->attributes & DNS_RDATASETATTR_QUESTION) == 0);
|
||||
|
||||
+ if (limit != 0 && dns_rdataset_count(rdataset) > limit) {
|
||||
+ return DNS_R_TOOMANYRECORDS;
|
||||
+ }
|
||||
+
|
||||
result = dns_rdataset_first(rdataset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
|
||||
index f8f53d2..bb0bfa1 100644
|
||||
--- a/lib/dns/resolver.c
|
||||
+++ b/lib/dns/resolver.c
|
||||
@@ -8904,7 +8904,7 @@ rctx_answer_any(respctx_t *rctx) {
|
||||
rdataset->trust = rctx->trust;
|
||||
|
||||
(void)dns_rdataset_additionaldata(rdataset, rctx->aname,
|
||||
- check_related, rctx);
|
||||
+ check_related, rctx, 0);
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
@@ -8952,7 +8952,7 @@ rctx_answer_match(respctx_t *rctx) {
|
||||
rctx->ardataset->attributes |= DNS_RDATASETATTR_CACHE;
|
||||
rctx->ardataset->trust = rctx->trust;
|
||||
(void)dns_rdataset_additionaldata(rctx->ardataset, rctx->aname,
|
||||
- check_related, rctx);
|
||||
+ check_related, rctx, 0);
|
||||
|
||||
for (sigrdataset = ISC_LIST_HEAD(rctx->aname->list);
|
||||
sigrdataset != NULL;
|
||||
@@ -9159,7 +9159,7 @@ rctx_authority_positive(respctx_t *rctx) {
|
||||
*/
|
||||
(void)dns_rdataset_additionaldata(
|
||||
rdataset, name, check_related,
|
||||
- rctx);
|
||||
+ rctx, 0);
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
@@ -9666,8 +9666,12 @@ rctx_referral(respctx_t *rctx) {
|
||||
*/
|
||||
INSIST(rctx->ns_rdataset != NULL);
|
||||
FCTX_ATTR_SET(fctx, FCTX_ATTR_GLUING);
|
||||
+
|
||||
+ /*
|
||||
+ * Mark the glue records in the additional section to be cached.
|
||||
+ */
|
||||
(void)dns_rdataset_additionaldata(rctx->ns_rdataset, rctx->ns_name,
|
||||
- check_related, rctx);
|
||||
+ check_related, rctx, 0);
|
||||
#if CHECK_FOR_GLUE_IN_ANSWER
|
||||
/*
|
||||
* Look in the answer section for "glue" that is incorrectly
|
||||
@@ -9679,8 +9683,9 @@ rctx_referral(respctx_t *rctx) {
|
||||
if (rctx->glue_in_answer &&
|
||||
(fctx->type == dns_rdatatype_aaaa || fctx->type == dns_rdatatype_a))
|
||||
{
|
||||
- (void)dns_rdataset_additionaldata(
|
||||
- rctx->ns_rdataset, rctx->ns_name, check_answer, fctx);
|
||||
+ (void)dns_rdataset_additionaldata(rctx->ns_rdataset,
|
||||
+ rctx->ns_name, check_answer,
|
||||
+ fctx, 0);
|
||||
}
|
||||
#endif /* if CHECK_FOR_GLUE_IN_ANSWER */
|
||||
FCTX_ATTR_CLR(fctx, FCTX_ATTR_GLUING);
|
||||
@@ -9782,7 +9787,7 @@ again:
|
||||
if (CHASE(rdataset)) {
|
||||
rdataset->attributes &= ~DNS_RDATASETATTR_CHASE;
|
||||
(void)dns_rdataset_additionaldata(
|
||||
- rdataset, name, check_related, rctx);
|
||||
+ rdataset, name, check_related, rctx, 0);
|
||||
rescan = true;
|
||||
}
|
||||
}
|
||||
diff --git a/lib/ns/query.c b/lib/ns/query.c
|
||||
index 5549e20..ded1eae 100644
|
||||
--- a/lib/ns/query.c
|
||||
+++ b/lib/ns/query.c
|
||||
@@ -2094,7 +2094,8 @@ addname:
|
||||
if (trdataset != NULL && dns_rdatatype_followadditional(type)) {
|
||||
if (client->additionaldepth++ < client->view->max_restarts) {
|
||||
eresult = dns_rdataset_additionaldata(
|
||||
- trdataset, fname, query_additional_cb, qctx);
|
||||
+ trdataset, fname, query_additional_cb, qctx,
|
||||
+ DNS_RDATASET_MAXADDITIONAL);
|
||||
}
|
||||
client->additionaldepth--;
|
||||
}
|
||||
@@ -2194,7 +2195,7 @@ regular:
|
||||
* We don't care if dns_rdataset_additionaldata() fails.
|
||||
*/
|
||||
(void)dns_rdataset_additionaldata(rdataset, name, query_additional_cb,
|
||||
- qctx);
|
||||
+ qctx, DNS_RDATASET_MAXADDITIONAL);
|
||||
CTRACE(ISC_LOG_DEBUG(3), "query_additional: done");
|
||||
}
|
||||
|
||||
@@ -2220,7 +2221,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
|
||||
- * already there. Also add any pertinent additional data.
|
||||
+ * already there. Also add any pertinent additional data, unless
|
||||
+ * the query was for type ANY.
|
||||
*
|
||||
* If 'dbuf' is not NULL, then '*namep' is the name whose data is
|
||||
* stored in 'dbuf'. In this case, query_addrrset() guarantees that
|
||||
@@ -2275,7 +2277,9 @@ query_addrrset(query_ctx_t *qctx, dns_name_t **namep,
|
||||
*/
|
||||
query_addtoname(mname, rdataset);
|
||||
query_setorder(qctx, mname, rdataset);
|
||||
- query_additional(qctx, mname, rdataset);
|
||||
+ if (qctx->qtype != dns_rdatatype_any) {
|
||||
+ query_additional(qctx, mname, rdataset);
|
||||
+ }
|
||||
|
||||
/*
|
||||
* Note: we only add SIGs if we've added the type they cover, so
|
||||
--
|
||||
2.48.1
|
||||
|
||||
@ -77,7 +77,7 @@ License: MPL-2.0 AND ISC AND MIT AND BSD-3-Clause AND BSD-2-Clause
|
||||
# ./lib/isc/tm.c BSD-2-clause and/or MPL-2.0
|
||||
# ./lib/isccfg/parser.c BSD-2-clause and/or MPL-2.0
|
||||
Version: 9.18.29
|
||||
Release: 2%{?dist}
|
||||
Release: 3%{?dist}
|
||||
Epoch: 32
|
||||
Url: https://www.isc.org/downloads/bind/
|
||||
#
|
||||
@ -119,6 +119,9 @@ Patch26: bind-9.18-unittest-netmgr-unstable.patch
|
||||
Patch27: bind-9.18-nsupdate-TLS.patch
|
||||
Patch28: bind-9.18-nsupdate-TLS-doc.patch
|
||||
Patch29: bind-9.18-nsupdate-TLS-tests.patch
|
||||
# https://gitlab.isc.org/isc-projects/bind9/-/commit/c6e6a7af8ac6b575dd3657b0f5cf4248d734c2b0
|
||||
Patch30: bind-9.18-CVE-2024-11187-pre-test.patch
|
||||
Patch31: bind-9.18-CVE-2024-11187.patch
|
||||
|
||||
%{?systemd_ordering}
|
||||
Requires: coreutils
|
||||
@ -966,6 +969,9 @@ fi;
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Mon Feb 03 2025 Petr Menšík <pemensik@redhat.com> - 32:9.18.29-3
|
||||
- Limit additional section records CPU processing (CVE-2024-11187)
|
||||
|
||||
* Mon Jan 27 2025 Petr Menšík <pemensik@redhat.com> - 32:9.18.29-2
|
||||
- Backport nsupdate TLS support into 9.18 (RHEL-76331)
|
||||
- Update nsupdate manual about new TLS options
|
||||
|
||||
Loading…
Reference in New Issue
Block a user