From 1a0f154983d5da0b3afd60fd770eec48f7a9a602 Mon Sep 17 00:00:00 2001 From: pojunxing Date: Wed, 19 Feb 2025 16:41:23 +0800 Subject: [PATCH] fix CVE-2024-11187 --- backport-CVE-2024-11187.patch | 310 ++++++++++++++++++++++++++++++++++ bind.spec | 9 +- 2 files changed, 318 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2024-11187.patch diff --git a/backport-CVE-2024-11187.patch b/backport-CVE-2024-11187.patch new file mode 100644 index 0000000..d1a848a --- /dev/null +++ b/backport-CVE-2024-11187.patch @@ -0,0 +1,310 @@ +From fa7b7973e36056440dd688c7f312c89600d4f8cf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= +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) + +Conflict:Context adaptation +Reference:https://downloads.isc.org/isc/bind9/9.18.33/patches/0001-CVE-2024-11187.patch + +--- + bin/tests/system/additional/tests.sh | 2 +- + bin/tests/system/resolver/ns4/named.noaa | 5 ----- + bin/tests/system/resolver/tests.sh | 8 ++++++++ + lib/dns/include/dns/rdataset.h | 10 +++++++++- + lib/dns/rbtdb.c | 2 +- + lib/dns/rdataset.c | 7 ++++++- + lib/dns/resolver.c | 16 ++++++++++------ + lib/isc/include/isc/result.h | 3 ++- + lib/isc/result.c | 6 ++++-- + lib/ns/query.c | 13 +++++++++---- + 10 files changed, 50 insertions(+), 22 deletions(-) + delete mode 100644 bin/tests/system/resolver/ns4/named.noaa + +diff --git a/bin/tests/system/additional/tests.sh b/bin/tests/system/additional/tests.sh +index 025f11f..539484c 100644 +--- a/bin/tests/system/additional/tests.sh ++++ b/bin/tests/system/additional/tests.sh +@@ -260,7 +260,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 ++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 +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 +--- a/bin/tests/system/resolver/ns4/named.noaa ++++ /dev/null +@@ -1,5 +0,0 @@ +-Copyright (C) Internet Systems Consortium, Inc. ("ISC") +- +-See COPYRIGHT in the source root or https://isc.org/copyright.html for terms. +- +-Add -T noaa. +diff --git a/bin/tests/system/resolver/tests.sh b/bin/tests/system/resolver/tests.sh +index 6c69c11..87b444d 100755 +--- a/bin/tests/system/resolver/tests.sh ++++ b/bin/tests/system/resolver/tests.sh +@@ -289,6 +289,10 @@ done + if [ $ret != 0 ]; then echo_i "failed"; fi + status=`expr $status + $ret` + ++stop_server ns4 ++touch ns4/named.noaa ++start_server --noclean --restart --port ${PORT} ns4 || ret=1 ++ + n=`expr $n + 1` + echo_i "RT21594 regression test check setup ($n)" + ret=0 +@@ -316,6 +320,10 @@ grep "status: NOERROR" dig.ns5.out.${n} > /dev/null || ret=1 + if [ $ret != 0 ]; then echo_i "failed"; fi + status=`expr $status + $ret` + ++stop_server ns4 ++rm ns4/named.noaa ++start_server --noclean --restart --port ${PORT} ns4 || ret=1 ++ + n=`expr $n + 1` + echo_i "RT21594 regression test NXDOMAIN answers ($n)" + ret=0 +diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h +index f2585ef..cba2234 100644 +--- a/lib/dns/include/dns/rdataset.h ++++ b/lib/dns/include/dns/rdataset.h +@@ -53,6 +53,8 @@ + #include + #include + ++#define DNS_RDATASET_MAXADDITIONAL 13 ++ + ISC_LANG_BEGINDECLS + + typedef enum { +@@ -439,7 +441,8 @@ dns_rdataset_towirepartial(dns_rdataset_t *rdataset, + + isc_result_t + dns_rdataset_additionaldata(dns_rdataset_t *rdataset, +- 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. +@@ -458,10 +461,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 a6da874..e20aef7 100644 +--- a/lib/dns/rbtdb.c ++++ b/lib/dns/rbtdb.c +@@ -10568,7 +10568,7 @@ no_glue: + maybe_rehash_gluetable(rbtversion); + idx = hash_32(hash, rbtversion->glue_table_bits); + +- (void)dns_rdataset_additionaldata(rdataset, glue_nsdname_cb, &ctx); ++ (void)dns_rdataset_additionaldata(rdataset, 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 bf9e7af..19a0051 100644 +--- a/lib/dns/rdataset.c ++++ b/lib/dns/rdataset.c +@@ -576,7 +576,8 @@ 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) { ++ dns_additionaldatafunc_t add, void *arg, ++ size_t limit) { + dns_rdata_t rdata = DNS_RDATA_INIT; + isc_result_t result; + +@@ -588,6 +589,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 cc8c9ab..2f932be 100644 +--- a/lib/dns/resolver.c ++++ b/lib/dns/resolver.c +@@ -8944,7 +8944,7 @@ rctx_answer_any(respctx_t *rctx) { + rdataset->trust = rctx->trust; + + (void)dns_rdataset_additionaldata(rdataset, check_related, +- rctx); ++ rctx, 0); + } + + return (ISC_R_SUCCESS); +@@ -8991,7 +8991,7 @@ rctx_answer_match(respctx_t *rctx) { + rctx->ardataset->attributes |= DNS_RDATASETATTR_ANSWER; + rctx->ardataset->attributes |= DNS_RDATASETATTR_CACHE; + rctx->ardataset->trust = rctx->trust; +- (void)dns_rdataset_additionaldata(rctx->ardataset, check_related, rctx); ++ (void)dns_rdataset_additionaldata(rctx->ardataset, check_related, rctx, 0); + + for (sigrdataset = ISC_LIST_HEAD(rctx->aname->list); + sigrdataset != NULL; +@@ -9197,7 +9197,7 @@ rctx_authority_positive(respctx_t *rctx) { + * to this rdataset. + */ + (void)dns_rdataset_additionaldata( +- rdataset, check_related, rctx); ++ rdataset, check_related, rctx, 0); + done = true; + } + } +@@ -9701,8 +9701,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, check_related, +- rctx); ++ rctx, 0); + #if CHECK_FOR_GLUE_IN_ANSWER + /* + * Look in the answer section for "glue" that is incorrectly +@@ -9715,7 +9719,7 @@ rctx_referral(respctx_t *rctx) { + (fctx->type == dns_rdatatype_aaaa || fctx->type == dns_rdatatype_a)) + { + (void)dns_rdataset_additionaldata(rctx->ns_rdataset, +- check_answer, fctx); ++ check_answer, fctx, 0); + } + #endif /* if CHECK_FOR_GLUE_IN_ANSWER */ + FCTX_ATTR_CLR(fctx, FCTX_ATTR_GLUING); +@@ -9825,7 +9829,7 @@ again: + if (CHASE(rdataset)) { + rdataset->attributes &= ~DNS_RDATASETATTR_CHASE; + (void)dns_rdataset_additionaldata( +- rdataset, check_related, rctx); ++ rdataset, check_related, rctx, 0); + rescan = true; + } + } +diff --git a/lib/isc/include/isc/result.h b/lib/isc/include/isc/result.h +index 21071c7..2b14d66 100644 +--- a/lib/isc/include/isc/result.h ++++ b/lib/isc/include/isc/result.h +@@ -90,9 +90,10 @@ + #define ISC_R_IPV4PREFIX 69 /*%< IPv4 prefix */ + #define ISC_R_TLSERROR 70 /*%< TLS error */ + #define ISC_R_HTTP2ALPNERROR 71 /*%< ALPN for HTTP/2 failed */ ++#define DNS_R_TOOMANYRECORDS 72 /*%< too many records */ + + /*% Not a result code: the number of results. */ +-#define ISC_R_NRESULTS 72 ++#define ISC_R_NRESULTS 73 + + ISC_LANG_BEGINDECLS + +diff --git a/lib/isc/result.c b/lib/isc/result.c +index 72e7a3c..a038b6e 100644 +--- a/lib/isc/result.c ++++ b/lib/isc/result.c +@@ -102,7 +102,8 @@ static const char *description[ISC_R_NRESULTS] = { + "default", /*%< 68 */ + "IPv4 prefix", /*%< 69 */ + "TLS error", /*%< 70 */ +- "ALPN for HTTP/2 failed" /*%< 71 */ ++ "ALPN for HTTP/2 failed", /*%< 71 */ ++ "too many records" /*%< 72 */ + }; + + static const char *identifier[ISC_R_NRESULTS] = { "ISC_R_SUCCESS", +@@ -176,7 +177,8 @@ static const char *identifier[ISC_R_NRESULTS] = { "ISC_R_SUCCESS", + "ISC_R_DEFAULT", + "ISC_R_IPV4PREFIX", + "ISC_R_TLSERROR", +- "ISC_R_HTTP2ALPNERROR" }; ++ "ISC_R_HTTP2ALPNERROR", ++ "DNS_R_TOOMANYRECODES" }; + + #define ISC_RESULT_RESULTSET 2 + #define ISC_RESULT_UNAVAILABLESET 3 +diff --git a/lib/ns/query.c b/lib/ns/query.c +index 520203f..15e321f 100644 +--- a/lib/ns/query.c ++++ b/lib/ns/query.c +@@ -2031,7 +2031,8 @@ addname: + */ + if (trdataset != NULL && dns_rdatatype_followadditional(type)) { + eresult = dns_rdataset_additionaldata( +- trdataset, query_additional_cb, qctx); ++ trdataset, query_additional_cb, qctx, ++ DNS_RDATASET_MAXADDITIONAL); + } + + cleanup: +@@ -2122,7 +2123,8 @@ regular: + * Add other additional data if needed. + * We don't care if dns_rdataset_additionaldata() fails. + */ +- (void)dns_rdataset_additionaldata(rdataset, query_additional_cb, qctx); ++ (void)dns_rdataset_additionaldata(rdataset, query_additional_cb, qctx, ++ DNS_RDATASET_MAXADDITIONAL); + CTRACE(ISC_LOG_DEBUG(3), "query_additional: done"); + } + +@@ -2148,7 +2150,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 +@@ -2203,7 +2206,9 @@ query_addrrset(query_ctx_t *qctx, dns_name_t **namep, + */ + query_addtoname(mname, rdataset); + query_setorder(qctx, mname, rdataset); +- query_additional(qctx, rdataset); ++ if (qctx->qtype != dns_rdatatype_any) { ++ query_additional(qctx, rdataset); ++ } + + /* + * Note: we only add SIGs if we've added the type they cover, so +-- +2.33.0 + diff --git a/bind.spec b/bind.spec index 8cfb596..1522773 100644 --- a/bind.spec +++ b/bind.spec @@ -30,7 +30,7 @@ Summary: The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) serv Name: bind License: MPLv2.0 Version: 9.16.23 -Release: 23 +Release: 24 Epoch: 32 Url: https://www.isc.org/downloads/bind/ # @@ -246,6 +246,7 @@ Patch6162:backport-0001-CVE-2024-1737.patch Patch6163:backport-0002-CVE-2024-1737.patch Patch6164:backport-0003-CVE-2024-1737.patch Patch6165:backport-0004-CVE-2024-1737.patch +Patch6166:backport-CVE-2024-11187.patch Patch9000:bugfix-limit-numbers-of-test-threads.patch @@ -1255,6 +1256,12 @@ fi; %endif %changelog +* Wed Feb 19 2025 chengyechun - 32:9.16.23-24 +- Type:CVE +- CVE:CVE-2024-11187 +- SUG:NA +- DESC:fix CVE-2024-11187 + * Fri Aug 02 2024 chengyechun - 32:9.16.23-23 - Type:CVE - CVE:CVE-2024-1975,CVE-2024-4076,CVE-2024-1737 -- Gitee