bind:fix CVE-2022-2795 CVE-2022-38177 CVE-2022-38178

CVE-2022-3080 CVE-2022-2881 CVE-2022-2906
Signed-off-by: huangyu <huangyu106@huawei.com>

(cherry picked from commit 6e6a5d5b26542aa0161f59446570b4ea26ab7d03)
This commit is contained in:
renmingshuai 2022-09-28 17:06:18 +08:00 committed by openeuler-sync-bot
parent abd68a5dd7
commit 7b039e89b3
7 changed files with 470 additions and 1 deletions

62
CVE-2022-2795.patch Normal file
View File

@ -0,0 +1,62 @@
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.
Conflict: NA
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/bf2ea6d8525bfd96a84dad221ba9e004adb710a8
(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 d2cf14bbc8b..73a0ee9f779 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);
--
GitLab

45
CVE-2022-2881.patch Normal file
View File

@ -0,0 +1,45 @@
From 13333db69f9b9710a98c86f44276e01e95420fa0 Mon Sep 17 00:00:00 2001
From: Evan Hunt <each@isc.org>
Date: Tue, 16 Aug 2022 16:26:02 -0700
Subject: [PATCH] compression buffer was not reused correctly
when the compression buffer was reused for multiple statistics
requests, responses could grow beyond the correct size. this was
because the buffer was not cleared before reuse; compressed data
was still written to the beginning of the buffer, but then the size
of used region was increased by the amount written, rather than set
to the amount written. this caused responses to grow larger and
larger, potentially reading past the end of the allocated buffer.
Conflict: NA
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/13333db69f9b9710a98c86f44276e01e95420fa0
(cherry picked from commit 47e9fa981e56a7a232f3219fe8a40525c79d748b)
---
lib/isc/httpd.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/isc/httpd.c b/lib/isc/httpd.c
index 776455a..e55330b 100644
--- a/lib/isc/httpd.c
+++ b/lib/isc/httpd.c
@@ -246,6 +246,8 @@ free_buffer(isc_mem_t *mctx, isc_buffer_t *buffer) {
if (r.length > 0) {
isc_mem_put(mctx, r.base, r.length);
}
+
+ isc_buffer_initnull(buffer);
}
static void
@@ -910,6 +912,7 @@ isc_httpd_compress(isc_httpd_t *httpd) {
if (result != ISC_R_SUCCESS) {
return (result);
}
+ isc_buffer_clear(&httpd->compbuffer);
isc_buffer_region(&httpd->compbuffer, &r);
/*
--
2.23.0

138
CVE-2022-2906.patch Normal file
View File

@ -0,0 +1,138 @@
From 73df5c80538970ee1fbc4fe3348109bdc281e197 Mon Sep 17 00:00:00 2001
From: Aram Sargsyan <aram@isc.org>
Date: Thu, 18 Aug 2022 08:59:09 +0000
Subject: [PATCH] Fix memory leaks in DH code
When used with OpenSSL v3.0.0+, the `openssldh_compare()`,
`openssldh_paramcompare()`, and `openssldh_todns()` functions
fail to cleanup the used memory on some error paths.
Use `DST_RET` instead of `return`, when there is memory to be
released before returning from the functions.
Conflict: NA
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/73df5c80538970ee1fbc4fe3348109bdc281e197
(cherry picked from commit 73d6bbff4e1df583810126fe58eac39bb52bc0d9)
---
lib/dns/openssldh_link.c | 45 +++++++++++++++++++++++-----------------
1 file changed, 26 insertions(+), 19 deletions(-)
diff --git a/lib/dns/openssldh_link.c b/lib/dns/openssldh_link.c
index 72b8209..ece97ea 100644
--- a/lib/dns/openssldh_link.c
+++ b/lib/dns/openssldh_link.c
@@ -68,6 +68,12 @@
"83655D23DCA3AD961C62F356208552BB9ED529077096966D" \
"670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"
+#define DST_RET(a) \
+ { \
+ ret = a; \
+ goto err; \
+ }
+
static BIGNUM *bn2 = NULL, *bn768 = NULL, *bn1024 = NULL, *bn1536 = NULL;
#if !HAVE_DH_GET0_KEY
@@ -180,7 +186,8 @@ openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv,
static bool
openssldh_compare(const dst_key_t *key1, const dst_key_t *key2) {
- DH *dh1, *dh2;
+ bool ret = true;
+ DH *dh1, *dh2;
const BIGNUM *pub_key1 = NULL, *pub_key2 = NULL;
const BIGNUM *priv_key1 = NULL, *priv_key2 = NULL;
const BIGNUM *p1 = NULL, *g1 = NULL, *p2 = NULL, *g2 = NULL;
@@ -202,23 +209,24 @@ openssldh_compare(const dst_key_t *key1, const dst_key_t *key2) {
if (BN_cmp(p1, p2) != 0 || BN_cmp(g1, g2) != 0 ||
BN_cmp(pub_key1, pub_key2) != 0)
{
- return (false);
+ DST_RET(false);
}
if (priv_key1 != NULL || priv_key2 != NULL) {
- if (priv_key1 == NULL || priv_key2 == NULL) {
- return (false);
- }
- if (BN_cmp(priv_key1, priv_key2) != 0) {
- return (false);
+ if (priv_key1 == NULL || priv_key2 == NULL ||
+ BN_cmp(priv_key1, priv_key2) != 0) {
+ DST_RET(false);
}
}
- return (true);
+
+err:
+ return (ret);
}
static bool
openssldh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) {
- DH *dh1, *dh2;
+ bool ret = true;
+ DH *dh1, *dh2;
const BIGNUM *p1 = NULL, *g1 = NULL, *p2 = NULL, *g2 = NULL;
dh1 = key1->keydata.dh;
@@ -234,9 +242,11 @@ openssldh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) {
DH_get0_pqg(dh2, &p2, NULL, &g2);
if (BN_cmp(p1, p2) != 0 || BN_cmp(g1, g2) != 0) {
- return (false);
+ DST_RET(false);
}
- return (true);
+
+err:
+ return (ret);
}
static int
@@ -386,7 +396,8 @@ uint16_fromregion(isc_region_t *region) {
static isc_result_t
openssldh_todns(const dst_key_t *key, isc_buffer_t *data) {
- DH *dh;
+ isc_result_t ret = ISC_R_SUCCESS;
+ DH *dh;
const BIGNUM *pub_key = NULL, *p = NULL, *g = NULL;
isc_region_t r;
uint16_t dnslen, plen, glen, publen;
@@ -412,7 +423,7 @@ openssldh_todns(const dst_key_t *key, isc_buffer_t *data) {
publen = BN_num_bytes(pub_key);
dnslen = plen + glen + publen + 6;
if (r.length < (unsigned int)dnslen) {
- return (ISC_R_NOSPACE);
+ DST_RET(ISC_R_NOSPACE);
}
uint16_toregion(plen, &r);
@@ -441,7 +452,8 @@ openssldh_todns(const dst_key_t *key, isc_buffer_t *data) {
isc_buffer_add(data, dnslen);
- return (ISC_R_SUCCESS);
+err:
+ return (ret);
}
static isc_result_t
@@ -659,11 +671,6 @@ openssldh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
DH *dh = NULL;
BIGNUM *pub_key = NULL, *priv_key = NULL, *p = NULL, *g = NULL;
isc_mem_t *mctx;
-#define DST_RET(a) \
- { \
- ret = a; \
- goto err; \
- }
UNUSED(pub);
mctx = key->mctx;
--
2.23.0

149
CVE-2022-3080.patch Normal file
View File

@ -0,0 +1,149 @@
From 3f68e2ad838b3c12a725ccb1082a54b0e8b69562 Mon Sep 17 00:00:00 2001
From: Matthijs Mekking <matthijs@isc.org>
Date: Fri, 2 Sep 2022 16:50:39 +0200
Subject: [PATCH] Only refresh RRset once
Don't attempt to resolve DNS responses for intermediate results. This
may create multiple refreshes and can cause a crash.
One scenario is where for the query there is a CNAME and canonical
answer in cache that are both stale. This will trigger a refresh of
the RRsets because we encountered stale data and we prioritized it over
the lookup. It will trigger a refresh of both RRsets. When we start
recursing, it will detect a recursion loop because the recursion
parameters will eventually be the same. In 'dns_resolver_destroyfetch'
the sanity check fails, one of the callers did not get its event back
before trying to destroy the fetch.
Move the call to 'query_refresh_rrset' to 'ns_query_done', so that it
is only called once per client request.
Another scenario is where for the query there is a stale CNAME in the
cache that points to a record that is also in cache but not stale. This
will trigger a refresh of the RRset (because we encountered stale data
and we prioritized it over the lookup).
We mark RRsets that we add to the message with
DNS_RDATASETATTR_STALE_ADDED to prevent adding a duplicate RRset when
a stale lookup and a normal lookup conflict with each other. However,
the other non-stale RRset when following a CNAME chain will be added to
the message without setting that attribute, because it is not stale.
This is a variant of the bug in #2594. The fix covered the same crash
but for stale-answer-client-timeout > 0.
Fix this by clearing all RRsets from the message before refreshing.
This requires the refresh to happen after the query is send back to
the client.
Conflict: NA
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/13333db69f9b9710a98c86f44276e01e95420fa0
(cherry picked from commit d939d2ecde5639d11acd6eac33a997b3e3c78b02)
---
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 142ef8c6c1d..be0dadd5099 100644
--- a/lib/ns/include/ns/query.h
+++ b/lib/ns/include/ns/query.h
@@ -147,6 +147,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 5c2701eb718..98cfffe8c36 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -5737,7 +5737,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");
@@ -5921,8 +5920,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 {
/*
@@ -5960,17 +5958,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);
}
@@ -7760,11 +7747,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
@@ -11478,9 +11468,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;
}
--
GitLab

26
CVE-2022-38177.patch Normal file
View File

@ -0,0 +1,26 @@
From 5b2282afff760b1ed3471f6666bdfe8e1d34e590 Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Thu, 11 Aug 2022 15:15:34 +1000
Subject: [PATCH] Free eckey on siglen mismatch
Conflict: NA
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/5b2282afff760b1ed3471f6666bdfe8e1d34e590
---
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 1f16ca70738..5ee4342b387 100644
--- a/lib/dns/opensslecdsa_link.c
+++ b/lib/dns/opensslecdsa_link.c
@@ -230,7 +230,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)) {
--
GitLab

33
CVE-2022-38178.patch Normal file
View File

@ -0,0 +1,33 @@
From 1af23378ebb11da2eb0f412e4563d6c4165fbd3d Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Thu, 11 Aug 2022 15:28:13 +1000
Subject: [PATCH] Free ctx on invalid siglen
Conflict: NA
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/1af23378ebb11da2eb0f412e4563d6c4165fbd3d
(cherry picked from commit 6ddb480a84836641a0711768a94122972c166825)
---
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 b5ab3b3d8a2..12fdf650eb6 100644
--- a/lib/dns/openssleddsa_link.c
+++ b/lib/dns/openssleddsa_link.c
@@ -236,11 +236,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);
--
GitLab

View File

@ -30,7 +30,7 @@ Summary: The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) serv
Name: bind Name: bind
License: MPLv2.0 License: MPLv2.0
Version: 9.16.23 Version: 9.16.23
Release: 9 Release: 10
Epoch: 32 Epoch: 32
Url: https://www.isc.org/downloads/bind/ Url: https://www.isc.org/downloads/bind/
# #
@ -81,6 +81,12 @@ Patch164:bind-9.11-rh1666814.patch
Patch6000: CVE-2022-0396.patch Patch6000: CVE-2022-0396.patch
Patch6001: CVE-2021-25220.patch Patch6001: CVE-2021-25220.patch
Patch6002: CVE-2022-2795.patch
Patch6003: CVE-2022-38177.patch
Patch6004: CVE-2022-38178.patch
Patch6005: CVE-2022-3080.patch
Patch6006: CVE-2022-2881.patch
Patch6007: CVE-2022-2906.patch
Patch9000: bugfix-limit-numbers-of-test-threads.patch Patch9000: bugfix-limit-numbers-of-test-threads.patch
%{?systemd_ordering} %{?systemd_ordering}
@ -379,6 +385,12 @@ in HTML and PDF format.
%patch6000 -p1 %patch6000 -p1
%patch6001 -p1 %patch6001 -p1
%patch6002 -p1
%patch6003 -p1
%patch6004 -p1
%patch6005 -p1
%patch6006 -p1
%patch6007 -p1
%patch9000 -p1 %patch9000 -p1
%if %{with PKCS11} %if %{with PKCS11}
@ -1103,6 +1115,10 @@ fi;
%endif %endif
%changelog %changelog
* Wed Sep 28 2022 huangyu <huangyu106@huawei.com> - 32:9.16.23-10
- DESC: fix CVE-2022-2795 CVE-2022-38177 CVE-2022-38178
CVE-2022-3080 CVE-2022-2906 CVE-2022-2881
* Wed Aug 31 2022 yangchenguang <yangchenguang@uniontech.com> - 32:9.16.23-9 * Wed Aug 31 2022 yangchenguang <yangchenguang@uniontech.com> - 32:9.16.23-9
- DESC: fix downgrade bind-utils conflict bind-dnssec-doc - DESC: fix downgrade bind-utils conflict bind-dnssec-doc