diff --git a/SOURCES/bind-9.11-CVE-2024-1737-runtime-env.patch b/SOURCES/bind-9.11-CVE-2024-1737-runtime-env.patch new file mode 100644 index 0000000..422ff9f --- /dev/null +++ b/SOURCES/bind-9.11-CVE-2024-1737-runtime-env.patch @@ -0,0 +1,133 @@ +From 0a7909045f9e1bf74c1f0fd561a8ef5f55481e8f Mon Sep 17 00:00:00 2001 +From: Petr Mensik +Date: Mon, 29 Jul 2024 16:20:50 +0200 +Subject: [PATCH] Allow global runtime definition by DNS_RBTDB_MAX_RTYPES + +Modify rbtdb to not set it only at runtime, but allow setting that also +in runtime via environment variable. It is still possible to modify +default during the build define. In addition to it allows runtime change +also. Can be positive number to set limit, 0 disabled the check. + +Similarly add also DNS_RDATASET_MAX_RECORDS to set maximum number of +records for a single name. This must be positive number, 0 is no accepted. + +These replaces max-records-per-type and max-types-per-name in later +versions. But can be configured only by environment and can be +configured only globally, not in each view or zone. +--- + lib/dns/rbtdb.c | 21 +++++++++++++++++++-- + lib/dns/rdataslab.c | 24 ++++++++++++++++++++++-- + 2 files changed, 41 insertions(+), 4 deletions(-) + +diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c +index a3cb8dc871..0104c3ee36 100644 +--- a/lib/dns/rbtdb.c ++++ b/lib/dns/rbtdb.c +@@ -6320,15 +6320,29 @@ update_recordsandbytes(bool add, 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 +@@ -8831,6 +8845,8 @@ static dns_dbmethods_t cache_methods = { + getservestalettl + }; + ++static isc_once_t once_db = ISC_ONCE_INIT; ++ + isc_result_t + #ifdef DNS_RBTDB_VERSION64 + dns_rbtdb64_create +@@ -8850,6 +8866,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 347b7d2ce8..9566f79671 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,23 @@ 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) +@@ -165,7 +183,9 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, + 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); + } + +@@ -662,7 +682,7 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, + #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.45.2 + diff --git a/SOURCES/bind-9.11-CVE-2024-1737.patch b/SOURCES/bind-9.11-CVE-2024-1737.patch new file mode 100644 index 0000000..ba9e032 --- /dev/null +++ b/SOURCES/bind-9.11-CVE-2024-1737.patch @@ -0,0 +1,317 @@ +From 71df06e2bf3da31c5d542fb33dbda67b21537322 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= +Date: Fri, 1 Mar 2024 08:26:07 +0100 +Subject: [PATCH] [9.11][CVE-2024-1737] Add a limit to the number of RRs in + RRSets + +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= + +(cherry picked from commit c5c4d00c38530390c9e1ae4c98b65fbbadfe9e5e) +(cherry picked from commit 7f705778af729ada7fec36ac4b456c73329bd996) +(cherry picked from commit b9b5485b22c364fb88c27aa04bad4c8f616da3fa) + +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= + +(cherry picked from commit 538b843d84f49ba5125ff545e3d0cf1c8434a8f2) +(cherry picked from commit 3f10d6eff035702796ba82cd28b9f7cf9836e743) + +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 23a4652346fb2877d6246b1eebaa967969dbde16) + +[9.11][CVE-2024-1737 (part 2)] Be smarter about refusing to add many RR types to the database + +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 3e0a67e4bdb253dae3a03a45c1aa117239a3313d) + +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 e4d7ce686bb38428eddc7e33b40057d68eca9a6e) +--- + configure | 2 +- + configure.ac | 2 +- + lib/dns/rbtdb.c | 114 +++++++++++++++++++++++++++++++++++++++++++- + lib/dns/rdataslab.c | 12 +++++ + 4 files changed, 126 insertions(+), 4 deletions(-) + +diff --git a/configure b/configure +index e060e9d..6421c9b 100755 +--- a/configure ++++ b/configure +@@ -12189,7 +12189,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 "${enable_filter_aaaa+set}" = set || enable_filter_aaaa=yes +diff --git a/configure.ac b/configure.ac +index 83cad4a..1c35ce9 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -100,7 +100,7 @@ AC_ARG_ENABLE(developer, + 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 "${enable_filter_aaaa+set}" = set || enable_filter_aaaa=yes +diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c +index ee59c1b..a2b2df7 100644 +--- a/lib/dns/rbtdb.c ++++ b/lib/dns/rbtdb.c +@@ -1183,6 +1183,44 @@ set_ttl(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, dns_ttl_t newttl) { + isc_heap_decreased(heap, header->heap_index); + } + ++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_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. +@@ -6278,6 +6316,30 @@ update_recordsandbytes(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. + */ +@@ -6288,6 +6350,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, + { + rbtdb_changed_t *changed = NULL; + rdatasetheader_t *topheader, *topheader_prev, *header, *sigheader; ++ rdatasetheader_t *prioheader = NULL, *expireheader = NULL; + unsigned char *merged; + isc_result_t result; + bool header_nx; +@@ -6297,6 +6360,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, + rbtdb_rdatatype_t negtype, sigtype; + dns_trust_t trust; + int idx; ++ uint32_t ntypes = 0; + + /* + * Add an rdatasetheader_t to a node. +@@ -6429,6 +6493,15 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, + 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; +@@ -6792,9 +6865,46 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, + /* + * 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); ++ } + } + } + +diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c +index b0f77b1..347b7d2 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) +@@ -161,6 +165,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); + +@@ -654,6 +662,10 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab, + #endif + INSIST(ocount > 0 && ncount > 0); + ++ if (ocount + ncount > DNS_RDATASET_MAX_RECORDS) { ++ return (DNS_R_TOOMANYRECORDS); ++ } ++ + #if DNS_RDATASET_FIXED + oncount = ncount; + #endif +-- +2.45.2 + diff --git a/SOURCES/bind-9.11-CVE-2024-1975.patch b/SOURCES/bind-9.11-CVE-2024-1975.patch new file mode 100644 index 0000000..f455871 --- /dev/null +++ b/SOURCES/bind-9.11-CVE-2024-1975.patch @@ -0,0 +1,322 @@ +From 5ff88892e43c049659a8a5aef8dfd56c3712daf0 Mon Sep 17 00:00:00 2001 +From: Petr Mensik +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/named/client.c | 7 +++ + bin/tests/system/tsiggss/authsock.pl | 5 ++ + bin/tests/system/tsiggss/tests.sh | 12 ++-- + bin/tests/system/upforwd/tests.sh | 21 ++++--- + doc/arm/Bv9ARM-book.xml | 22 +++---- + lib/dns/message.c | 94 +++------------------------- + 6 files changed, 49 insertions(+), 112 deletions(-) + +diff --git a/bin/named/client.c b/bin/named/client.c +index 368bc94..ea121b3 100644 +--- a/bin/named/client.c ++++ b/bin/named/client.c +@@ -3013,6 +3013,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 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 456ce61..d0db388 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 -R $RANDFILE -k ns1/Kkey.example.nil.*.private < /dev/null 2>&1 || ret=1 ++$NSUPDATE -R $RANDFILE -k ns1/Kkey.example.nil.*.private <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 ++# update must have failed - SIG(0) signer is not supported + output=`$DIG $DIGOPTS +short cname fred.example.nil.` +-[ -n "$output" ] || ret=1 +-[ $ret -eq 0 ] || echo_i "failed" ++[ -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 ebc9ded..f5b89d4 100644 +--- a/bin/tests/system/upforwd/tests.sh ++++ b/bin/tests/system/upforwd/tests.sh +@@ -181,19 +181,22 @@ n=`expr $n + 1` + + 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 -- - <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/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml +index acf772b..563dced 100644 +--- a/doc/arm/Bv9ARM-book.xml ++++ b/doc/arm/Bv9ARM-book.xml +@@ -2027,7 +2027,7 @@ allow-update { !{ !localnets; any; }; key host1-host2. ;}; + The TKEY process is initiated by a client or server by sending + a query of type TKEY to a TKEY-aware server. The query must include + an appropriate KEY record in the additional section, and +- must be signed using either TSIG or SIG(0) with a previously ++ must be signed using TSIG with a previously + established key. The server's response, if successful, + contains a TKEY record in its answer section. After this transaction, + both participants have enough information to calculate a +@@ -2050,24 +2050,24 @@ allow-update { !{ !localnets; any; }; key host1-host2. ;}; +
SIG(0) + + +- BIND partially supports DNSSEC SIG(0) ++ BIND partially supported DNSSEC SIG(0) + transaction signatures as specified in RFC 2535 and RFC 2931. + SIG(0) uses public/private keys to authenticate messages. Access control +- is performed in the same manner as with TSIG keys; privileges can be ++ were performed in the same manner as with TSIG keys; privileges can be + granted or denied in ACL directives based on the key name. + + +- When a SIG(0) signed message is received, it is only ++ When a SIG(0) signed message were received, it were only + verified if the key is known and trusted by the server. The +- server does not attempt to recursively fetch or validate the ++ server did not attempt to recursively fetch or validate the + key. + + +- SIG(0) signing of multiple-message TCP streams is not supported. ++ SIG(0) signing of multiple-message TCP streams were not supported. + + +- The only tool shipped with BIND 9 that +- generates SIG(0) signed messages is nsupdate. ++ Support for SIG(0) message verification was removed ++ as part of the mitigation of CVE-2024-1975. + +
+ +@@ -12655,7 +12655,7 @@ example.com. NS ns2.example.net. + 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). ++ signed the update request, using TSIG. + In most cases, update-policy rules + only apply to key-based identities. There is no way + to specify update permissions based on client source +@@ -12742,7 +12742,7 @@ example.com. NS ns2.example.net. + + 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 must be ++ 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 +@@ -15952,7 +15952,7 @@ HOST-127.EXAMPLE. MX 0 . + + + 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 ++ 1) 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. + +diff --git a/lib/dns/message.c b/lib/dns/message.c +index a44eb2d..9ea2b9e 100644 +--- a/lib/dns/message.c ++++ b/lib/dns/message.c +@@ -3373,103 +3373,23 @@ 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)); +- } 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); +- } ++ if (view != NULL) ++ return (dns_view_checksig(view, &msgb, msg)); ++ else ++ return (dns_tsig_verify(&msgb, msg, NULL, NULL)); + } + + #define INDENT(sp) \ +-- +2.45.2 + diff --git a/SOURCES/generate-rndc-key.sh b/SOURCES/generate-rndc-key.sh old mode 100755 new mode 100644 diff --git a/SOURCES/setup-named-chroot.sh b/SOURCES/setup-named-chroot.sh old mode 100755 new mode 100644 diff --git a/SOURCES/setup-named-softhsm.sh b/SOURCES/setup-named-softhsm.sh old mode 100755 new mode 100644 diff --git a/SPECS/bind.spec b/SPECS/bind.spec index 34b69d7..7c6c5c5 100644 --- a/SPECS/bind.spec +++ b/SPECS/bind.spec @@ -68,7 +68,7 @@ Summary: The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) serv Name: bind License: MPLv2.0 Version: 9.11.36 -Release: 14%{?PATCHVER:.%{PATCHVER}}%{?PREVER:.%{PREVER}}%{?dist} +Release: 16%{?PATCHVER:.%{PATCHVER}}%{?PREVER:.%{PREVER}}%{?dist}.2 Epoch: 32 Url: https://www.isc.org/downloads/bind/ # @@ -187,6 +187,16 @@ Patch202: bind-9.11-CVE-2023-50387.patch Patch203: bind-9.11-CVE-2023-2828-fixup.patch # addition to patch 200 Patch204: bind-9.11-CVE-2023-50387-fixup.patch +# https://gitlab.isc.org/isc-projects/bind9/commit/225f2861920b8f8d42a0ea6c34dd1faa93aa8726 +Patch205: bind-9.11-CVE-2024-1975.patch +# https://gitlab.isc.org/isc-projects/bind9/commit/3e0a67e4bdb253dae3a03a45c1aa117239a3313d +# https://gitlab.isc.org/isc-projects/bind9/commit/e4d7ce686bb38428eddc7e33b40057d68eca9a6e +# https://gitlab.isc.org/isc-projects/bind9/commit/b9b5485b22c364fb88c27aa04bad4c8f616da3fa +# https://gitlab.isc.org/isc-projects/bind9/commit/3f10d6eff035702796ba82cd28b9f7cf9836e743 +# https://gitlab.isc.org/isc-projects/bind9/commit/23a4652346fb2877d6246b1eebaa967969dbde16 +Patch206: bind-9.11-CVE-2024-1737.patch +# RH downstream, allow changing by environment +Patch208: bind-9.11-CVE-2024-1737-runtime-env.patch # SDB patches Patch11: bind-9.3.2b2-sdbsrc.patch @@ -212,6 +222,12 @@ Obsoletes: caching-nameserver < 31:9.4.1-7.fc8 Provides: caching-nameserver = 31:9.4.1-7.fc8 Obsoletes: dnssec-conf < 1.27-2 Provides: dnssec-conf = 1.27-2 +# Fixes of CVE-2023-50387 and CVE-2023-50868 caused ABI change +# Enforce updated rebuild is accepted only +Conflicts: bind-dyndb-ldap < 11.6-5 +Conflicts: dhcp-client < 12:4.3.6-50 +Conflicts: dhcp-server < 12:4.3.6-50 +Conflicts: dhcp-relay < 12:4.3.6-50 BuildRequires: gcc, make BuildRequires: openssl-devel, libtool, autoconf, pkgconfig, libcap-devel BuildRequires: libidn2-devel, libxml2-devel @@ -601,6 +617,9 @@ are used for building ISC DHCP. %patch202 -p1 -b .CVE-2023-50387+50868 %patch203 -p1 -b .CVE-2023-2828-fixup %patch204 -p1 -b .CVE-2023-50387-fixup +%patch205 -p1 -b .CVE-2024-1975 +%patch206 -p1 -b .CVE-2024-1737 +%patch208 -p1 -b .CVE-2024-1737-env mkdir lib/dns/tests/testdata/dstrandom cp -a %{SOURCE50} lib/dns/tests/testdata/dstrandom/random.data @@ -1653,6 +1672,20 @@ rm -rf ${RPM_BUILD_ROOT} %endif %changelog +* Tue Aug 06 2024 Petr Menšík - 32:9.11.36-16.2 +- Rebuild after CI change + +* Thu Jul 18 2024 Petr Menšík - 32:9.11.36-16.1 +- Resolve CVE-2024-1975 +- Resolve CVE-2024-1737 +- Add ability to change runtime limits for max types and records per name + +* Mon Apr 15 2024 Petr Menšík - 32:9.11.36-16 +- Ensure incompatible dhcp is not accepted + +* Fri Apr 12 2024 Petr Menšík - 32:9.11.36-15 +- Ensure incompatible bind-dyndb-ldap is not accepted + * Mon Feb 26 2024 Petr Menšík - 32:9.11.36-14 - Speed up parsing of DNS messages with many different names (CVE-2023-4408) - Prevent increased CPU consumption in DNSSEC validator (CVE-2023-50387 CVE-2023-50868)