diff --git a/bind-9.16-tcp-listening.patch b/bind-9.16-tcp-listening.patch new file mode 100644 index 0000000..a96c6c7 --- /dev/null +++ b/bind-9.16-tcp-listening.patch @@ -0,0 +1,480 @@ +From 0807d8b0588c89ee9eb18c17544174e51c2aaa97 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= +Date: Tue, 7 Sep 2021 14:40:19 +0200 +Subject: [PATCH] Remove the code to adjust listening interfaces for + *-source-v6 + +Previously, named would run with a configuration +where *-source-v6 (notify-source-v6, transfer-source-v6 and +query-source-v6) address and port could be simultaneously used for +listening. This is no longer true for BIND 9.16+ and the code that +would do interface adjustments would unexpectedly disable listening on +TCP for such interfaces. + +This commit removes the code that would adjust listening interfaces +for addresses/ports configured in *-source-v6 option. + +(cherry picked from commit 8ac1d4e0daee6fc785377761da42023127ec2284) +--- + bin/named/server.c | 162 ------------------------------- + lib/ns/include/ns/interfacemgr.h | 14 --- + lib/ns/interfacemgr.c | 117 +++++++--------------- + 3 files changed, 33 insertions(+), 260 deletions(-) + +diff --git a/bin/named/server.c b/bin/named/server.c +index 0237817c29..60da9c9b1e 100644 +--- a/bin/named/server.c ++++ b/bin/named/server.c +@@ -6767,160 +6767,6 @@ directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) { + return (ISC_R_SUCCESS); + } + +-static isc_result_t +-add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr, +- isc_dscp_t dscp, bool wcardport_ok) { +- ns_listenelt_t *lelt = NULL; +- dns_acl_t *src_acl = NULL; +- isc_result_t result; +- isc_sockaddr_t any_sa6; +- isc_netaddr_t netaddr; +- +- REQUIRE(isc_sockaddr_pf(addr) == AF_INET6); +- +- isc_sockaddr_any6(&any_sa6); +- if (!isc_sockaddr_equal(&any_sa6, addr) && +- (wcardport_ok || isc_sockaddr_getport(addr) != 0)) +- { +- isc_netaddr_fromin6(&netaddr, &addr->type.sin6.sin6_addr); +- +- result = dns_acl_create(mctx, 0, &src_acl); +- if (result != ISC_R_SUCCESS) { +- return (result); +- } +- +- result = dns_iptable_addprefix(src_acl->iptable, &netaddr, 128, +- true); +- if (result != ISC_R_SUCCESS) { +- goto clean; +- } +- +- result = ns_listenelt_create(mctx, isc_sockaddr_getport(addr), +- dscp, src_acl, &lelt); +- if (result != ISC_R_SUCCESS) { +- goto clean; +- } +- ISC_LIST_APPEND(list->elts, lelt, link); +- } +- +- return (ISC_R_SUCCESS); +- +-clean: +- INSIST(lelt == NULL); +- dns_acl_detach(&src_acl); +- +- return (result); +-} +- +-/* +- * Make a list of xxx-source addresses and call ns_interfacemgr_adjust() +- * to update the listening interfaces accordingly. +- * We currently only consider IPv6, because this only affects IPv6 wildcard +- * sockets. +- */ +-static void +-adjust_interfaces(named_server_t *server, isc_mem_t *mctx) { +- isc_result_t result; +- ns_listenlist_t *list = NULL; +- dns_view_t *view; +- dns_zone_t *zone, *next; +- isc_sockaddr_t addr, *addrp; +- isc_dscp_t dscp = -1; +- +- result = ns_listenlist_create(mctx, &list); +- if (result != ISC_R_SUCCESS) { +- return; +- } +- +- for (view = ISC_LIST_HEAD(server->viewlist); view != NULL; +- view = ISC_LIST_NEXT(view, link)) +- { +- dns_dispatch_t *dispatch6; +- +- dispatch6 = dns_resolver_dispatchv6(view->resolver); +- if (dispatch6 == NULL) { +- continue; +- } +- result = dns_dispatch_getlocaladdress(dispatch6, &addr); +- if (result != ISC_R_SUCCESS) { +- goto fail; +- } +- +- /* +- * We always add non-wildcard address regardless of whether +- * the port is 'any' (the fourth arg is TRUE): if the port is +- * specific, we need to add it since it may conflict with a +- * listening interface; if it's zero, we'll dynamically open +- * query ports, and some of them may override an existing +- * wildcard IPv6 port. +- */ +- /* XXXMPA fix dscp */ +- result = add_listenelt(mctx, list, &addr, dscp, true); +- if (result != ISC_R_SUCCESS) { +- goto fail; +- } +- } +- +- zone = NULL; +- for (result = dns_zone_first(server->zonemgr, &zone); +- result == ISC_R_SUCCESS; +- next = NULL, result = dns_zone_next(zone, &next), zone = next) +- { +- dns_view_t *zoneview; +- +- /* +- * At this point the zone list may contain a stale zone +- * just removed from the configuration. To see the validity, +- * check if the corresponding view is in our current view list. +- * There may also be old zones that are still in the process +- * of shutting down and have detached from their old view +- * (zoneview == NULL). +- */ +- zoneview = dns_zone_getview(zone); +- if (zoneview == NULL) { +- continue; +- } +- for (view = ISC_LIST_HEAD(server->viewlist); +- view != NULL && view != zoneview; +- view = ISC_LIST_NEXT(view, link)) +- {} +- if (view == NULL) { +- continue; +- } +- +- addrp = dns_zone_getnotifysrc6(zone); +- dscp = dns_zone_getnotifysrc6dscp(zone); +- result = add_listenelt(mctx, list, addrp, dscp, false); +- if (result != ISC_R_SUCCESS) { +- goto fail; +- } +- +- addrp = dns_zone_getxfrsource6(zone); +- dscp = dns_zone_getxfrsource6dscp(zone); +- result = add_listenelt(mctx, list, addrp, dscp, false); +- if (result != ISC_R_SUCCESS) { +- goto fail; +- } +- } +- +- ns_interfacemgr_adjust(server->interfacemgr, list, true); +- +-clean: +- ns_listenlist_detach(&list); +- return; +- +-fail: +- /* +- * Even when we failed the procedure, most of other interfaces +- * should work correctly. We therefore just warn it. +- */ +- isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, +- NAMED_LOGMODULE_SERVER, ISC_LOG_WARNING, +- "could not adjust the listen-on list; " +- "some interfaces may not work"); +- goto clean; +-} +- + /* + * This event callback is invoked to do periodic network interface + * scanning. +@@ -9633,14 +9479,6 @@ cleanup: + isc_mem_put(server->sctx->mctx, altsecret, sizeof(*altsecret)); + } + +- /* +- * Adjust the listening interfaces in accordance with the source +- * addresses specified in views and zones. +- */ +- if (isc_net_probeipv6() == ISC_R_SUCCESS) { +- adjust_interfaces(server, named_g_mctx); +- } +- + /* + * Record the time of most recent configuration + */ +diff --git a/lib/ns/include/ns/interfacemgr.h b/lib/ns/include/ns/interfacemgr.h +index e210ee3bc0..0a2092a249 100644 +--- a/lib/ns/include/ns/interfacemgr.h ++++ b/lib/ns/include/ns/interfacemgr.h +@@ -147,20 +147,6 @@ ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose); + * in named.conf. + */ + +-isc_result_t +-ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list, +- bool verbose); +-/*%< +- * Similar to ns_interfacemgr_scan(), but this function also tries to see the +- * need for an explicit listen-on when a list element in 'list' is going to +- * override an already-listening a wildcard interface. +- * +- * This function does not update localhost and localnets ACLs. +- * +- * This should be called once on server startup, after configuring views and +- * zones. +- */ +- + void + ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value); + /*%< +diff --git a/lib/ns/interfacemgr.c b/lib/ns/interfacemgr.c +index b8302b75e6..acc83016dc 100644 +--- a/lib/ns/interfacemgr.c ++++ b/lib/ns/interfacemgr.c +@@ -503,8 +503,8 @@ ns_interface_listentcp(ns_interface_t *ifp) { + + static isc_result_t + ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, +- const char *name, ns_interface_t **ifpret, bool accept_tcp, +- isc_dscp_t dscp, bool *addr_in_use) { ++ const char *name, ns_interface_t **ifpret, isc_dscp_t dscp, ++ bool *addr_in_use) { + isc_result_t result; + ns_interface_t *ifp = NULL; + REQUIRE(ifpret != NULL && *ifpret == NULL); +@@ -525,7 +525,7 @@ ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr, + goto cleanup_interface; + } + +- if (((mgr->sctx->options & NS_SERVER_NOTCP) == 0) && accept_tcp) { ++ if (((mgr->sctx->options & NS_SERVER_NOTCP) == 0)) { + result = ns_interface_listentcp(ifp); + if (result != ISC_R_SUCCESS) { + if ((result == ISC_R_ADDRINUSE) && +@@ -774,11 +774,10 @@ clearlistenon(ns_interfacemgr_t *mgr) { + } + + static isc_result_t +-do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { ++do_scan(ns_interfacemgr_t *mgr, bool verbose) { + isc_interfaceiter_t *iter = NULL; + bool scan_ipv4 = false; + bool scan_ipv6 = false; +- bool adjusting = false; + bool ipv6only = true; + bool ipv6pktinfo = true; + isc_result_t result; +@@ -792,10 +791,6 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { + bool tried_listening; + bool all_addresses_in_use; + +- if (ext_listen != NULL) { +- adjusting = true; +- } +- + if (isc_net_probeipv6() == ISC_R_SUCCESS) { + scan_ipv6 = true; + } else if ((mgr->sctx->options & NS_SERVER_DISABLE6) == 0) { +@@ -864,7 +859,7 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { + "interfaces, port %u", + le->port); + result = ns_interface_setup(mgr, &listen_addr, +- "", &ifp, true, ++ "", &ifp, + le->dscp, NULL); + if (result == ISC_R_SUCCESS) { + ifp->flags |= NS_INTERFACEFLAG_ANYADDR; +@@ -887,17 +882,15 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { + return (result); + } + +- if (!adjusting) { +- result = clearacl(mgr->mctx, &mgr->aclenv.localhost); +- if (result != ISC_R_SUCCESS) { +- goto cleanup_iter; +- } +- result = clearacl(mgr->mctx, &mgr->aclenv.localnets); +- if (result != ISC_R_SUCCESS) { +- goto cleanup_iter; +- } +- clearlistenon(mgr); ++ result = clearacl(mgr->mctx, &mgr->aclenv.localhost); ++ if (result != ISC_R_SUCCESS) { ++ goto cleanup_iter; + } ++ result = clearacl(mgr->mctx, &mgr->aclenv.localnets); ++ if (result != ISC_R_SUCCESS) { ++ goto cleanup_iter; ++ } ++ clearlistenon(mgr); + + tried_listening = false; + all_addresses_in_use = true; +@@ -940,22 +933,19 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { + continue; + } + +- if (!adjusting) { +- /* +- * If running with -T fixedlocal, then we only +- * want 127.0.0.1 and ::1 in the localhost ACL. +- */ +- if (((mgr->sctx->options & NS_SERVER_FIXEDLOCAL) != +- 0) && +- !isc_netaddr_isloopback(&interface.address)) +- { +- goto listenon; +- } ++ /* ++ * If running with -T fixedlocal, then we only ++ * want 127.0.0.1 and ::1 in the localhost ACL. ++ */ ++ if (((mgr->sctx->options & NS_SERVER_FIXEDLOCAL) != 0) && ++ !isc_netaddr_isloopback(&interface.address)) ++ { ++ goto listenon; ++ } + +- result = setup_locals(mgr, &interface); +- if (result != ISC_R_SUCCESS) { +- goto ignore_interface; +- } ++ result = setup_locals(mgr, &interface); ++ if (result != ISC_R_SUCCESS) { ++ goto ignore_interface; + } + + listenon: +@@ -995,7 +985,7 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { + continue; + } + +- if (!adjusting && dolistenon) { ++ if (dolistenon) { + setup_listenon(mgr, &interface, le->port); + dolistenon = false; + } +@@ -1009,37 +999,6 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { + ipv6_wildcard = true; + } + +- /* +- * When adjusting interfaces with extra a listening +- * list, see if the address matches the extra list. +- * If it does, and is also covered by a wildcard +- * interface, we need to listen on the address +- * explicitly. +- */ +- if (adjusting) { +- ns_listenelt_t *ele; +- +- match = 0; +- for (ele = ISC_LIST_HEAD(ext_listen->elts); +- ele != NULL; +- ele = ISC_LIST_NEXT(ele, link)) +- { +- (void)dns_acl_match(&listen_netaddr, +- NULL, ele->acl, +- NULL, &match, NULL); +- if (match > 0 && +- (ele->port == le->port || +- ele->port == 0)) { +- break; +- } else { +- match = 0; +- } +- } +- if (ipv6_wildcard && match == 0) { +- continue; +- } +- } +- + ifp = find_matching_interface(mgr, &listen_sockaddr); + if (ifp != NULL) { + ifp->generation = mgr->generation; +@@ -1058,12 +1017,12 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { + } else { + bool addr_in_use = false; + +- if (!adjusting && ipv6_wildcard) { ++ if (ipv6_wildcard) { + continue; + } + + if (log_explicit && family == AF_INET6 && +- !adjusting && listenon_is_ip6_any(le)) { ++ listenon_is_ip6_any(le)) { + isc_log_write( + IFMGR_COMMON_LOGARGS, + verbose ? ISC_LOG_INFO +@@ -1078,17 +1037,14 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, bool verbose) { + sizeof(sabuf)); + isc_log_write( + IFMGR_COMMON_LOGARGS, ISC_LOG_INFO, +- "%s" + "listening on %s interface " + "%s, %s", +- (adjusting) ? "additionally " : "", + (family == AF_INET) ? "IPv4" : "IPv6", + interface.name, sabuf); + + result = ns_interface_setup( + mgr, &listen_sockaddr, interface.name, +- &ifp, (adjusting) ? false : true, +- le->dscp, &addr_in_use); ++ &ifp, le->dscp, &addr_in_use); + + tried_listening = true; + if (!addr_in_use) { +@@ -1135,8 +1091,7 @@ cleanup_iter: + } + + static isc_result_t +-ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, +- bool verbose) { ++ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, bool verbose) { + isc_result_t result; + bool purge = true; + +@@ -1144,7 +1099,7 @@ ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, + + mgr->generation++; /* Increment the generation count. */ + +- result = do_scan(mgr, ext_listen, verbose); ++ result = do_scan(mgr, verbose); + if ((result != ISC_R_SUCCESS) && (result != ISC_R_ADDRINUSE)) { + purge = false; + } +@@ -1162,7 +1117,7 @@ ns_interfacemgr_scan0(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen, + /* + * Warn if we are not listening on any interface. + */ +- if (ext_listen == NULL && ISC_LIST_EMPTY(mgr->interfaces)) { ++ if (ISC_LIST_EMPTY(mgr->interfaces)) { + isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_WARNING, + "not listening on any interfaces"); + } +@@ -1192,7 +1147,7 @@ ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose) { + unlock = true; + } + +- result = ns_interfacemgr_scan0(mgr, NULL, verbose); ++ result = ns_interfacemgr_scan0(mgr, verbose); + + if (unlock) { + isc_task_endexclusive(mgr->excl); +@@ -1201,12 +1156,6 @@ ns_interfacemgr_scan(ns_interfacemgr_t *mgr, bool verbose) { + return (result); + } + +-isc_result_t +-ns_interfacemgr_adjust(ns_interfacemgr_t *mgr, ns_listenlist_t *list, +- bool verbose) { +- return (ns_interfacemgr_scan0(mgr, list, verbose)); +-} +- + void + ns_interfacemgr_setlistenon4(ns_interfacemgr_t *mgr, ns_listenlist_t *value) { + REQUIRE(NS_INTERFACEMGR_VALID(mgr)); +-- +2.31.1 + diff --git a/bind.spec b/bind.spec index bc8072d..81b9a37 100644 --- a/bind.spec +++ b/bind.spec @@ -51,7 +51,7 @@ Summary: The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) serv Name: bind License: MPLv2.0 Version: 9.16.20 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 32 Url: https://www.isc.org/downloads/bind/ # @@ -106,6 +106,8 @@ Patch171:bind-9.11-tests-variants.patch # https://gitlab.isc.org/isc-projects/bind9/-/issues/2872 # https://kb.isc.org/docs/map-zone-format-incompatibility-in-bind-9-16-20-and-9-17-17 Patch172:https://downloads.isc.org/isc/bind9/9.16.20/patches/bind-9.16.20-map-format-fix.patch +# https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/5400 +Patch173:bind-9.16-tcp-listening.patch %{?systemd_ordering} Requires: coreutils @@ -407,6 +409,7 @@ in HTML and PDF format. %patch170 -p1 -b .featuretest-named %patch171 -p1 -b .test-variant %patch172 -p1 -b .map-format +%patch173 -p1 -b .rh1999691 %if %{with PKCS11} %patch135 -p1 -b .config-pkcs11 @@ -1131,6 +1134,9 @@ fi; %endif %changelog +* Tue Oct 12 2021 Petr Menšík - 32:9.16.20-4 +- Fixes listening on TCP in some race conditions (#1999691) + * Tue Oct 12 2021 Petr Menšík - 32:9.16.20-3 - Include documentation of dig return codes (#1989909)