diff --git a/CHANGES b/CHANGES index 36a9eae78a..103a360cc5 100644 --- a/CHANGES +++ b/CHANGES @@ -20,73 +20,94 @@ that the DS record has been published in the parent. [GL #1613] + --- 9.17.4 released --- + 5485. [placeholder] -5484. [func] Expire the 0 TTL RRSet quickly rather using them for - stale answers. [GL #1829] +5484. [func] Expire zero TTL records quickly rather than using them + for stale answers. [GL #1829] 5483. [func] Keeping "stale" answers in cache has been disabled by default and can be re-enabled with a new configuration option "stale-cache-enable". [GL #1712] -5482. [bug] BIND 9 would fail to bind to IPv6 addresses in a - tentative state when a new IPv6 address was added to the - system, but the Duplicate Address Detection (DAD) - mechanism had not yet finished. [GL #2038] +5482. [bug] If the Duplicate Address Detection (DAD) mechanism had + not yet finished after adding a new IPv6 address to the + system, BIND 9 would fail to bind to IPv6 addresses in a + tentative state. [GL #2038] -5481. [placeholder] +5481. [security] "update-policy" rules of type "subdomain" were + incorrectly treated as "zonesub" rules, which allowed + keys used in "subdomain" rules to update names outside + of the specified subdomains. The problem was fixed by + making sure "subdomain" rules are again processed as + described in the ARM. (CVE-2020-8624) [GL #2055] -5480. [placeholder] +5480. [security] When BIND 9 was compiled with native PKCS#11 support, it + was possible to trigger an assertion failure in code + determining the number of bits in the PKCS#11 RSA public + key with a specially crafted packet. (CVE-2020-8623) + [GL #2037] -5479. [placeholder] +5479. [security] named could crash in certain query resolution scenarios + where QNAME minimization and forwarding were both + enabled. (CVE-2020-8621) [GL #1997] -5478. [placeholder] +5478. [security] It was possible to trigger an assertion failure by + sending a specially crafted large TCP DNS message. + (CVE-2020-8620) [GL #1996] -5477. [bug] The idle timeout for connected TCP sockets is now - derived from the client query processing timeout - configured for a resolver. [GL #2024] +5477. [bug] The idle timeout for connected TCP sockets, which was + previously set to a high fixed value, is now derived + from the client query processing timeout configured for + a resolver. [GL #2024] -5476. [placeholder] +5476. [security] It was possible to trigger an assertion failure when + verifying the response to a TSIG-signed request. + (CVE-2020-8622) [GL #2028] -5475. [bug] Fix RPZ wildcard passthru ignored when a rejection - would overwrite a passthru action matching some - rule in a previously loaded passthru rpz zone. - [GL #1619] +5475. [bug] Wildcard RPZ passthru rules could incorrectly be + overridden by other rules that were loaded from RPZ + zones which appeared later in the "response-policy" + statement. This has been fixed. [GL #1619] 5474. [bug] dns_rdata_hip_next() failed to return ISC_R_NOMORE when it should have. [GL !3880] -5473. [func] The rbt hashtable implementation has been changed - to use faster hash-function (HalfSipHash2-4) and - uses Fibonacci hashing for better distribution. - Setting the max-cache-size now preallocates fixed - size hashtable, so the rehashing doesn't cause - resolution brownouts when growing the hashtable. - [GL #1775] +5473. [func] The RBT hash table implementation has been changed + to use a faster hash function (HalfSipHash2-4) and + Fibonacci hashing for better distribution. Setting + "max-cache-size" now preallocates a fixed-size hash + table so that rehashing does not cause resolution + brownouts while the hash table is grown. [GL #1775] 5472. [func] The statistics channel has been updated to use the new network manager. [GL #2022] -5471. [bug] The introduction of KASP support broke whether the - second field of sig-validity-interval was treated as - days or hours. (Thanks to Tony Finch.) [GL !3735] +5471. [bug] The introduction of KASP support inadvertently caused + the second field of "sig-validity-interval" to always be + calculated in hours, even in cases when it should have + been calculated in days. This has been fixed. (Thanks to + Tony Finch.) [GL !3735] -5470. [port] illumos: only call gsskrb5_register_acceptor_identity - if we have gssapi_krb5.h. [GL #1995] +5470. [port] gsskrb5_register_acceptor_identity() is now only called + if gssapi_krb5.h is present. [GL #1995] -5469. [port] illumos: SEC is defined in which - conflicted with our use of SEC. [GL #1993] +5469. [port] On illumos, a constant called SEC is already defined in + , which conflicts with an identically named + constant in libbind9. This conflict has been resolved. + [GL #1993] -5468. [bug] Address potential double unlock in process_fd(). +5468. [bug] Addressed potential double unlock in process_fd(). [GL #2005] 5467. [func] The control channel and the rndc utility have been updated to use the new network manager. To support this, the network manager was updated to enable - wthe initiation of client TCP connections. Its + the initiation of client TCP connections. Its internal reference counting has been refactored. - Note: As side effects of this change, rndc cannot + Note: As a side effect of this change, rndc cannot currently be used with UNIX-domain sockets, and its default timeout has changed from 60 seconds to 30. These will be addressed in a future release. @@ -95,30 +116,30 @@ 5466. [bug] Addressed an error in recursive clients stats reporting. [GL #1719] -5465. [func] Fallback to built in trust-anchors, managed-keys, or - trusted-keys if the bindkeys-file (bind.keys) cannot +5465. [func] Added fallback to built-in trust-anchors, managed-keys, + or trusted-keys if the bindkeys-file (bind.keys) cannot be parsed. [GL #1235] -5464. [bug] Specifying saving more than 128 files when rolling - dnstap / log files would cause buffer overflow. - [GL #1989] +5464. [bug] Requesting more than 128 files to be saved when rolling + dnstap log files caused a buffer overflow. This has been + fixed. [GL #1989] 5463. [placeholder] 5462. [bug] Move LMDB locking from LMDB itself to named. [GL #1976] -5461. [bug] The header STALE attribute was not being updated with - the write lock being held leading to incorrect - statistics. Convert the header attributes to use atomic - operations. [GL #1475] +5461. [bug] The STALE rdataset header attribute was updated while + the write lock was not being held, leading to incorrect + statistics. The header attributes are now converted to + use atomic operations. [GL #1475] 5460. [cleanup] tsig-keygen was previously an alias for ddns-confgen and was documented in the ddns-confgen man page. This has been reversed; tsig-keygen is now the primary name. [GL #1998] -5459. [bug] Bad isc_mem_put() size when an invalid type was - specified in a update-policy rule. [GL #1990] +5459. [bug] Fixed bad isc_mem_put() size when an invalid type was + specified in an "update-policy" rule. [GL #1990] --- 9.17.3 released --- diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 8abbbc462b..39ef13fdcf 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -252,7 +252,8 @@ configure_zone_ssutable(const cfg_obj_t *zconfig, dns_zone_t *zone, str = cfg_obj_asstring(matchtype); CHECK(dns_ssu_mtypefromstring(str, &mtype)); - if (mtype == dns_ssumatchtype_subdomain) { + if (mtype == dns_ssumatchtype_subdomain && + strcasecmp(str, "zonesub") == 0) { usezone = true; } diff --git a/bin/tests/system/nsupdate/ns1/named.conf.in b/bin/tests/system/nsupdate/ns1/named.conf.in index b20912e86c..f79a6f223a 100644 --- a/bin/tests/system/nsupdate/ns1/named.conf.in +++ b/bin/tests/system/nsupdate/ns1/named.conf.in @@ -37,6 +37,16 @@ key altkey { secret "1234abcd8765"; }; +key restricted.example.nil { + algorithm hmac-md5; + secret "1234abcd8765"; +}; + +key zonesub-key.example.nil { + algorithm hmac-md5; + secret "1234subk8765"; +}; + include "ddns.key"; zone "example.nil" { @@ -45,7 +55,9 @@ zone "example.nil" { check-integrity no; check-mx ignore; update-policy { + grant zonesub-key.example.nil zonesub TXT; grant ddns-key.example.nil subdomain example.nil ANY; + grant restricted.example.nil subdomain restricted.example.nil ANY; }; allow-transfer { any; }; }; diff --git a/bin/tests/system/nsupdate/tests.sh b/bin/tests/system/nsupdate/tests.sh index 2cc2a4ec30..9e0e618541 100755 --- a/bin/tests/system/nsupdate/tests.sh +++ b/bin/tests/system/nsupdate/tests.sh @@ -429,7 +429,7 @@ EOF # this also proves that the server is still running. $DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocmd +norec example.\ @10.53.0.3 nsec3param > dig.out.ns3.$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.$n > /dev/null || ret=1 +grep "ANSWER: 0," dig.out.ns3.$n > /dev/null || ret=1 grep "flags:[^;]* aa[ ;]" dig.out.ns3.$n > /dev/null || ret=1 [ $ret = 0 ] || { echo_i "failed"; status=1; } @@ -444,7 +444,7 @@ EOF $DIG $DIGOPTS +tcp +noadd +nosea +nostat +noquest +nocmd +norec nsec3param.test.\ @10.53.0.3 nsec3param > dig.out.ns3.$n || ret=1 -grep "ANSWER: 1" dig.out.ns3.$n > /dev/null || ret=1 +grep "ANSWER: 1," dig.out.ns3.$n > /dev/null || ret=1 grep "3600.*NSEC3PARAM" dig.out.ns3.$n > /dev/null || ret=1 grep "flags:[^;]* aa[ ;]" dig.out.ns3.$n > /dev/null || ret=1 [ $ret = 0 ] || { echo_i "failed"; status=1; } @@ -461,7 +461,7 @@ EOF _ret=1 for i in 0 1 2 3 4 5 6 7 8 9; do $DIG $DIGOPTS +tcp +norec +time=1 +tries=1 @10.53.0.3 nsec3param.test. NSEC3PARAM > dig.out.ns3.$n || _ret=1 - if grep "ANSWER: 2" dig.out.ns3.$n > /dev/null; then + if grep "ANSWER: 2," dig.out.ns3.$n > /dev/null; then _ret=0 break fi @@ -486,7 +486,7 @@ EOF _ret=1 for i in 0 1 2 3 4 5 6 7 8 9; do $DIG $DIGOPTS +tcp +norec +time=1 +tries=1 @10.53.0.3 nsec3param.test. NSEC3PARAM > dig.out.ns3.$n || _ret=1 - if grep "ANSWER: 1" dig.out.ns3.$n > /dev/null; then + if grep "ANSWER: 1," dig.out.ns3.$n > /dev/null; then _ret=0 break fi @@ -639,6 +639,58 @@ then echo_i "failed"; status=1 fi +n=`expr $n + 1` +ret=0 +echo_i "check that 'update-policy subdomain' is properly enforced ($n)" +# "restricted.example.nil" matches "grant ... subdomain restricted.example.nil" +# and thus this UPDATE should succeed. +$NSUPDATE -d < nsupdate.out1-$n 2>&1 || ret=1 +server 10.53.0.1 ${PORT} +key restricted.example.nil 1234abcd8765 +update add restricted.example.nil 0 IN TXT everywhere. +send +END +$DIG $DIGOPTS +tcp @10.53.0.1 restricted.example.nil TXT > dig.out.1.test$n || ret=1 +grep "TXT.*everywhere" dig.out.1.test$n > /dev/null || ret=1 +# "example.nil" does not match "grant ... subdomain restricted.example.nil" and +# thus this UPDATE should fail. +$NSUPDATE -d < nsupdate.out2-$n 2>&1 && ret=1 +server 10.53.0.1 ${PORT} +key restricted.example.nil 1234abcd8765 +update add example.nil 0 IN TXT everywhere. +send +END +$DIG $DIGOPTS +tcp @10.53.0.1 example.nil TXT > dig.out.2.test$n || ret=1 +grep "TXT.*everywhere" dig.out.2.test$n > /dev/null && ret=1 +[ $ret = 0 ] || { echo_i "failed"; status=1; } + +n=`expr $n + 1` +ret=0 +echo_i "check that 'update-policy zonesub' is properly enforced ($n)" +# grant zonesub-key.example.nil zonesub TXT; +# the A record update should be rejected as it is not in the type list +$NSUPDATE -d < nsupdate.out1-$n 2>&1 && ret=1 +server 10.53.0.1 ${PORT} +key zonesub-key.example.nil 1234subk8765 +update add zonesub.example.nil 0 IN A 1.2.3.4 +send +END +$DIG $DIGOPTS +tcp @10.53.0.1 zonesub.example.nil A > dig.out.1.test$n || ret=1 +grep "status: REFUSED" nsupdate.out1-$n > /dev/null || ret=1 +grep "ANSWER: 0," dig.out.1.test$n > /dev/null || ret=1 +# the TXT record update should be accepted as it is in the type list +$NSUPDATE -d < nsupdate.out2-$n 2>&1 || ret=1 +server 10.53.0.1 ${PORT} +key zonesub-key.example.nil 1234subk8765 +update add zonesub.example.nil 0 IN TXT everywhere. +send +END +$DIG $DIGOPTS +tcp @10.53.0.1 zonesub.example.nil TXT > dig.out.2.test$n || ret=1 +grep "status: REFUSED" nsupdate.out2-$n > /dev/null && ret=1 +grep "ANSWER: 1," dig.out.2.test$n > /dev/null || ret=1 +grep "TXT.*everywhere" dig.out.2.test$n > /dev/null || ret=1 +[ $ret = 0 ] || { echo_i "failed"; status=1; } + n=`expr $n + 1` ret=0 echo_i "check that changes to the DNSKEY RRset TTL do not have side effects ($n)" diff --git a/bin/tests/system/run.sh.in b/bin/tests/system/run.sh.in index 0d291a4b01..ed6c2e2a9a 100644 --- a/bin/tests/system/run.sh.in +++ b/bin/tests/system/run.sh.in @@ -70,7 +70,7 @@ if ! $do_run; then if [ "$baseport" -eq 0 ]; then log_flags="$log_flags -p 5300" fi - env - PATH="$PATH" ${LD_LIBRARY_PATH:+"LD_LIBRARY_PATH=${LD_LIBRARY_PATH}"} TESTS="$*" TEST_SUITE_LOG=run.log LOG_DRIVER_FLAGS="--verbose yes --color-tests yes" LOG_FLAGS="$log_flags" make -e check + env - SLOT="$SLOT" SOFTHSM2_CONF="$SOFTHSM2_CONF" PATH="$PATH" ${LD_LIBRARY_PATH:+"LD_LIBRARY_PATH=${LD_LIBRARY_PATH}"} TESTS="$*" TEST_SUITE_LOG=run.log LOG_DRIVER_FLAGS="--verbose yes --color-tests yes" LOG_FLAGS="$log_flags" make -e check exit $? fi diff --git a/configure.ac b/configure.ac index 7f2fe3738d..0418b9fcda 100644 --- a/configure.ac +++ b/configure.ac @@ -14,7 +14,7 @@ # m4_define([bind_VERSION_MAJOR], 9)dnl m4_define([bind_VERSION_MINOR], 17)dnl -m4_define([bind_VERSION_PATCH], 3)dnl +m4_define([bind_VERSION_PATCH], 4)dnl m4_define([bind_VERSION_EXTRA], )dnl m4_define([bind_DESCRIPTION], [(Development Release)])dnl m4_define([bind_SRCID], [m4_esyscmd_s([git rev-parse --short HEAD | cut -b1-7])])dnl diff --git a/doc/arm/notes.rst b/doc/arm/notes.rst index 16a8227d75..681624f3f9 100644 --- a/doc/arm/notes.rst +++ b/doc/arm/notes.rst @@ -53,6 +53,7 @@ information about each release, source code, and pre-compiled versions for Microsoft Windows operating systems. .. include:: ../notes/notes-current.rst +.. include:: ../notes/notes-9.17.4.rst .. include:: ../notes/notes-9.17.3.rst .. include:: ../notes/notes-9.17.2.rst .. include:: ../notes/notes-9.17.1.rst diff --git a/doc/notes/notes-9.17.4.rst b/doc/notes/notes-9.17.4.rst new file mode 100644 index 0000000000..0571babf09 --- /dev/null +++ b/doc/notes/notes-9.17.4.rst @@ -0,0 +1,127 @@ +.. + 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. + +Notes for BIND 9.17.4 +--------------------- + +Security Fixes +~~~~~~~~~~~~~~ + +- It was possible to trigger an assertion failure by sending a specially + crafted large TCP DNS message. This was disclosed in CVE-2020-8620. + + ISC would like to thank Emanuel Almeida of Cisco Systems, Inc. for + bringing this vulnerability to our attention. [GL #1996] + +- ``named`` could crash after failing an assertion check in certain + query resolution scenarios where QNAME minimization and forwarding + were both enabled. To prevent such crashes, QNAME minimization is now + always disabled for a given query resolution process, if forwarders + are used at any point. This was disclosed in CVE-2020-8621. + + ISC would like to thank Joseph Gullo for bringing this vulnerability + to our attention. [GL #1997] + +- It was possible to trigger an assertion failure when verifying the + response to a TSIG-signed request. This was disclosed in + CVE-2020-8622. + + ISC would like to thank Dave Feldman, Jeff Warren, and Joel Cunningham + of Oracle for bringing this vulnerability to our attention. [GL #2028] + +- When BIND 9 was compiled with native PKCS#11 support, it was possible + to trigger an assertion failure in code determining the number of bits + in the PKCS#11 RSA public key with a specially crafted packet. This + was disclosed in CVE-2020-8623. + + ISC would like to thank Lyu Chiy for bringing this vulnerability to + our attention. [GL #2037] + +- ``update-policy`` rules of type ``subdomain`` were incorrectly treated + as ``zonesub`` rules, which allowed keys used in ``subdomain`` rules + to update names outside of the specified subdomains. The problem was + fixed by making sure ``subdomain`` rules are again processed as + described in the ARM. This was disclosed in CVE-2020-8624. + + ISC would like to thank Joop Boonen of credativ GmbH for bringing this + vulnerability to our attention. [GL #2055] + +New Features +~~~~~~~~~~~~ + +- A new configuration option ``stale-cache-enable`` has been introduced + to enable or disable keeping stale answers in cache. [GL #1712] + +- ``rndc`` has been updated to use the new BIND network manager API. + This change had the side effect of altering the TCP timeout for RNDC + connections from 60 seconds to the ``tcp-idle-timeout`` value, which + defaults to 30 seconds. Also, because the network manager currently + has no support for UNIX-domain sockets, those cannot now be used + with ``rndc``. This will be addressed in a future release, either by + restoring UNIX-domain socket support or by formally declaring them + to be obsolete in the control channel. [GL #1759] + +- Statistics channels have also been updated to use the new BIND network + manager API. [GL #2022] + +Feature Changes +~~~~~~~~~~~~~~~ + +- BIND's cache database implementation has been updated to use a faster + hash function with better distribution. In addition, the effective + ``max-cache-size`` (configured explicitly, defaulting to a value based + on system memory or set to ``unlimited``) now pre-allocates fixed-size + hash tables. This prevents interruption to query resolution when the + hash table sizes need to be increased. [GL #1775] + +- Keeping stale answers in cache has been disabled by default. + [GL #1712] + +- Resource records received with 0 TTL are no longer kept in the cache + to be used for stale answers. [GL #1829] + +Bug Fixes +~~~~~~~~~ + +- Wildcard RPZ passthru rules could incorrectly be overridden by other + rules that were loaded from RPZ zones which appeared later in the + ``response-policy`` statement. This has been fixed. [GL #1619] + +- The IPv6 Duplicate Address Detection (DAD) mechanism could + inadvertently prevent ``named`` from binding to new IPv6 interfaces, + by causing multiple route socket messages to be sent for each IPv6 + address. ``named`` monitors for new interfaces to ``bind()`` to when + it is configured to listen on ``any`` or on a specific range of + addresses. New IPv6 interfaces can be in a "tentative" state before + they are fully available for use. When DAD is in use, two messages are + emitted by the route socket: one when the interface first appears and + then a second one when it is fully "up." An attempt by ``named`` to + ``bind()`` to the new interface prematurely would fail, causing it + thereafter to ignore that address/interface. The problem was worked + around by setting the ``IP_FREEBIND`` option on the socket and trying + to ``bind()`` to each IPv6 address again if the first ``bind()`` call + for that address failed with ``EADDRNOTAVAIL``. [GL #2038] + +- Addressed an error in recursive clients stats reporting which could + cause underflow, and even negative statistics. There were occasions + when an incoming query could trigger a prefetch for some eligible + RRset, and if the prefetch code were executed before recursion, no + increment in recursive clients stats would take place. Conversely, + when processing the answers, if the recursion code were executed + before the prefetch, the same counter would be decremented without a + matching increment. [GL #1719] + +- The introduction of KASP support inadvertently caused the second field + of ``sig-validity-interval`` to always be calculated in hours, even in + cases when it should have been calculated in days. This has been + fixed. (Thanks to Tony Finch.) [GL !3735] + +- LMDB locking code was revised to make ``rndc reconfig`` work properly + on FreeBSD and with LMDB >= 0.9.26. [GL #1976] diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index bb2edc1278..3c367f9cde 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -8,7 +8,7 @@ See the COPYRIGHT file distributed with this work for additional information regarding copyright ownership. -Notes for BIND 9.17.4 +Notes for BIND 9.17.5 --------------------- Security Fixes @@ -29,56 +29,12 @@ New Features from the parent. Replaces the time-based ``parent-registration-delay`` configuration option. [GL #1613] -- ``rndc`` has been updated to use the new BIND network manager API. - This change had the side effect of altering the TCP timeout for RNDC - connections from 60 seconds to the ``tcp-idle-timeout`` value, which - defaults to 30 seconds. Also, because the network manager currently - has no support for UNIX-domain sockets, those cannot now be used - with ``rndc``. This will be addressed in a future release, either by - restoring UNIX-domain socket support or by formally declaring them - to be obsolete in the control channel. [GL #1759] - -- Statistics channels have also been updated to use the new BIND network - manager API. [GL #2022] - -- A new configuration option ``stale-cache-enable`` has been introduced to - enable or disable the keeping of stale answers in cache. [GL #1712] - Feature Changes ~~~~~~~~~~~~~~~ -- BIND's cache database implementation has been updated to use a faster - hash-function with better distribution. In addition, the effective - max-cache-size (configured explicitly, defaulting to a value based on system - memory or set to 'unlimited') now pre-allocates fixed size hash tables. This - prevents interruption to query resolution when the hash tables need to be - increased in size. [GL #1775] - -- Keeping stale answers in cache has been disabled by default. - -- The resource records received with 0 TTL are no longer kept in the cache - to be used for stale answers. [GL #1829] +- None. Bug Fixes ~~~~~~~~~ -- Addressed an error in recursive clients stats reporting. - There were occasions when an incoming query could trigger a prefetch for - some eligible rrset, and if the prefetch code were executed before recursion, - no increment in recursive clients stats would take place. Conversely, - when processing the answers, if the recursion code were executed before the - prefetch, the same counter would be decremented without a matching increment. - [GL #1719] - -- The introduction of KASP support broke whether the second field - of sig-validity-interval was treated as days or hours. (Thanks to - Tony Finch.) [GL !3735] - -- The IPv6 Duplicate Address Detection (DAD) mechanism could cause the operating - system to report the new IPv6 addresses to the applications via the - getifaddrs() API in a tentative (DAD not yet finished) or duplicate (DAD - failed) state. Such addresses cannot be bound by an application, and named - failed to listen on IPv6 addresses after the DAD mechanism finished. It is - possible to work around the issue by setting the IP_FREEBIND option on the - socket and trying to bind() to the IPv6 address again if the first bind() call - fails with EADDRNOTAVAIL. [GL #2038] +- None. diff --git a/fuzz/Makefile.am b/fuzz/Makefile.am index d3c858a606..9eecd6111c 100644 --- a/fuzz/Makefile.am +++ b/fuzz/Makefile.am @@ -15,6 +15,7 @@ LDADD = \ check_LTLIBRARIES = libfuzzmain.la libfuzzmain_la_SOURCES = \ + fuzz.h \ main.c check_PROGRAMS = \ diff --git a/lib/bind9/api b/lib/bind9/api index 1612f27a5d..334285afed 100644 --- a/lib/bind9/api +++ b/lib/bind9/api @@ -12,5 +12,5 @@ # 9.15/9.16: 1500-1699 # 9.17/9.18: 1700-1899 LIBINTERFACE = 1701 -LIBREVISION = 1 +LIBREVISION = 2 LIBAGE = 0 diff --git a/lib/dns/api b/lib/dns/api index c1c1be9b85..0708982280 100644 --- a/lib/dns/api +++ b/lib/dns/api @@ -11,6 +11,6 @@ # 9.13/9.14: 1300-1499 # 9.15/9.16: 1500-1699 # 9.17/9.18: 1700-1899 -LIBINTERFACE = 1703 +LIBINTERFACE = 1704 LIBREVISION = 0 -LIBAGE = 0 +LIBAGE = 1 diff --git a/lib/dns/message.c b/lib/dns/message.c index dd9dd23a12..97425c753b 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -1709,6 +1709,16 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source, msg->header_ok = 0; msg->question_ok = 0; + if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0) { + isc_buffer_usedregion(&origsource, &msg->saved); + } else { + msg->saved.length = isc_buffer_usedlength(&origsource); + msg->saved.base = isc_mem_get(msg->mctx, msg->saved.length); + memmove(msg->saved.base, isc_buffer_base(&origsource), + msg->saved.length); + msg->free_saved = 1; + } + isc_buffer_remainingregion(source, &r); if (r.length < DNS_MESSAGE_HEADERLEN) { return (ISC_R_UNEXPECTEDEND); @@ -1793,15 +1803,6 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source, } truncated: - if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0) { - isc_buffer_usedregion(&origsource, &msg->saved); - } else { - msg->saved.length = isc_buffer_usedlength(&origsource); - msg->saved.base = isc_mem_get(msg->mctx, msg->saved.length); - memmove(msg->saved.base, isc_buffer_base(&origsource), - msg->saved.length); - msg->free_saved = 1; - } if (ret == ISC_R_UNEXPECTEDEND && ignore_tc) { return (DNS_R_RECOVERABLE); diff --git a/lib/dns/pkcs11rsa_link.c b/lib/dns/pkcs11rsa_link.c index fc5efe3bb8..c31ae33da9 100644 --- a/lib/dns/pkcs11rsa_link.c +++ b/lib/dns/pkcs11rsa_link.c @@ -292,6 +292,7 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, key->key_alg == DST_ALG_NSEC3RSASHA1 || key->key_alg == DST_ALG_RSASHA256 || key->key_alg == DST_ALG_RSASHA512); + REQUIRE(maxbits <= RSA_MAX_PUBEXP_BITS); /* * Reject incorrect RSA key lengths. @@ -334,6 +335,7 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) + { switch (attr->type) { case CKA_MODULUS: INSIST(keyTemplate[5].type == attr->type); @@ -350,13 +352,16 @@ pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; - if (pk11_numbits(attr->pValue, attr->ulValueLen) > - maxbits && - maxbits != 0) { + unsigned int bits; + ret = pk11_numbits(attr->pValue, attr->ulValueLen, + &bits); + if (ret != ISC_R_SUCCESS || + (bits > maxbits && maxbits != 0)) { DST_RET(DST_R_VERIFYFAILURE); } break; } + } pk11_ctx->object = CK_INVALID_HANDLE; pk11_ctx->ontoken = false; PK11_RET(pkcs_C_CreateObject, @@ -957,14 +962,17 @@ pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) { keyTemplate[5].ulValueLen = attr->ulValueLen; break; case CKA_PUBLIC_EXPONENT: + unsigned int bits; INSIST(keyTemplate[6].type == attr->type); keyTemplate[6].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); memmove(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); keyTemplate[6].ulValueLen = attr->ulValueLen; - if (pk11_numbits(attr->pValue, attr->ulValueLen) > - RSA_MAX_PUBEXP_BITS) { + ret = pk11_numbits(attr->pValue, attr->ulValueLen, + &bits); + if (ret != ISC_R_SUCCESS || bits > RSA_MAX_PUBEXP_BITS) + { DST_RET(DST_R_VERIFYFAILURE); } break; @@ -1335,6 +1343,8 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { CK_BYTE *exponent = NULL, *modulus = NULL; CK_ATTRIBUTE *attr; unsigned int length; + unsigned int bits; + isc_result_t ret = ISC_R_SUCCESS; isc_buffer_remainingregion(data, &r); if (r.length == 0) { @@ -1351,9 +1361,7 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { if (e_bytes == 0) { if (r.length < 2) { - isc_safe_memwipe(rsa, sizeof(*rsa)); - isc_mem_put(key->mctx, rsa, sizeof(*rsa)); - return (DST_R_INVALIDPUBLICKEY); + DST_RET(DST_R_INVALIDPUBLICKEY); } e_bytes = (*r.base) << 8; isc_region_consume(&r, 1); @@ -1362,16 +1370,18 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { } if (r.length < e_bytes) { - isc_safe_memwipe(rsa, sizeof(*rsa)); - isc_mem_put(key->mctx, rsa, sizeof(*rsa)); - return (DST_R_INVALIDPUBLICKEY); + DST_RET(DST_R_INVALIDPUBLICKEY); } exponent = r.base; isc_region_consume(&r, e_bytes); modulus = r.base; mod_bytes = r.length; - key->key_size = pk11_numbits(modulus, mod_bytes); + ret = pk11_numbits(modulus, mod_bytes, &bits); + if (ret != ISC_R_SUCCESS) { + goto err; + } + key->key_size = bits; isc_buffer_forward(data, length); @@ -1391,6 +1401,10 @@ pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { key->keydata.pkey = rsa; return (ISC_R_SUCCESS); +err: + isc_safe_memwipe(rsa, sizeof(*rsa)); + isc_mem_put(key->mctx, rsa, sizeof(*rsa)); + return (ret); } static isc_result_t @@ -1564,6 +1578,7 @@ pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label, pk11_object_t *pubrsa; pk11_context_t *pk11_ctx = NULL; isc_result_t ret; + unsigned int bits; if (label == NULL) { return (DST_R_NOENGINE); @@ -1642,7 +1657,11 @@ pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label, attr = pk11_attribute_bytype(rsa, CKA_MODULUS); INSIST(attr != NULL); - key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); + ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); + if (ret != ISC_R_SUCCESS) { + goto err; + } + key->key_size = bits; return (ISC_R_SUCCESS); @@ -1734,6 +1753,7 @@ pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { CK_ATTRIBUTE *attr; isc_mem_t *mctx = key->mctx; const char *engine = NULL, *label = NULL; + unsigned int bits; /* read private key file */ ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); @@ -1871,12 +1891,20 @@ pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { attr = pk11_attribute_bytype(rsa, CKA_MODULUS); INSIST(attr != NULL); - key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); + ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); + if (ret != ISC_R_SUCCESS) { + goto err; + } + key->key_size = bits; attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); INSIST(attr != NULL); - if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS) - { + + ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); + if (ret != ISC_R_SUCCESS) { + goto err; + } + if (bits > RSA_MAX_PUBEXP_BITS) { DST_RET(ISC_R_RANGE); } @@ -1911,6 +1939,7 @@ pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label, pk11_context_t *pk11_ctx = NULL; isc_result_t ret; unsigned int i; + unsigned int bits; UNUSED(pin); @@ -1996,14 +2025,22 @@ pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label, attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); INSIST(attr != NULL); - if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS) - { + + ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); + if (ret != ISC_R_SUCCESS) { + goto err; + } + if (bits > RSA_MAX_PUBEXP_BITS) { DST_RET(ISC_R_RANGE); } attr = pk11_attribute_bytype(rsa, CKA_MODULUS); INSIST(attr != NULL); - key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); + ret = pk11_numbits(attr->pValue, attr->ulValueLen, &bits); + if (ret != ISC_R_SUCCESS) { + goto err; + } + key->key_size = bits; pk11_return_session(pk11_ctx); isc_safe_memwipe(pk11_ctx, sizeof(*pk11_ctx)); diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 21f8d96e0e..df43b0a09a 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -4013,6 +4013,15 @@ fctx_nextaddress(fetchctx_t *fctx) { addrinfo->flags |= FCTX_ADDRINFO_MARK; fctx->find = NULL; fctx->forwarding = true; + + /* + * QNAME minimization is disabled when + * forwarding, and has to remain disabled if + * we switch back to normal recursion; otherwise + * forwarding could leave us in an inconsistent + * state. + */ + fctx->minimized = false; return (addrinfo); } } diff --git a/lib/isc/api b/lib/isc/api index c1c1be9b85..2a38956a54 100644 --- a/lib/isc/api +++ b/lib/isc/api @@ -11,6 +11,6 @@ # 9.13/9.14: 1300-1499 # 9.15/9.16: 1500-1699 # 9.17/9.18: 1700-1899 -LIBINTERFACE = 1703 +LIBINTERFACE = 1704 LIBREVISION = 0 LIBAGE = 0 diff --git a/lib/isc/include/pk11/internal.h b/lib/isc/include/pk11/internal.h index dfdf526eeb..05be8997d3 100644 --- a/lib/isc/include/pk11/internal.h +++ b/lib/isc/include/pk11/internal.h @@ -30,8 +30,8 @@ pk11_mem_put(void *ptr, size_t size); CK_SLOT_ID pk11_get_best_token(pk11_optype_t optype); -unsigned int -pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt); +isc_result_t +pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt, unsigned int *bits); CK_ATTRIBUTE * pk11_attribute_first(const pk11_object_t *obj); diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index b5593a7f59..6f4d1ff3e7 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -559,16 +559,6 @@ isc__nm_enqueue_ievent(isc__networker_t *worker, isc__netievent_t *event); * way to use an isc__networker_t from another thread.) */ -void -isc__nm_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf); -/*%< - * Allocator for recv operations. - * - * Note that as currently implemented, this doesn't actually - * allocate anything, it just assigns the the isc__networker's UDP - * receive buffer to a socket, and marks it as "in use". - */ - void isc__nm_free_uvbuf(isc_nmsocket_t *sock, const uv_buf_t *buf); /*%< diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 30260afb29..bb10557e9c 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -1003,23 +1003,6 @@ isc__nmsocket_clearcb(isc_nmsocket_t *sock) { sock->accept_cbarg = NULL; } -void -isc__nm_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf) { - isc_nmsocket_t *sock = uv_handle_get_data(handle); - isc__networker_t *worker = NULL; - - REQUIRE(VALID_NMSOCK(sock)); - REQUIRE(isc__nm_in_netthread()); - REQUIRE(size <= ISC_NETMGR_RECVBUF_SIZE); - - worker = &sock->mgr->workers[sock->tid]; - INSIST(!worker->recvbuf_inuse); - - buf->base = worker->recvbuf; - worker->recvbuf_inuse = true; - buf->len = ISC_NETMGR_RECVBUF_SIZE; -} - void isc__nm_free_uvbuf(isc_nmsocket_t *sock, const uv_buf_t *buf) { isc__networker_t *worker = NULL; @@ -1032,7 +1015,7 @@ isc__nm_free_uvbuf(isc_nmsocket_t *sock, const uv_buf_t *buf) { worker = &sock->mgr->workers[sock->tid]; REQUIRE(worker->recvbuf_inuse); - if (buf->base > worker->recvbuf && + if (sock->type == isc_nm_udpsocket && buf->base > worker->recvbuf && buf->base <= worker->recvbuf + ISC_NETMGR_RECVBUF_SIZE) { /* Can happen in case of out-of-order recvmmsg in libuv1.36 */ diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index 558b685caf..73b8b1fa0b 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -637,6 +637,30 @@ isc__nm_tcp_read(isc_nmhandle_t *handle, isc_nm_recv_cb_t cb, void *cbarg) { return (ISC_R_SUCCESS); } +/*%< + * Allocator for TCP read operations. Limited to size 2^16. + * + * Note this doesn't actually allocate anything, it just assigns the + * worker's receive buffer to a socket, and marks it as "in use". + */ +static void +tcp_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf) { + isc_nmsocket_t *sock = uv_handle_get_data(handle); + isc__networker_t *worker = NULL; + + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_tcpsocket); + REQUIRE(isc__nm_in_netthread()); + REQUIRE(size <= 65536); + + worker = &sock->mgr->workers[sock->tid]; + INSIST(!worker->recvbuf_inuse); + + buf->base = worker->recvbuf; + buf->len = size; + worker->recvbuf_inuse = true; +} + void isc__nm_async_tcp_startread(isc__networker_t *worker, isc__netievent_t *ev0) { isc__netievent_startread_t *ievent = (isc__netievent_startread_t *)ev0; @@ -654,7 +678,7 @@ isc__nm_async_tcp_startread(isc__networker_t *worker, isc__netievent_t *ev0) { 0); } - r = uv_read_start(&sock->uv_handle.stream, isc__nm_alloc_cb, read_cb); + r = uv_read_start(&sock->uv_handle.stream, tcp_alloc_cb, read_cb); if (r != 0) { isc__nm_incstats(sock->mgr, sock->statsindex[STATID_RECVFAIL]); } diff --git a/lib/isc/netmgr/udp.c b/lib/isc/netmgr/udp.c index 544a967ae9..ff981f920f 100644 --- a/lib/isc/netmgr/udp.c +++ b/lib/isc/netmgr/udp.c @@ -132,6 +132,32 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_nmiface_t *iface, isc_nm_recv_cb_t cb, return (ISC_R_SUCCESS); } +/*%< + * Allocator for UDP recv operations. Limited to size 20 * (2^16 + 2), + * which allows enough space for recvmmsg() to get multiple messages at + * a time. + * + * Note this doesn't actually allocate anything, it just assigns the + * worker's receive buffer to a socket, and marks it as "in use". + */ +static void +udp_alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf) { + isc_nmsocket_t *sock = uv_handle_get_data(handle); + isc__networker_t *worker = NULL; + + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_udpsocket); + REQUIRE(isc__nm_in_netthread()); + REQUIRE(size <= ISC_NETMGR_RECVBUF_SIZE); + + worker = &sock->mgr->workers[sock->tid]; + INSIST(!worker->recvbuf_inuse); + + buf->base = worker->recvbuf; + buf->len = ISC_NETMGR_RECVBUF_SIZE; + worker->recvbuf_inuse = true; +} + /* * handle 'udplisten' async call - start listening on a socket. */ @@ -193,7 +219,7 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) { uv_send_buffer_size(&sock->uv_handle.handle, &(int){ ISC_SEND_BUFFER_SIZE }); #endif - uv_udp_recv_start(&sock->uv_handle.udp, isc__nm_alloc_cb, udp_recv_cb); + uv_udp_recv_start(&sock->uv_handle.udp, udp_alloc_cb, udp_recv_cb); } static void diff --git a/lib/isc/pk11.c b/lib/isc/pk11.c index bc910d7fdf..315f1170e9 100644 --- a/lib/isc/pk11.c +++ b/lib/isc/pk11.c @@ -652,13 +652,14 @@ pk11_get_best_token(pk11_optype_t optype) { return (token->slotid); } -unsigned int -pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt) { +isc_result_t +pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt, unsigned int *bits) { unsigned int bitcnt, i; CK_BYTE top; if (bytecnt == 0) { - return (0); + *bits = 0; + return (ISC_R_SUCCESS); } bitcnt = bytecnt * 8; for (i = 0; i < bytecnt; i++) { @@ -668,33 +669,40 @@ pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt) { continue; } if (top & 0x80) { - return (bitcnt); + *bits = bitcnt; + return (ISC_R_SUCCESS); } if (top & 0x40) { - return (bitcnt - 1); + *bits = bitcnt - 1; + return (ISC_R_SUCCESS); } if (top & 0x20) { - return (bitcnt - 2); + *bits = bitcnt - 2; + return (ISC_R_SUCCESS); } if (top & 0x10) { - return (bitcnt - 3); + *bits = bitcnt - 3; + return (ISC_R_SUCCESS); } if (top & 0x08) { - return (bitcnt - 4); + *bits = bitcnt - 4; + return (ISC_R_SUCCESS); } if (top & 0x04) { - return (bitcnt - 5); + *bits = bitcnt - 5; + return (ISC_R_SUCCESS); } if (top & 0x02) { - return (bitcnt - 6); + *bits = bitcnt - 6; + return (ISC_R_SUCCESS); } if (top & 0x01) { - return (bitcnt - 7); + *bits = bitcnt - 7; + return (ISC_R_SUCCESS); } break; } - INSIST(0); - ISC_UNREACHABLE(); + return (ISC_R_RANGE); } CK_ATTRIBUTE * diff --git a/lib/isccc/api b/lib/isccc/api index 88c9b9df52..ac7231dc34 100644 --- a/lib/isccc/api +++ b/lib/isccc/api @@ -11,6 +11,6 @@ # 9.13/9.14: 1300-1499 # 9.15/9.16: 1500-1699 # 9.17/9.18: 1700-1899 -LIBINTERFACE = 1701 +LIBINTERFACE = 1702 LIBREVISION = 0 LIBAGE = 0 diff --git a/lib/isccfg/api b/lib/isccfg/api index 1612f27a5d..334285afed 100644 --- a/lib/isccfg/api +++ b/lib/isccfg/api @@ -12,5 +12,5 @@ # 9.15/9.16: 1500-1699 # 9.17/9.18: 1700-1899 LIBINTERFACE = 1701 -LIBREVISION = 1 +LIBREVISION = 2 LIBAGE = 0 diff --git a/lib/ns/api b/lib/ns/api index c1c1be9b85..6c720712b8 100644 --- a/lib/ns/api +++ b/lib/ns/api @@ -12,5 +12,5 @@ # 9.15/9.16: 1500-1699 # 9.17/9.18: 1700-1899 LIBINTERFACE = 1703 -LIBREVISION = 0 +LIBREVISION = 1 LIBAGE = 0 diff --git a/util/copyrights b/util/copyrights index 6ea744aaee..2503b7ad17 100644 --- a/util/copyrights +++ b/util/copyrights @@ -1231,7 +1231,7 @@ ./doc/notes/notes-9.17.1.rst RST 2020 ./doc/notes/notes-9.17.2.rst RST 2020 ./doc/notes/notes-9.17.3.rst RST 2020 -./doc/notes/notes-current.rst RST 2020 +./doc/notes/notes-9.17.4.rst RST 2020 ./docutil/HTML_COPYRIGHT X 2001,2004,2016,2018,2019,2020 ./docutil/MAN_COPYRIGHT X 2001,2004,2016,2018,2019,2020 ./docutil/patch-db2latex-duplicate-template-bug X 2007,2018,2019,2020