From e07df022e191789d6e88a012185df1f10a8ad274 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: May 20 2020 10:43:33 +0000 Subject: import bind-9.11.4-22.P2.el7 --- diff --git a/SOURCES/bind-9.11-disab-timer-test.patch b/SOURCES/bind-9.11-disab-timer-test.patch new file mode 100644 index 0000000..7054b3e --- /dev/null +++ b/SOURCES/bind-9.11-disab-timer-test.patch @@ -0,0 +1,36 @@ +diff --git a/lib/isc-pkcs11/tests/Atffile b/lib/isc-pkcs11/tests/Atffile +index 74a4a77..ff02df1 100644 +--- a/lib/isc-pkcs11/tests/Atffile ++++ b/lib/isc-pkcs11/tests/Atffile +@@ -31,4 +31,3 @@ tp: symtab_test + tp: task_test + tp: taskpool_test + tp: time_test +-tp: timer_test +diff --git a/lib/isc-pkcs11/tests/Kyuafile b/lib/isc-pkcs11/tests/Kyuafile +index a86824a..94afc41 100644 +--- a/lib/isc-pkcs11/tests/Kyuafile ++++ b/lib/isc-pkcs11/tests/Kyuafile +@@ -29,4 +29,3 @@ atf_test_program{name='symtab_test'} + atf_test_program{name='task_test'} + atf_test_program{name='taskpool_test'} + atf_test_program{name='time_test'} +-atf_test_program{name='timer_test'} +diff --git a/lib/isc/tests/Atffile b/lib/isc/tests/Atffile +index 74a4a77..ff02df1 100644 +--- a/lib/isc/tests/Atffile ++++ b/lib/isc/tests/Atffile +@@ -31,4 +31,3 @@ tp: symtab_test + tp: task_test + tp: taskpool_test + tp: time_test +-tp: timer_test +diff --git a/lib/isc/tests/Kyuafile b/lib/isc/tests/Kyuafile +index a86824a..94afc41 100644 +--- a/lib/isc/tests/Kyuafile ++++ b/lib/isc/tests/Kyuafile +@@ -29,4 +29,3 @@ atf_test_program{name='symtab_test'} + atf_test_program{name='task_test'} + atf_test_program{name='taskpool_test'} + atf_test_program{name='time_test'} +-atf_test_program{name='timer_test'} diff --git a/SOURCES/bind-9.11-rh1300636.patch b/SOURCES/bind-9.11-rh1300636.patch new file mode 100644 index 0000000..5f0cdf1 --- /dev/null +++ b/SOURCES/bind-9.11-rh1300636.patch @@ -0,0 +1,77 @@ +From cfbb8a96570959a3d7471edbd8df559ea4e73123 Mon Sep 17 00:00:00 2001 +From: Mark Andrews +Date: Wed, 14 Nov 2018 15:17:48 +1100 +Subject: [PATCH] free tmpzonename and restart_master + +(cherry picked from commit 50714a9b35ce80bd8839a52106778d65b6d4d7ba) +(cherry picked from commit e409b8c6982a275e3fad960b2e66437890ff08e2) +--- + bin/nsupdate/nsupdate.c | 14 ++++++++++++-- + lib/dns/include/dns/name.h | 5 +++++ + 2 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c +index a0d0278635..7e241c17e9 100644 +--- a/bin/nsupdate/nsupdate.c ++++ b/bin/nsupdate/nsupdate.c +@@ -158,8 +158,8 @@ static dns_fixedname_t fuserzone; + static dns_fixedname_t fzname; + static dns_name_t *userzone = NULL; + static dns_name_t *zname = NULL; +-static dns_name_t tmpzonename; +-static dns_name_t restart_master; ++static dns_name_t tmpzonename = DNS_NAME_INITEMPTY; ++static dns_name_t restart_master = DNS_NAME_INITEMPTY; + static dns_tsig_keyring_t *gssring = NULL; + static dns_tsigkey_t *tsigkey = NULL; + static dst_key_t *sig0key = NULL; +@@ -2415,6 +2415,8 @@ update_completed(isc_task_t *task, isc_event_t *event) { + if (usegsstsig) { + dns_name_free(&tmpzonename, gmctx); + dns_name_free(&restart_master, gmctx); ++ dns_name_init(&tmpzonename, 0); ++ dns_name_init(&restart_master, 0); + } + isc_event_free(&event); + done_update(); +@@ -2830,6 +2832,8 @@ failed_gssrequest() { + + dns_name_free(&tmpzonename, gmctx); + dns_name_free(&restart_master, gmctx); ++ dns_name_init(&tmpzonename, NULL); ++ dns_name_init(&restart_master, NULL); + + done_update(); + } +@@ -3238,6 +3242,12 @@ cleanup(void) { + isc_mem_free(gmctx, realm); + realm = NULL; + } ++ if (dns_name_dynamic(&tmpzonename)) { ++ dns_name_free(&tmpzonename, gmctx); ++ } ++ if (dns_name_dynamic(&restart_master)) { ++ dns_name_free(&restart_master, gmctx); ++ } + #endif + + if (sig0key != NULL) +diff --git a/lib/dns/include/dns/name.h b/lib/dns/include/dns/name.h +index be74667ccb..93ddacd80b 100644 +--- a/lib/dns/include/dns/name.h ++++ b/lib/dns/include/dns/name.h +@@ -181,6 +181,11 @@ LIBDNS_EXTERNAL_DATA extern dns_name_t *dns_wildcardname; + {NULL, NULL} \ + } + ++#define DNS_NAME_INITEMPTY { \ ++ DNS_NAME_MAGIC, NULL, 0, 0, 0, NULL, NULL, \ ++ { (void *)-1, (void *)-1 }, { NULL, NULL } \ ++} ++ + /*% + * Standard size of a wire format name + */ +-- +2.21.1 + diff --git a/SOURCES/bind-9.11-rh1743572-2.patch b/SOURCES/bind-9.11-rh1743572-2.patch new file mode 100644 index 0000000..a46c8ec --- /dev/null +++ b/SOURCES/bind-9.11-rh1743572-2.patch @@ -0,0 +1,29 @@ +From 908b71224037745db3d1420a37e99ee9cbb3b3b3 Mon Sep 17 00:00:00 2001 +From: Petr Mensik +Date: Thu, 12 Dec 2019 16:05:25 +0100 +Subject: [PATCH] Terminate query if both setup_lookup and next_origin failed + +That happens in case searched name plus search domain is too long and no +shorted origin would follow. +--- + bin/dig/dighost.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c +index 6302a98..ed9625e 100644 +--- a/bin/dig/dighost.c ++++ b/bin/dig/dighost.c +@@ -2053,6 +2053,10 @@ start_lookup(void) { + do_lookup(current_lookup); + else if (next_origin(current_lookup)) + check_next_lookup(current_lookup); ++ else { ++ cancel_lookup(current_lookup); ++ check_next_lookup(current_lookup); ++ } + } else { + check_if_done(); + } +-- +2.21.0 + diff --git a/SOURCES/bind-9.11-rh1744081.patch b/SOURCES/bind-9.11-rh1744081.patch new file mode 100644 index 0000000..c58911d --- /dev/null +++ b/SOURCES/bind-9.11-rh1744081.patch @@ -0,0 +1,33 @@ +From f6b9f4dfa61038a353f3974ec7683231fa23ed21 Mon Sep 17 00:00:00 2001 +From: Petr Mensik +Date: Wed, 11 Mar 2020 17:36:51 +0100 +Subject: [PATCH] Allow conflicting files in zones, warn only + +Change hard error to just annoying warning. Broken configuration is +still error, but it was possible before. Make it possible again. +Would be fixed by using in-view clause properly. +--- + lib/bind9/check.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/bind9/check.c b/lib/bind9/check.c +index 545e3c6..b02a894 100644 +--- a/lib/bind9/check.c ++++ b/lib/bind9/check.c +@@ -2650,11 +2650,11 @@ fileexist(const cfg_obj_t *obj, isc_symtab_t *symtab, isc_boolean_t writeable, + if (writeable) { + file = cfg_obj_file(symvalue.as_cpointer); + line = cfg_obj_line(symvalue.as_cpointer); +- cfg_obj_log(obj, logctx, ISC_LOG_ERROR, ++ cfg_obj_log(obj, logctx, ISC_LOG_WARNING, + "writeable file '%s': already in use: " + "%s:%u", cfg_obj_asstring(obj), + file, line); +- return (ISC_R_EXISTS); ++ return (ISC_R_SUCCESS); // Pretend it is ok + } + result = isc_symtab_lookup(symtab, cfg_obj_asstring(obj), 2, + &symvalue); +-- +2.21.1 + diff --git a/SOURCES/bind-9.11-rh1753259.patch b/SOURCES/bind-9.11-rh1753259.patch new file mode 100644 index 0000000..8bf9f47 --- /dev/null +++ b/SOURCES/bind-9.11-rh1753259.patch @@ -0,0 +1,34 @@ +From f968f649e7e57eb097fb766be805a2d976d2dcc6 Mon Sep 17 00:00:00 2001 +From: Petr Mensik +Date: Wed, 27 Nov 2019 16:06:12 +0100 +Subject: [PATCH] Disable listening on IPV6 by default + +If configuration file does not mention listen-on-v6, for backward +compatibility assume none; Upstream changed default value to any; but +previous RHEL7 version did not have it. +--- + bin/named/server.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/bin/named/server.c b/bin/named/server.c +index 93f9417..eac467f 100644 +--- a/bin/named/server.c ++++ b/bin/named/server.c +@@ -7781,11 +7781,13 @@ load_configuration(const char *filename, ns_server_t *server, + ns_g_mctx, AF_INET6, + &listenon); + } else if (!ns_g_lwresdonly) { ++ isc_boolean_t enable; + /* + * Not specified, use default. + */ ++ enable = ISC_TF(isc_net_probeipv4() != ISC_R_SUCCESS); + CHECK(ns_listenlist_default(ns_g_mctx, listen_port, +- -1, ISC_TRUE, &listenon)); ++ -1, enable, &listenon)); + } + if (listenon != NULL) { + ns_interfacemgr_setlistenon6(server->interfacemgr, +-- +2.20.1 + diff --git a/SOURCES/bind-9.11-rh1756201.patch b/SOURCES/bind-9.11-rh1756201.patch new file mode 100644 index 0000000..b4d011d --- /dev/null +++ b/SOURCES/bind-9.11-rh1756201.patch @@ -0,0 +1,246 @@ +From bd79638f1c2c8f765e316c30b15dfb3e5d31e1e4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Witold=20Kr=C4=99cicki?= +Date: Thu, 3 Jan 2019 14:58:05 +0100 +Subject: [PATCH] If possible don't use forwarders when priming the resolver. + +If we try to fetch a record from cache and need to look into +hints database we assume that the resolver is not primed and +start dns_resolver_prime(). Priming query is supposed to return +NSes for "." in ANSWER section and glue records for them in +ADDITIONAL section, so that we can fill that info in 'regular' +cache and not use hints db anymore. +However, if we're using a forwarder the priming query goes through +it, and if it's configured to return minimal answers we won't get +the addresses of root servers in ADDITIONAL section. Since the +only records for root servers we have are in hints database we'll +try to prime the resolver with every single query. + +This patch adds a DNS_FETCHOPT_NOFORWARD flag which avoids using +forwarders if possible (that is if we have forward-first policy). +Using this flag on priming fetch fixes the problem as we get the +proper glue. With forward-only policy the problem is non-existent, +as we'll never ask for root server addresses because we'll never +have a need to query them. + +Also added a test to confirm priming queries are not forwarded. + +(cherry picked from commit b49310ac06ac87733dc2867828e61370a84b2a9a) +(cherry picked from commit f8963ad70e222edad0c1e64f855f7fb41fb13c3c) +(cherry picked from commit aa9866c390a21d6984aa75cdb84d7bc77e114c2f) +--- + bin/tests/system/forward/ns4/named.conf.in | 3 ++ + bin/tests/system/forward/ns7/named.conf.in | 28 +++++++++++++++++ + bin/tests/system/forward/ns7/root.db | 28 +++++++++++++++++ + bin/tests/system/forward/setup.sh | 1 + + bin/tests/system/forward/tests.sh | 12 ++++++++ + lib/dns/include/dns/resolver.h | 36 ++++++++++++---------- + lib/dns/resolver.c | 17 ++++++++-- + 7 files changed, 106 insertions(+), 19 deletions(-) + create mode 100644 bin/tests/system/forward/ns7/named.conf.in + create mode 100644 bin/tests/system/forward/ns7/root.db + +diff --git a/bin/tests/system/forward/ns4/named.conf.in b/bin/tests/system/forward/ns4/named.conf.in +index 480530b0f2..643e1271b5 100644 +--- a/bin/tests/system/forward/ns4/named.conf.in ++++ b/bin/tests/system/forward/ns4/named.conf.in +@@ -17,6 +17,9 @@ options { + pid-file "named.pid"; + listen-on { 10.53.0.4; }; + listen-on-v6 { none; }; ++ recursion yes; ++ dnssec-validation yes; ++ minimal-responses yes; + }; + + zone "." { +diff --git a/bin/tests/system/forward/ns7/named.conf.in b/bin/tests/system/forward/ns7/named.conf.in +new file mode 100644 +index 0000000000..d9f5e8a9db +--- /dev/null ++++ b/bin/tests/system/forward/ns7/named.conf.in +@@ -0,0 +1,28 @@ ++/* ++ * Copyright (C) Internet Systems Consortium, Inc. ("ISC") ++ * ++ * 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 http://mozilla.org/MPL/2.0/. ++ * ++ * See the COPYRIGHT file distributed with this work for additional ++ * information regarding copyright ownership. ++ */ ++ ++options { ++ query-source address 10.53.0.7; ++ notify-source 10.53.0.7; ++ transfer-source 10.53.0.7; ++ port @PORT@; ++ pid-file "named.pid"; ++ listen-on { 10.53.0.7; }; ++ listen-on-v6 { none; }; ++ forwarders { 10.53.0.4; }; ++ forward first; ++ dnssec-validation yes; ++}; ++ ++zone "." { ++ type hint; ++ file "root.db"; ++}; +diff --git a/bin/tests/system/forward/ns7/root.db b/bin/tests/system/forward/ns7/root.db +new file mode 100644 +index 0000000000..7346810ba6 +--- /dev/null ++++ b/bin/tests/system/forward/ns7/root.db +@@ -0,0 +1,28 @@ ++; Copyright (C) Internet Systems Consortium, Inc. ("ISC") ++; ++; 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 http://mozilla.org/MPL/2.0/. ++; ++; See the COPYRIGHT file distributed with this work for additional ++; information regarding copyright ownership. ++ ++$TTL 300 ++. IN SOA gson.nominum.com. a.root.servers.nil. ( ++ 2000042100 ; serial ++ 600 ; refresh ++ 600 ; retry ++ 1200 ; expire ++ 600 ; minimum ++ ) ++. NS a.root-servers.nil. ++a.root-servers.nil. A 10.53.0.1 ++ ++example1 NS ns.example1 ++ns.example1 A 10.53.0.1 ++ ++example2 NS ns.example2 ++ns.example2 A 10.53.0.1 ++ ++example3 NS ns.example3 ++ns.example3 A 10.53.0.1 +diff --git a/bin/tests/system/forward/setup.sh b/bin/tests/system/forward/setup.sh +index c63aeb10d2..d64579e590 100644 +--- a/bin/tests/system/forward/setup.sh ++++ b/bin/tests/system/forward/setup.sh +@@ -18,3 +18,4 @@ copy_setports ns2/named.conf.in ns2/named.conf + copy_setports ns3/named.conf.in ns3/named.conf + copy_setports ns4/named.conf.in ns4/named.conf + copy_setports ns5/named.conf.in ns5/named.conf ++copy_setports ns7/named.conf.in ns7/named.conf +diff --git a/bin/tests/system/forward/tests.sh b/bin/tests/system/forward/tests.sh +index f23cde1751..8c6496037d 100644 +--- a/bin/tests/system/forward/tests.sh ++++ b/bin/tests/system/forward/tests.sh +@@ -131,5 +131,17 @@ $CHECKCONF ula-notinherited.conf | grep "forward first;" >/dev/null && ret=1 + if [ $ret != 0 ]; then echo_i "failed"; fi + status=`expr $status + $ret` + ++echo_i "checking that priming queries are not forwarded" ++ret=0 ++$DIG $DIGOPTS +noadd +noauth txt.example1. txt @10.53.0.7 > dig.out.f7 || ret=1 ++sent=`sed -n '/sending packet to 10.53.0.1/,/^$/p' ns7/named.run | grep ";.*IN.*NS" | wc -l` ++[ $sent -eq 1 ] || ret=1 ++sent=`grep "10.53.0.7#.* (.): query '\./NS/IN' approved" ns4/named.run | wc -l` ++[ $sent -eq 0 ] || ret=1 ++sent=`grep "10.53.0.7#.* (.): query '\./NS/IN' approved" ns1/named.run | wc -l` ++[ $sent -eq 1 ] || ret=1 ++if [ $ret != 0 ]; then echo_i "failed"; fi ++status=`expr $status + $ret` ++ + echo_i "exit status: $status" + [ $status -eq 0 ] || exit 1 +diff --git a/lib/dns/include/dns/resolver.h b/lib/dns/include/dns/resolver.h +index f2f8714d16..e1a10295f3 100644 +--- a/lib/dns/include/dns/resolver.h ++++ b/lib/dns/include/dns/resolver.h +@@ -88,23 +88,25 @@ typedef enum { + /* + * Options that modify how a 'fetch' is done. + */ +-#define DNS_FETCHOPT_TCP 0x0001 /*%< Use TCP. */ +-#define DNS_FETCHOPT_UNSHARED 0x0002 /*%< See below. */ +-#define DNS_FETCHOPT_RECURSIVE 0x0004 /*%< Set RD? */ +-#define DNS_FETCHOPT_NOEDNS0 0x0008 /*%< Do not use EDNS. */ +-#define DNS_FETCHOPT_FORWARDONLY 0x0010 /*%< Only use forwarders. */ +-#define DNS_FETCHOPT_NOVALIDATE 0x0020 /*%< Disable validation. */ +-#define DNS_FETCHOPT_EDNS512 0x0040 /*%< Advertise a 512 byte +- UDP buffer. */ +-#define DNS_FETCHOPT_WANTNSID 0x0080 /*%< Request NSID */ +-#define DNS_FETCHOPT_PREFETCH 0x0100 /*%< Do prefetch */ +-#define DNS_FETCHOPT_NOCDFLAG 0x0200 /*%< Don't set CD flag. */ +-#define DNS_FETCHOPT_NONTA 0x0400 /*%< Ignore NTA table. */ +-/* RESERVED ECS 0x0000 */ +-/* RESERVED ECS 0x1000 */ +-/* RESERVED ECS 0x2000 */ +-/* RESERVED TCPCLIENT 0x4000 */ +-#define DNS_FETCHOPT_NOCACHED 0x8000 /*%< Force cache update. */ ++#define DNS_FETCHOPT_TCP 0x00001 /*%< Use TCP. */ ++#define DNS_FETCHOPT_UNSHARED 0x00002 /*%< See below. */ ++#define DNS_FETCHOPT_RECURSIVE 0x00004 /*%< Set RD? */ ++#define DNS_FETCHOPT_NOEDNS0 0x00008 /*%< Do not use EDNS. */ ++#define DNS_FETCHOPT_FORWARDONLY 0x00010 /*%< Only use forwarders. */ ++#define DNS_FETCHOPT_NOVALIDATE 0x00020 /*%< Disable validation. */ ++#define DNS_FETCHOPT_EDNS512 0x00040 /*%< Advertise a 512 byte ++ 0 UDP buffer. */ ++#define DNS_FETCHOPT_WANTNSID 0x00080 /*%< Request NSID */ ++#define DNS_FETCHOPT_PREFETCH 0x00100 /*%< Do prefetch */ ++#define DNS_FETCHOPT_NOCDFLAG 0x00200 /*%< Don't set CD flag. */ ++#define DNS_FETCHOPT_NONTA 0x00400 /*%< Ignore NTA table. */ ++/* RESERVED ECS 0x00000 */ ++/* RESERVED ECS 0x01000 */ ++/* RESERVED ECS 0x02000 */ ++/* RESERVED TCPCLIENT 0x04000 */ ++#define DNS_FETCHOPT_NOCACHED 0x08000 /*%< Force cache update. */ ++#define DNS_FETCHOPT_NOFORWARD 0x80000 /*%< Do not use forwarders ++ if possible. */ + + /* Reserved in use by adb.c 0x00400000 */ + #define DNS_FETCHOPT_EDNSVERSIONSET 0x00800000 +diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c +index 301ad52fe2..f701a09be9 100644 +--- a/lib/dns/resolver.c ++++ b/lib/dns/resolver.c +@@ -3261,6 +3261,18 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) { + INSIST(ISC_LIST_EMPTY(fctx->forwaddrs)); + INSIST(ISC_LIST_EMPTY(fctx->altaddrs)); + ++ /* ++ * If we have DNS_FETCHOPT_NOFORWARD set and forwarding policy ++ * allows us to not forward - skip forwarders and go straight ++ * to NSes. This is currently used to make sure that priming query ++ * gets root servers' IP addresses in ADDITIONAL section. ++ */ ++ if ((fctx->options & DNS_FETCHOPT_NOFORWARD) != 0 && ++ (fctx->fwdpolicy != dns_fwdpolicy_only)) ++ { ++ goto normal_nses; ++ } ++ + /* + * If this fctx has forwarders, use them; otherwise use any + * selective forwarders specified in the view; otherwise use the +@@ -3346,7 +3358,7 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) { + /* + * Normal nameservers. + */ +- ++ normal_nses: + stdoptions = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_EMPTYEVENT; + if (fctx->restarts == 1) { + /* +@@ -9194,7 +9206,8 @@ dns_resolver_prime(dns_resolver_t *res) { + LOCK(&res->primelock); + result = dns_resolver_createfetch(res, dns_rootname, + dns_rdatatype_ns, +- NULL, NULL, NULL, 0, ++ NULL, NULL, NULL, ++ DNS_FETCHOPT_NOFORWARD, + res->buckets[0].task, + prime_done, + res, rdataset, NULL, +-- +2.21.1 + diff --git a/SOURCES/bind-9.11-rh1781576.patch b/SOURCES/bind-9.11-rh1781576.patch new file mode 100644 index 0000000..e57ffd3 --- /dev/null +++ b/SOURCES/bind-9.11-rh1781576.patch @@ -0,0 +1,672 @@ +From 64d62856d251b58fe3350e9c3cf985a78debba5d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= +Date: Wed, 7 Aug 2019 05:46:45 -0400 +Subject: [PATCH] Merge branch '1148-deadlock-hangs-named-v9_11' into 'v9_11' + +Convert (dns_view_t){ .weakrefs } to isc_refcount_t + +See merge request isc-projects/bind9!2227 + +(cherry picked from commit e3903e83962c659bbac52454c816588c24078b5e) +--- + lib/dns/client.c | 121 +++++++++++++++++-------------------- + lib/dns/include/dns/view.h | 2 +- + lib/dns/view.c | 88 +++++++++------------------ + lib/isc/app_api.c | 18 +++++- + 4 files changed, 103 insertions(+), 126 deletions(-) + +diff --git a/lib/dns/client.c b/lib/dns/client.c +index b0dfa57dbe..e7eb40cd07 100644 +--- a/lib/dns/client.c ++++ b/lib/dns/client.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -92,8 +93,9 @@ struct dns_client { + unsigned int find_timeout; + unsigned int find_udpretries; + ++ isc_refcount_t references; ++ + /* Locked */ +- unsigned int references; + dns_viewlist_t viewlist; + ISC_LIST(struct resctx) resctxs; + ISC_LIST(struct reqctx) reqctxs; +@@ -463,8 +465,7 @@ dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx, + + result = isc_mutex_init(&client->lock); + if (result != ISC_R_SUCCESS) { +- isc_mem_put(mctx, client, sizeof(*client)); +- return (result); ++ goto cleanup_client; + } + + client->actx = actx; +@@ -474,12 +475,14 @@ dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx, + + client->task = NULL; + result = isc_task_create(client->taskmgr, 0, &client->task); +- if (result != ISC_R_SUCCESS) +- goto cleanup; ++ if (result != ISC_R_SUCCESS) { ++ goto cleanup_lock; ++ } + + result = dns_dispatchmgr_create(mctx, NULL, &dispatchmgr); +- if (result != ISC_R_SUCCESS) +- goto cleanup; ++ if (result != ISC_R_SUCCESS) { ++ goto cleanup_task; ++ } + client->dispatchmgr = dispatchmgr; + + /* +@@ -491,8 +494,9 @@ dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx, + result = getudpdispatch(AF_INET, dispatchmgr, socketmgr, + taskmgr, ISC_TRUE, + &dispatchv4, localaddr4); +- if (result == ISC_R_SUCCESS) ++ if (result == ISC_R_SUCCESS) { + client->dispatchv4 = dispatchv4; ++ } + } + + client->dispatchv6 = NULL; +@@ -500,22 +504,30 @@ dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx, + result = getudpdispatch(AF_INET6, dispatchmgr, socketmgr, + taskmgr, ISC_TRUE, + &dispatchv6, localaddr6); +- if (result == ISC_R_SUCCESS) ++ if (result == ISC_R_SUCCESS) { + client->dispatchv6 = dispatchv6; ++ } + } + + /* We need at least one of the dispatchers */ + if (dispatchv4 == NULL && dispatchv6 == NULL) { + INSIST(result != ISC_R_SUCCESS); +- goto cleanup; ++ goto cleanup_dispatchmgr; ++ } ++ ++ result = isc_refcount_init(&client->references, 1); ++ if (result != ISC_R_SUCCESS) { ++ goto cleanup_dispatches; + } + + /* Create the default view for class IN */ + result = createview(mctx, dns_rdataclass_in, options, taskmgr, + RESOLVER_NTASKS, socketmgr, timermgr, + dispatchmgr, dispatchv4, dispatchv6, &view); +- if (result != ISC_R_SUCCESS) +- goto cleanup; ++ if (result != ISC_R_SUCCESS) { ++ goto cleanup_references; ++ } ++ + ISC_LIST_INIT(client->viewlist); + ISC_LIST_APPEND(client->viewlist, view, link); + +@@ -535,32 +547,38 @@ dns_client_createx2(isc_mem_t *mctx, isc_appctx_t *actx, + client->find_udpretries = DEF_FIND_UDPRETRIES; + client->attributes = 0; + +- client->references = 1; + client->magic = DNS_CLIENT_MAGIC; + + *clientp = client; + + return (ISC_R_SUCCESS); + +- cleanup: ++ cleanup_references: ++ isc_refcount_decrement(&client->references, NULL); ++ isc_refcount_destroy(&client->references); ++ cleanup_dispatches: + if (dispatchv4 != NULL) + dns_dispatch_detach(&dispatchv4); + if (dispatchv6 != NULL) + dns_dispatch_detach(&dispatchv6); +- if (dispatchmgr != NULL) +- dns_dispatchmgr_destroy(&dispatchmgr); +- if (client->task != NULL) +- isc_task_detach(&client->task); ++ cleanup_dispatchmgr: ++ dns_dispatchmgr_destroy(&dispatchmgr); ++ cleanup_task: ++ isc_task_detach(&client->task); ++ cleanup_lock: ++ DESTROYLOCK(&client->lock); ++ cleanup_client: + isc_mem_put(mctx, client, sizeof(*client)); + + return (result); + } + + static void +-destroyclient(dns_client_t **clientp) { +- dns_client_t *client = *clientp; ++destroyclient(dns_client_t *client) { + dns_view_t *view; + ++ isc_refcount_destroy(&client->references); ++ + while ((view = ISC_LIST_HEAD(client->viewlist)) != NULL) { + ISC_LIST_UNLINK(client->viewlist, view, link); + dns_view_detach(&view); +@@ -592,32 +610,22 @@ destroyclient(dns_client_t **clientp) { + client->magic = 0; + + isc_mem_putanddetach(&client->mctx, client, sizeof(*client)); +- +- *clientp = NULL; + } + + void + dns_client_destroy(dns_client_t **clientp) { + dns_client_t *client; +- isc_boolean_t destroyok = ISC_FALSE; ++ isc_uint32_t references; + + REQUIRE(clientp != NULL); + client = *clientp; ++ *clientp = NULL; + REQUIRE(DNS_CLIENT_VALID(client)); + +- LOCK(&client->lock); +- client->references--; +- if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) && +- ISC_LIST_EMPTY(client->reqctxs) && +- ISC_LIST_EMPTY(client->updatectxs)) { +- destroyok = ISC_TRUE; ++ isc_refcount_decrement(&client->references, &references); ++ if (references == 0U) { ++ destroyclient(client); + } +- UNLOCK(&client->lock); +- +- if (destroyok) +- destroyclient(&client); +- +- *clientp = NULL; + } + + isc_result_t +@@ -1407,6 +1415,7 @@ dns_client_startresolve(dns_client_t *client, dns_name_t *name, + rctx->event = event; + + rctx->magic = RCTX_MAGIC; ++ isc_refcount_increment(&client->references, NULL); + + LOCK(&client->lock); + ISC_LIST_APPEND(client->resctxs, rctx, link); +@@ -1477,10 +1486,10 @@ dns_client_destroyrestrans(dns_clientrestrans_t **transp) { + resctx_t *rctx; + isc_mem_t *mctx; + dns_client_t *client; +- isc_boolean_t need_destroyclient = ISC_FALSE; + + REQUIRE(transp != NULL); + rctx = (resctx_t *)*transp; ++ *transp = NULL; + REQUIRE(RCTX_VALID(rctx)); + REQUIRE(rctx->fetch == NULL); + REQUIRE(rctx->event == NULL); +@@ -1502,11 +1511,6 @@ dns_client_destroyrestrans(dns_clientrestrans_t **transp) { + INSIST(ISC_LINK_LINKED(rctx, link)); + ISC_LIST_UNLINK(client->resctxs, rctx, link); + +- if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) && +- ISC_LIST_EMPTY(client->reqctxs) && +- ISC_LIST_EMPTY(client->updatectxs)) +- need_destroyclient = ISC_TRUE; +- + UNLOCK(&client->lock); + + INSIST(ISC_LIST_EMPTY(rctx->namelist)); +@@ -1516,10 +1520,8 @@ dns_client_destroyrestrans(dns_clientrestrans_t **transp) { + + isc_mem_put(mctx, rctx, sizeof(*rctx)); + +- if (need_destroyclient) +- destroyclient(&client); ++ dns_client_destroy(&client); + +- *transp = NULL; + } + + isc_result_t +@@ -1793,6 +1795,7 @@ dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage, + + LOCK(&client->lock); + ISC_LIST_APPEND(client->reqctxs, ctx, link); ++ isc_refcount_increment(&client->references, NULL); + UNLOCK(&client->lock); + + ctx->request = NULL; +@@ -1807,6 +1810,8 @@ dns_client_startrequest(dns_client_t *client, dns_message_t *qmessage, + return (ISC_R_SUCCESS); + } + ++ isc_refcount_decrement(&client->references, NULL); ++ + cleanup: + if (ctx != NULL) { + LOCK(&client->lock); +@@ -1847,10 +1852,10 @@ dns_client_destroyreqtrans(dns_clientreqtrans_t **transp) { + reqctx_t *ctx; + isc_mem_t *mctx; + dns_client_t *client; +- isc_boolean_t need_destroyclient = ISC_FALSE; + + REQUIRE(transp != NULL); + ctx = (reqctx_t *)*transp; ++ *transp = NULL; + REQUIRE(REQCTX_VALID(ctx)); + client = ctx->client; + REQUIRE(DNS_CLIENT_VALID(client)); +@@ -1865,12 +1870,6 @@ dns_client_destroyreqtrans(dns_clientreqtrans_t **transp) { + INSIST(ISC_LINK_LINKED(ctx, link)); + ISC_LIST_UNLINK(client->reqctxs, ctx, link); + +- if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) && +- ISC_LIST_EMPTY(client->reqctxs) && +- ISC_LIST_EMPTY(client->updatectxs)) { +- need_destroyclient = ISC_TRUE; +- } +- + UNLOCK(&client->lock); + + DESTROYLOCK(&ctx->lock); +@@ -1878,10 +1877,7 @@ dns_client_destroyreqtrans(dns_clientreqtrans_t **transp) { + + isc_mem_put(mctx, ctx, sizeof(*ctx)); + +- if (need_destroyclient) +- destroyclient(&client); +- +- *transp = NULL; ++ dns_client_destroy(&client); + } + + /*% +@@ -2971,6 +2967,7 @@ dns_client_startupdate(dns_client_t *client, dns_rdataclass_t rdclass, + + LOCK(&client->lock); + ISC_LIST_APPEND(client->updatectxs, uctx, link); ++ isc_refcount_increment(&client->references, NULL); + UNLOCK(&client->lock); + + *transp = (dns_clientupdatetrans_t *)uctx; +@@ -2989,6 +2986,8 @@ dns_client_startupdate(dns_client_t *client, dns_rdataclass_t rdclass, + } + if (result == ISC_R_SUCCESS) + return (result); ++ ++ isc_refcount_decrement(&client->references, NULL); + *transp = NULL; + + fail: +@@ -3046,11 +3045,11 @@ dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp) { + updatectx_t *uctx; + isc_mem_t *mctx; + dns_client_t *client; +- isc_boolean_t need_destroyclient = ISC_FALSE; + isc_sockaddr_t *sa; + + REQUIRE(transp != NULL); + uctx = (updatectx_t *)*transp; ++ *transp = NULL; + REQUIRE(UCTX_VALID(uctx)); + client = uctx->client; + REQUIRE(DNS_CLIENT_VALID(client)); +@@ -3071,11 +3070,6 @@ dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp) { + INSIST(ISC_LINK_LINKED(uctx, link)); + ISC_LIST_UNLINK(client->updatectxs, uctx, link); + +- if (client->references == 0 && ISC_LIST_EMPTY(client->resctxs) && +- ISC_LIST_EMPTY(client->reqctxs) && +- ISC_LIST_EMPTY(client->updatectxs)) +- need_destroyclient = ISC_TRUE; +- + UNLOCK(&client->lock); + + DESTROYLOCK(&uctx->lock); +@@ -3083,10 +3077,7 @@ dns_client_destroyupdatetrans(dns_clientupdatetrans_t **transp) { + + isc_mem_put(mctx, uctx, sizeof(*uctx)); + +- if (need_destroyclient) +- destroyclient(&client); +- +- *transp = NULL; ++ dns_client_destroy(&client); + } + + isc_mem_t * +diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h +index 7cd88f8377..e383c40f0f 100644 +--- a/lib/dns/include/dns/view.h ++++ b/lib/dns/include/dns/view.h +@@ -191,9 +191,9 @@ struct dns_view { + + /* Locked by themselves. */ + isc_refcount_t references; ++ isc_refcount_t weakrefs; + + /* Locked by lock. */ +- unsigned int weakrefs; + unsigned int attributes; + /* Under owner's locking control. */ + ISC_LINK(struct dns_view) link; +diff --git a/lib/dns/view.c b/lib/dns/view.c +index f53193c3ec..db09c3db6e 100644 +--- a/lib/dns/view.c ++++ b/lib/dns/view.c +@@ -155,9 +155,13 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, + view->frozen = ISC_FALSE; + view->task = NULL; + result = isc_refcount_init(&view->references, 1); +- if (result != ISC_R_SUCCESS) ++ if (result != ISC_R_SUCCESS) { + goto cleanup_fwdtable; +- view->weakrefs = 0; ++ } ++ result = isc_refcount_init(&view->weakrefs, 1); ++ if (result != ISC_R_SUCCESS) { ++ goto cleanup_references; ++ } + view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN| + DNS_VIEWATTR_REQSHUTDOWN); + view->statickeys = NULL; +@@ -167,7 +171,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, + view->matchrecursiveonly = ISC_FALSE; + result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys); + if (result != ISC_R_SUCCESS) +- goto cleanup_references; ++ goto cleanup_weakrefs; + view->peers = NULL; + view->order = NULL; + view->delonly = NULL; +@@ -304,6 +308,10 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, + if (view->dynamickeys != NULL) + dns_tsigkeyring_detach(&view->dynamickeys); + ++ cleanup_weakrefs: ++ isc_refcount_decrement(&view->weakrefs, NULL); ++ isc_refcount_destroy(&view->weakrefs); ++ + cleanup_references: + isc_refcount_destroy(&view->references); + +@@ -336,12 +344,13 @@ destroy(dns_view_t *view) { + dns_dlzdb_t *dlzdb; + + REQUIRE(!ISC_LINK_LINKED(view, link)); +- REQUIRE(isc_refcount_current(&view->references) == 0); +- REQUIRE(view->weakrefs == 0); + REQUIRE(RESSHUTDOWN(view)); + REQUIRE(ADBSHUTDOWN(view)); + REQUIRE(REQSHUTDOWN(view)); + ++ isc_refcount_destroy(&view->references); ++ isc_refcount_destroy(&view->weakrefs); ++ + if (view->order != NULL) + dns_order_detach(&view->order); + if (view->peers != NULL) +@@ -536,26 +545,12 @@ destroy(dns_view_t *view) { + DESTROYLOCK(&view->new_zone_lock); + DESTROYLOCK(&view->lock); + isc_refcount_destroy(&view->references); ++ isc_refcount_destroy(&view->weakrefs); + isc_mem_free(view->mctx, view->nta_file); + isc_mem_free(view->mctx, view->name); + isc_mem_putanddetach(&view->mctx, view, sizeof(*view)); + } + +-/* +- * Return true iff 'view' may be freed. +- * The caller must be holding the view lock. +- */ +-static isc_boolean_t +-all_done(dns_view_t *view) { +- +- if (isc_refcount_current(&view->references) == 0 && +- view->weakrefs == 0 && +- RESSHUTDOWN(view) && ADBSHUTDOWN(view) && REQSHUTDOWN(view)) +- return (ISC_TRUE); +- +- return (ISC_FALSE); +-} +- + void + dns_view_attach(dns_view_t *source, dns_view_t **targetp) { + +@@ -571,10 +566,10 @@ static void + view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { + dns_view_t *view; + unsigned int refs; +- isc_boolean_t done = ISC_FALSE; + + REQUIRE(viewp != NULL); + view = *viewp; ++ *viewp = NULL; + REQUIRE(DNS_VIEW_VALID(view)); + + if (flush) +@@ -613,7 +608,6 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { + if (view->catzs != NULL) { + dns_catz_catzs_detach(&view->catzs); + } +- done = all_done(view); + UNLOCK(&view->lock); + + /* Need to detach zones outside view lock */ +@@ -622,12 +616,9 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) { + + if (rdzone != NULL) + dns_zone_detach(&rdzone); +- } +- +- *viewp = NULL; + +- if (done) +- destroy(view); ++ dns_view_weakdetach(&view); ++ } + } + + void +@@ -661,9 +652,7 @@ dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) { + REQUIRE(DNS_VIEW_VALID(source)); + REQUIRE(targetp != NULL && *targetp == NULL); + +- LOCK(&source->lock); +- source->weakrefs++; +- UNLOCK(&source->lock); ++ isc_refcount_increment(&source->weakrefs, NULL); + + *targetp = source; + } +@@ -671,30 +660,22 @@ dns_view_weakattach(dns_view_t *source, dns_view_t **targetp) { + void + dns_view_weakdetach(dns_view_t **viewp) { + dns_view_t *view; +- isc_boolean_t done = ISC_FALSE; ++ unsigned int weakrefs; + + REQUIRE(viewp != NULL); + view = *viewp; + REQUIRE(DNS_VIEW_VALID(view)); +- +- LOCK(&view->lock); +- +- INSIST(view->weakrefs > 0); +- view->weakrefs--; +- done = all_done(view); +- +- UNLOCK(&view->lock); +- + *viewp = NULL; + +- if (done) ++ isc_refcount_decrement(&view->weakrefs, &weakrefs); ++ if (weakrefs == 0) { + destroy(view); ++ } + } + + static void + resolver_shutdown(isc_task_t *task, isc_event_t *event) { + dns_view_t *view = event->ev_arg; +- isc_boolean_t done; + + REQUIRE(event->ev_type == DNS_EVENT_VIEWRESSHUTDOWN); + REQUIRE(DNS_VIEW_VALID(view)); +@@ -705,20 +686,15 @@ resolver_shutdown(isc_task_t *task, isc_event_t *event) { + isc_event_free(&event); + + LOCK(&view->lock); +- + view->attributes |= DNS_VIEWATTR_RESSHUTDOWN; +- done = all_done(view); +- + UNLOCK(&view->lock); + +- if (done) +- destroy(view); ++ dns_view_weakdetach(&view); + } + + static void + adb_shutdown(isc_task_t *task, isc_event_t *event) { + dns_view_t *view = event->ev_arg; +- isc_boolean_t done; + + REQUIRE(event->ev_type == DNS_EVENT_VIEWADBSHUTDOWN); + REQUIRE(DNS_VIEW_VALID(view)); +@@ -729,20 +705,15 @@ adb_shutdown(isc_task_t *task, isc_event_t *event) { + isc_event_free(&event); + + LOCK(&view->lock); +- + view->attributes |= DNS_VIEWATTR_ADBSHUTDOWN; +- done = all_done(view); +- + UNLOCK(&view->lock); + +- if (done) +- destroy(view); ++ dns_view_weakdetach(&view); + } + + static void + req_shutdown(isc_task_t *task, isc_event_t *event) { + dns_view_t *view = event->ev_arg; +- isc_boolean_t done; + + REQUIRE(event->ev_type == DNS_EVENT_VIEWREQSHUTDOWN); + REQUIRE(DNS_VIEW_VALID(view)); +@@ -753,14 +724,10 @@ req_shutdown(isc_task_t *task, isc_event_t *event) { + isc_event_free(&event); + + LOCK(&view->lock); +- + view->attributes |= DNS_VIEWATTR_REQSHUTDOWN; +- done = all_done(view); +- + UNLOCK(&view->lock); + +- if (done) +- destroy(view); ++ dns_view_weakdetach(&view); + } + + isc_result_t +@@ -809,6 +776,7 @@ dns_view_createresolver(dns_view_t *view, + event = &view->resevent; + dns_resolver_whenshutdown(view->resolver, view->task, &event); + view->attributes &= ~DNS_VIEWATTR_RESSHUTDOWN; ++ isc_refcount_increment(&view->weakrefs, NULL); + + result = isc_mem_create(0, 0, &mctx); + if (result != ISC_R_SUCCESS) { +@@ -826,6 +794,7 @@ dns_view_createresolver(dns_view_t *view, + event = &view->adbevent; + dns_adb_whenshutdown(view->adb, view->task, &event); + view->attributes &= ~DNS_VIEWATTR_ADBSHUTDOWN; ++ isc_refcount_increment(&view->weakrefs, NULL); + + result = dns_requestmgr_create(view->mctx, timermgr, socketmgr, + dns_resolver_taskmgr(view->resolver), +@@ -840,6 +809,7 @@ dns_view_createresolver(dns_view_t *view, + event = &view->reqevent; + dns_requestmgr_whenshutdown(view->requestmgr, view->task, &event); + view->attributes &= ~DNS_VIEWATTR_REQSHUTDOWN; ++ isc_refcount_increment(&view->weakrefs, NULL); + + return (ISC_R_SUCCESS); + } +diff --git a/lib/isc/app_api.c b/lib/isc/app_api.c +index 5563c7cc0b..40ec2d93b8 100644 +--- a/lib/isc/app_api.c ++++ b/lib/isc/app_api.c +@@ -23,6 +23,7 @@ + static isc_mutex_t createlock; + static isc_once_t once = ISC_ONCE_INIT; + static isc_appctxcreatefunc_t appctx_createfunc = NULL; ++static isc_mutex_t runninglock; + static isc_boolean_t is_running = ISC_FALSE; + + #define ISCAPI_APPMETHODS_VALID(m) ISC_MAGIC_VALID(m, ISCAPI_APPMETHODS_MAGIC) +@@ -30,6 +31,7 @@ static isc_boolean_t is_running = ISC_FALSE; + static void + initialize(void) { + RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS); ++ RUNTIME_CHECK(isc_mutex_init(&runninglock) == ISC_R_SUCCESS); + } + + isc_result_t +@@ -196,9 +198,15 @@ isc_app_run() { + if (isc_bind9) { + isc_result_t result; + ++ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); ++ ++ LOCK(&runninglock); + is_running = ISC_TRUE; ++ UNLOCK(&runninglock); + result = isc__app_run(); ++ LOCK(&runninglock); + is_running = ISC_FALSE; ++ UNLOCK(&runninglock); + + return (result); + } +@@ -208,7 +216,15 @@ isc_app_run() { + + isc_boolean_t + isc_app_isrunning() { +- return (is_running); ++ isc_boolean_t running; ++ ++ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); ++ ++ LOCK(&runninglock); ++ running = is_running; ++ UNLOCK(&runninglock); ++ ++ return (running); + } + + isc_result_t +-- +2.21.1 + diff --git a/SOURCES/bind-9.11.4-CVE-2019-6477.patch b/SOURCES/bind-9.11.4-CVE-2019-6477.patch new file mode 100644 index 0000000..0a7e554 --- /dev/null +++ b/SOURCES/bind-9.11.4-CVE-2019-6477.patch @@ -0,0 +1,157 @@ +From c3314d0fa0756d39cab1e9d9e3cf2e36dd6273da Mon Sep 17 00:00:00 2001 +From: Petr Mensik +Date: Mon, 18 Nov 2019 16:44:58 +0100 +Subject: [PATCH] Limit number of queries per TCP connection + +5306. [security] Set a limit on the number of concurrently served + pipelined TCP queries. (CVE-2019-6477) [GL #1264] +--- + bin/named/client.c | 73 ++++++++++++++++++++------------ + bin/named/include/named/client.h | 5 ++- + 2 files changed, 50 insertions(+), 28 deletions(-) + +diff --git a/bin/named/client.c b/bin/named/client.c +index f21a77ba52..23f70edaff 100644 +--- a/bin/named/client.c ++++ b/bin/named/client.c +@@ -98,7 +98,15 @@ + #define SEND_BUFFER_SIZE 4096 + #define RECV_BUFFER_SIZE 4096 + ++#define TCP_CLIENTS_PER_CONN 23 ++/*%< ++ * Number of simultaneous ns_clients_t (queries in flight) for one ++ * TCP connection. The number was arbitrarily picked and might be ++ * changed in the future. ++ */ ++ + #ifdef ISC_PLATFORM_USETHREADS ++ + #define NMCTXS 100 + /*%< + * Number of 'mctx pools' for clients. (Should this be configurable?) +@@ -333,7 +341,7 @@ tcpconn_init(ns_client_t *client, isc_boolean_t force) { + */ + tconn = isc_mem_allocate(ns_g_mctx, sizeof(*tconn)); + +- isc_refcount_init(&tconn->refs, 1); ++ isc_refcount_init(&tconn->clients, 1); /* Current client */ + tconn->tcpquota = quota; + quota = NULL; + tconn->pipelined = ISC_FALSE; +@@ -350,14 +358,14 @@ tcpconn_init(ns_client_t *client, isc_boolean_t force) { + */ + static void + tcpconn_attach(ns_client_t *source, ns_client_t *target) { +- int refs; ++ int old_clients; + + REQUIRE(source->tcpconn != NULL); + REQUIRE(target->tcpconn == NULL); + REQUIRE(source->tcpconn->pipelined); + +- isc_refcount_increment(&source->tcpconn->refs, &refs); +- INSIST(refs > 1); ++ isc_refcount_increment(&source->tcpconn->clients, &old_clients); ++ INSIST(old_clients > 1); + target->tcpconn = source->tcpconn; + } + +@@ -370,15 +378,15 @@ tcpconn_attach(ns_client_t *source, ns_client_t *target) { + static void + tcpconn_detach(ns_client_t *client) { + ns_tcpconn_t *tconn = NULL; +- int refs; ++ int old_clients; + + REQUIRE(client->tcpconn != NULL); + + tconn = client->tcpconn; + client->tcpconn = NULL; + +- isc_refcount_decrement(&tconn->refs, &refs); +- if (refs == 0) { ++ isc_refcount_decrement(&tconn->clients, &old_clients); ++ if (old_clients == 0) { + isc_quota_detach(&tconn->tcpquota); + isc_mem_free(ns_g_mctx, tconn); + } +@@ -2629,28 +2637,39 @@ client_request(isc_task_t *task, isc_event_t *event) { + /* + * Pipeline TCP query processing. + */ +- if (TCP_CLIENT(client) && +- client->message->opcode != dns_opcode_query) +- { +- client->tcpconn->pipelined = ISC_FALSE; +- } +- if (TCP_CLIENT(client) && client->tcpconn->pipelined) { +- /* +- * We're pipelining. Replace the client; the +- * replacement can read the TCP socket looking +- * for new messages and this one can process the +- * current message asynchronously. +- * +- * There will now be at least three clients using this +- * TCP socket - one accepting new connections, +- * one reading an existing connection to get new +- * messages, and one answering the message already +- * received. +- */ +- result = ns_client_replace(client); +- if (result != ISC_R_SUCCESS) { ++ if (TCP_CLIENT(client)) { ++ if (client->message->opcode != dns_opcode_query) { + client->tcpconn->pipelined = ISC_FALSE; + } ++ ++ /* ++ * Limit the maximum number of simultaneous pipelined ++ * queries on TCP connection to TCP_CLIENTS_PER_CONN. ++ */ ++ if ((isc_refcount_current(&client->tcpconn->clients) ++ > TCP_CLIENTS_PER_CONN)) ++ { ++ client->tcpconn->pipelined = ISC_FALSE; ++ } ++ ++ if (client->tcpconn->pipelined) { ++ /* ++ * We're pipelining. Replace the client; the ++ * replacement can read the TCP socket looking ++ * for new messages and this one can process the ++ * current message asynchronously. ++ * ++ * There will now be at least three clients using this ++ * TCP socket - one accepting new connections, ++ * one reading an existing connection to get new ++ * messages, and one answering the message already ++ * received. ++ */ ++ result = ns_client_replace(client); ++ if (result != ISC_R_SUCCESS) { ++ client->tcpconn->pipelined = ISC_FALSE; ++ } ++ } + } + + dns_opcodestats_increment(ns_g_server->opcodestats, +diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h +index 0f54d2267b..86437ade22 100644 +--- a/bin/named/include/named/client.h ++++ b/bin/named/include/named/client.h +@@ -77,7 +77,10 @@ + + /*% reference-counted TCP connection object */ + typedef struct ns_tcpconn { +- isc_refcount_t refs; ++ isc_refcount_t clients; /* Number of clients using ++ * this connection. Conn can ++ * be freed if goes to 0 ++ */ + isc_quota_t *tcpquota; + isc_boolean_t pipelined; + } ns_tcpconn_t; +-- +2.20.1 + diff --git a/SPECS/bind.spec b/SPECS/bind.spec index c9bf6d3..115942c 100644 --- a/SPECS/bind.spec +++ b/SPECS/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: 13%{?PATCHVER:.%{PATCHVER}}%{?PREVER:.%{PREVER}}%{?dist} +Release: 22%{?PATCHVER:.%{PATCHVER}}%{?PREVER:.%{PREVER}}%{?dist} Epoch: 32 Url: http://www.isc.org/products/BIND/ # @@ -158,6 +158,14 @@ Patch171:bind-9.11-CVE-2019-6465.patch Patch172:bind-9.11-rh1732883.patch Patch173: bind-9.11-CVE-2018-5745-testfix.patch Patch174: bind-9.11-rh1743572.patch +Patch175: bind-9.11.4-CVE-2019-6477.patch +Patch176: bind-9.11-rh1753259.patch +Patch177: bind-9.11-rh1743572-2.patch +Patch178: bind-9.11-rh1781576.patch +Patch179: bind-9.11-disab-timer-test.patch +Patch180: bind-9.11-rh1744081.patch +Patch181: bind-9.11-rh1300636.patch +Patch182: bind-9.11-rh1756201.patch # SDB patches Patch11: bind-9.3.2b2-sdbsrc.patch @@ -510,6 +518,13 @@ are used for building ISC DHCP. %patch172 -p1 -b .rh1732883 %patch173 -p1 -b .CVE-2018-5745-testfix %patch174 -p1 -b .rh1743572 +%patch175 -p1 -b .CVE-2019-6477 +%patch176 -p1 -b .rh1753259 +%patch177 -p1 -b .rh1743572 +%patch178 -p1 -b .rh1781576 +%patch180 -p1 -b .rh1744081 +%patch181 -p1 -b .rh1300636 +%patch182 -p1 -b .rh1756201 # Override upstream builtin keys cp -fp %{SOURCE29} bind.keys @@ -523,6 +538,10 @@ cp -r lib/dns{,-pkcs11} %patch149 -p1 -b .kyua-pkcs11 %endif +%ifarch ppc64le +%patch179 -p1 -b .timer-test-ppc64le +%endif + %if %{with SDB} %patch101 -p1 -b .old-api mkdir bin/named-sdb @@ -613,6 +632,9 @@ export LIBDIR_SUFFIX --enable-filter-aaaa \ --enable-rrl \ --with-pic \ +%ifarch aarch64 ppc ppc64 ppc64le + --disable-atomic \ +%endif --disable-static \ --includedir=%{_includedir}/bind9 \ --with-tuning=large \ @@ -1484,6 +1506,34 @@ rm -rf ${RPM_BUILD_ROOT} %changelog +* Wed Mar 18 2020 Petr Menšík - 32:9.11.4-22.P2 +- Solve often priming queries on some forwarder (#1756201) + +* Mon Mar 16 2020 Petr Menšík - 32:9.11.4-21.P2 +- Disable atomic operations also on ppc (#1779589) + +* Fri Mar 13 2020 Petr Menšík - 32:9.11.4-20.P2 +- Do not crash when nsupdate with GSS terminated early (#1300636) + +* Wed Mar 11 2020 Petr Menšík - 32:9.11.4-19.P2 +- Allow conflicting zone files with a warning (#1744081) + +* Wed Mar 04 2020 Miroslav Lichvar - 32:9.11.4-18.P2 +- Disable atomic operations on ppc64, ppc64le, aarch64 (#1779589) + +* Fri Feb 21 2020 Tomas Korbar - 32:9.11.4-17.P2 +- Prevent deadlock on reload (#1781576) +- Disable unit test timer_test on ppc64le because of its instability + +* Thu Dec 12 2019 Petr Menšík - 32:9.11.4-16.P2 +- Finish dig query when name is too long (#1743572) + +* Wed Nov 27 2019 Petr Menšík - 32:9.11.4-15.P2 +- Stop listening on IPv6 by default (#1753259) + +* Tue Nov 19 2019 Petr Menšík - 32:9.11.4-14.P2 +- Limit number of queries per TCP connection (CVE-2019-6477) + * Wed Oct 02 2019 Petr Menšík - 32:9.11.4-13.P2 - Revert not searching names with dot (#1743572)