diff --git a/CVE-2024-1737-runtime-env.patch b/CVE-2024-1737-runtime-env.patch new file mode 100644 index 0000000000000000000000000000000000000000..06a35ac0327cbad696d5ec7ab16332be5f45449c --- /dev/null +++ b/CVE-2024-1737-runtime-env.patch @@ -0,0 +1,118 @@ +From be1ecff9424cdea6e531e7e9d91875211bd64054 Mon Sep 17 00:00:00 2001 +From: pangqing +Date: Tue, 10 Sep 2024 11:08:28 +0800 +Subject: [PATCH] Allow global runtime definition by DNS_RBTDB_MAX_RTYPES + +--- + lib/dns/rbtdb.c | 20 ++++++++++++++++++-- + lib/dns/rdataslab.c | 21 +++++++++++++++++++-- + 2 files changed, 37 insertions(+), 4 deletions(-) + +diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c +index 79872d9..6803e53 100644 +--- a/lib/dns/rbtdb.c ++++ b/lib/dns/rbtdb.c +@@ -6630,15 +6630,29 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, + #define DNS_RBTDB_MAX_RTYPES 100 + #endif /* DNS_RBTDB_MAX_RTYPES */ + ++static uint32_t dns_g_rbtdb_max_rtypes = DNS_RBTDB_MAX_RTYPES; ++ ++static void ++init_max_rtypes(void) { ++ /* Red Hat change, allow setting different max value by environment. */ ++ const char *max = getenv("DNS_RBTDB_MAX_RTYPES"); ++ if (max) { ++ char *endp = NULL; ++ long l = strtol(max, &endp, 10); ++ if (max != endp && endp && !*endp && l >= 0) ++ dns_g_rbtdb_max_rtypes = l; ++ } ++} ++ + static bool + overmaxtype(dns_rbtdb_t *rbtdb, uint32_t ntypes) { + UNUSED(rbtdb); + +- if (DNS_RBTDB_MAX_RTYPES == 0) { ++ if (dns_g_rbtdb_max_rtypes == 0) { + return (false); + } + +- return (ntypes >= DNS_RBTDB_MAX_RTYPES); ++ return (ntypes >= dns_g_rbtdb_max_rtypes); + } + + static bool +@@ -8454,6 +8468,7 @@ static dns_dbmethods_t cache_methods = { + NULL + }; + ++static isc_once_t once_db = ISC_ONCE_INIT; + isc_result_t + #ifdef DNS_RBTDB_VERSION64 + dns_rbtdb64_create +@@ -8473,6 +8488,7 @@ dns_rbtdb_create + + /* Keep the compiler happy. */ + UNUSED(driverarg); ++ RUNTIME_CHECK(isc_once_do(&once_db, init_max_rtypes) == ISC_R_SUCCESS); + + rbtdb = isc_mem_get(mctx, sizeof(*rbtdb)); + if (rbtdb == NULL) +diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c +index c7eeee4..a68508b 100644 +--- a/lib/dns/rdataslab.c ++++ b/lib/dns/rdataslab.c +@@ -17,6 +17,7 @@ + #include + + #include ++#include + #include + #include /* Required for HP/UX (and others?) */ + #include +@@ -119,6 +120,21 @@ fillin_offsets(unsigned char *offsetbase, unsigned int *offsettable, + #define DNS_RDATASET_MAX_RECORDS 100 + #endif /* DNS_RDATASET_MAX_RECORDS */ + ++static unsigned int dns_g_rdataset_max_records = DNS_RDATASET_MAX_RECORDS; ++static isc_once_t once = ISC_ONCE_INIT; ++ ++static void ++init_max_records(void) { ++ /* Red Hat change, allow setting different max value by environment. */ ++ const char *max = getenv("DNS_RDATASET_MAX_RECORDS"); ++ if (max) { ++ char *endp = NULL; ++ long l = strtol(max, &endp, 10); ++ if (max != endp && endp && !*endp && l > 0) ++ dns_g_rdataset_max_records = l; ++ } ++} ++ + isc_result_t + dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, + isc_region_t *region, unsigned int reservelen) +@@ -164,7 +180,8 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, + *rawbuf = 0; + return (ISC_R_SUCCESS); + } +- if (nitems > DNS_RDATASET_MAX_RECORDS) { ++ RUNTIME_CHECK(isc_once_do(&once, init_max_records) == ISC_R_SUCCESS); ++ if (nitems > dns_g_rdataset_max_records) { + return (DNS_R_TOOMANYRECORDS); + } + +@@ -657,7 +674,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, + ncurrent += (4 * ncount); + #endif + INSIST(ocount > 0 && ncount > 0); +- if (ocount + ncount > DNS_RDATASET_MAX_RECORDS) { ++ if (ocount + ncount > dns_g_rdataset_max_records) { + return (DNS_R_TOOMANYRECORDS); + } + +-- +2.39.3 + diff --git a/CVE-2024-1737.patch b/CVE-2024-1737.patch new file mode 100644 index 0000000000000000000000000000000000000000..2d7a325adb034bbd587822126a7ed3670ebffd86 --- /dev/null +++ b/CVE-2024-1737.patch @@ -0,0 +1,105 @@ +From 5c2df01a9dd7be9d0f32b6262e7a92880f3b4bd4 Mon Sep 17 00:00:00 2001 +From: pangqing +Date: Tue, 10 Sep 2024 10:39:17 +0800 +Subject: [PATCH] CVE-2024-1737 + +--- + configure | 2 +- + lib/dns/rbtdb.c | 25 +++++++++++++++++++++++++ + lib/dns/rdataslab.c | 10 ++++++++++ + 3 files changed, 36 insertions(+), 1 deletion(-) + +diff --git a/configure b/configure +index c83773a..af0ad47 100755 +--- a/configure ++++ b/configure +@@ -12003,7 +12003,7 @@ fi + XTARGETS= + case "$enable_developer" in + yes) +- STD_CDEFINES="$STD_CDEFINES -DISC_LIST_CHECKINIT=1" ++ STD_CDEFINES="$STD_CDEFINES -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_atf+set}" = set || with_atf=yes +diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c +index 4171039..79872d9 100644 +--- a/lib/dns/rbtdb.c ++++ b/lib/dns/rbtdb.c +@@ -18,6 +18,7 @@ + #ifdef HAVE_INTTYPES_H + #include /* uintptr_t */ + #endif ++#include + + #include + #include +@@ -6625,6 +6626,30 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, + return (ISC_R_SUCCESS); + } + ++#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)); ++} ++ + static inline isc_boolean_t + delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, + rbtdb_rdatatype_t type) +diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c +index 6615abc..c7eeee4 100644 +--- a/lib/dns/rdataslab.c ++++ b/lib/dns/rdataslab.c +@@ -115,6 +115,10 @@ fillin_offsets(unsigned char *offsetbase, unsigned int *offsettable, + } + #endif + ++#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) +@@ -160,6 +164,9 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, + *rawbuf = 0; + return (ISC_R_SUCCESS); + } ++ if (nitems > DNS_RDATASET_MAX_RECORDS) { ++ return (DNS_R_TOOMANYRECORDS); ++ } + + if (nitems > 0xffff) + return (ISC_R_NOSPACE); +@@ -650,6 +657,9 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, + ncurrent += (4 * ncount); + #endif + INSIST(ocount > 0 && ncount > 0); ++ if (ocount + ncount > DNS_RDATASET_MAX_RECORDS) { ++ return (DNS_R_TOOMANYRECORDS); ++ } + + #if DNS_RDATASET_FIXED + oncount = ncount; +-- +2.39.3 + diff --git a/CVE-2024-1975.patch b/CVE-2024-1975.patch new file mode 100644 index 0000000000000000000000000000000000000000..eb6e8ac9d5c79bd0ef134483e58ef196594181fb --- /dev/null +++ b/CVE-2024-1975.patch @@ -0,0 +1,168 @@ +From 08aef37c5eaf01bc51aa2eae18c4397c5b944f1d Mon Sep 17 00:00:00 2001 +From: pangqing +Date: Mon, 9 Sep 2024 18:08:16 +0800 +Subject: [PATCH] CVE-2024-1975 + +--- + bin/named/client.c | 7 +++ + bin/tests/system/tsiggss/authsock.pl | 4 ++ + lib/dns/message.c | 92 +++------------------------- + 3 files changed, 18 insertions(+), 85 deletions(-) + +diff --git a/bin/named/client.c b/bin/named/client.c +index 66ebbf7..9cae6ce 100644 +--- a/bin/named/client.c ++++ b/bin/named/client.c +@@ -2893,6 +2893,13 @@ client_request(isc_task_t *task, isc_event_t *event) { + 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; +diff --git a/bin/tests/system/tsiggss/authsock.pl b/bin/tests/system/tsiggss/authsock.pl +index 57a72b2..fa3a084 100644 +--- a/bin/tests/system/tsiggss/authsock.pl ++++ b/bin/tests/system/tsiggss/authsock.pl +@@ -30,6 +30,9 @@ if (!defined($path)) { + print("Usage: authsock.pl --path= --type=type --pidfile=pidfile\n"); + 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 +@@ -48,6 +51,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/lib/dns/message.c b/lib/dns/message.c +index c97b7bd..a69dab7 100644 +--- a/lib/dns/message.c ++++ b/lib/dns/message.c +@@ -3329,102 +3329,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 +- 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, ISC_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)); + } + } + +-- +2.39.3 + diff --git a/bind.spec b/bind.spec index 704662ea651dc292a8a4977cd86d90c4c2cdbdb3..f657edea63554d1955bc5cb24893e0615a014b03 100644 --- a/bind.spec +++ b/bind.spec @@ -64,7 +64,7 @@ Summary: The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) serv Name: bind License: MPLv2.0 Version: 9.11.4 -Release: 26%{?PATCHVER:.%{PATCHVER}}%{?PREVER:.%{PREVER}}%{?dist}.16 +Release: 26%{?PATCHVER:.%{PATCHVER}}%{?PREVER:.%{PREVER}}%{?dist}.17 Epoch: 32 Url: http://www.isc.org/products/BIND/ # @@ -194,6 +194,9 @@ Patch207: bind-9.11.4-CVE-2023-50387.patch Patch208: bind-9.11.4-missing-DBC-checks.patch Patch209: bind-9.11.4-CVE-2023-4408.patch Patch210: bind-9.11.4-CVE-2023-2828-fixup.patch +Patch211: CVE-2024-1975.patch +Patch212: CVE-2024-1737.patch +Patch213: CVE-2024-1737-runtime-env.patch # SDB patches Patch11: bind-9.3.2b2-sdbsrc.patch @@ -580,6 +583,9 @@ are used for building ISC DHCP. %patch208 -p1 -b .DBC-checks %patch209 -p1 -b .CVE-2023-4408 %patch210 -p1 -b .CVE-2023-2828-fixup +%patch211 -p1 -b .CVE-2024-1975 +%patch212 -p1 -b .CVE-2024-1737 +%patch213 -p1 -b .CVE-2024-1737-runtime-env # Override upstream builtin keys cp -fp %{SOURCE29} bind.keys @@ -1561,6 +1567,9 @@ rm -rf ${RPM_BUILD_ROOT} %changelog +* Mon Sep 09 2024 pangqing - 32:9.11.4-26.P2.17 +- CVE-2024-1975 and CVE-2024-1737 + * Tue Apr 16 2024 Stepan Broz - 32:9.11.4-26.P2.16 - Prevent increased CPU consumption in DNSSEC validator (CVE-2023-50387 CVE-2023-50868)