Commit Graph

12641 Commits

Author SHA1 Message Date
Mark Andrews
9675d83b96 X25: Check that record is all ASCII digits
(cherry picked from commit 7e49689746)
2020-08-14 00:38:45 +10:00
Mark Andrews
ee10a93cbc WKS: reject records with zero octets at the end of the bitmap
(cherry picked from commit 9d446142d8)
2020-08-14 00:38:45 +10:00
Mark Andrews
e44da35092 TLSA: fix fromwire length checks
(cherry picked from commit 3429c35f52)
2020-08-14 00:38:45 +10:00
Mark Andrews
b4a66cffa8 SIG: reject records with a zero length signature
(cherry picked from commit 9b93e5d684)
2020-08-14 00:38:45 +10:00
Mark Andrews
10e8ad22c5 NXT: fix fromwire bitmap checks
(cherry picked from commit 73dd849655)
2020-08-14 00:38:45 +10:00
Mark Andrews
c712394b34 NSEC3PARAM: check that saltlen is consistent with the rdata length
(cherry picked from commit 7dc8e720ff)
2020-08-14 00:38:45 +10:00
Mark Andrews
26be6c817b NSEC3: reject records with a zero length hash field
(cherry picked from commit 031ee9e279)
2020-08-14 00:38:45 +10:00
Mark Andrews
ebd8033a96 IPSECKEY: require non-zero length public keys
(cherry picked from commit d7f7014803)
2020-08-14 00:38:45 +10:00
Mark Andrews
baf7d114af CERT: reject records with a empty certificate field
(cherry picked from commit a238f37239)
2020-08-14 00:38:45 +10:00
Mark Andrews
f09691feff Get rid of type 'RESERVED0'.
(cherry picked from commit 3c492b3ef1)
2020-08-14 00:38:45 +10:00
Mark Andrews
5806d856cf base32_decode*() could incorrectly decode a input.
base32_decode_char() added a extra zero octet to the output
if the fifth character was a pad character.  The length
of octets to copy to the output was set to 3 instead of 2.

(cherry picked from commit 6c7e50c267)
2020-08-14 00:11:06 +10:00
Mark Andrews
f3b25f1ffb Address use after free between view, resolver and nta.
Hold a weak reference to the view so that it can't go away while
nta is performing its lookups.  Cancel nta timers once all external
references to the view have gone to prevent them triggering new work.

(cherry picked from commit 0b2555e8cf)
2020-08-11 11:55:44 +10:00
Ondřej Surý
f0ccc17f30 Reduce the default RBT hash table size to 16 entries (4 bits)
The hash table rework MRs (!3865, !3871) increased the default RBT hash
table size from 64 to 65,536 entries (for 64-bit architectures, that is
512 bytes before vs. 524,288 bytes after).  This works fine for RBTs
used for cache databases, but since three separate RBT databases are
created for every zone loaded (RRs, NSEC, NSEC3), memory usage would
skyrocket when BIND 9 is used as an authoritative DNS server with many
zones.

The default RBT hash table size before the rework was 64 entries, this
commit reduces it to 16 entries because our educated guess is that most
zones are just couple of entries (SOA, NS, A, AAAA, MX) and rehashing
small hash tables is actually cheap.  The rework we did in the previous
MRs tries to avoid growing the hash tables for big-to-huge caches where
growing the hash table comes at a price because the whole cache needs to
be locked.

(cherry picked from commit 1e043a011b)
2020-08-10 10:32:26 +02:00
Mark Andrews
8a4dd25562 Silence 'may be used uninitialized' 2020-08-08 16:12:12 +10:00
Matthijs Mekking
624f1b9531 rndc dnssec -checkds set algorithm
In the rare case that you have multiple keys acting as KSK and that
have the same keytag, you can now set the algorithm when calling
'-checkds'.

(cherry picked from commit 46fcd927e7)
2020-08-07 13:34:10 +02:00
Matthijs Mekking
4892006a92 Make 'parent-registration-delay' obsolete
With the introduction of 'checkds', the 'parent-registration-delay'
option becomes obsolete.

(cherry picked from commit a25f49f153)
2020-08-07 13:30:50 +02:00
Matthijs Mekking
5dcf56f216 Fix time printing in key files
Don't strip off the final character when printing times in key files.

With the introduction of 'rndc dnssec -status' we introduced
'isc_stdtime_tostring()'. This changed in behavior such that it was no
longer needed to strip of the final '\n' of the string format
datetime. However, in 'printtime()' it still stripped the final
character.

(cherry picked from commit e3eb55fd1c)
2020-08-07 13:30:30 +02:00
Matthijs Mekking
81d0c63ecb Implement 'rndc dnssec -checkds'
Add a new 'rndc' command 'dnssec -checkds' that allows the user to
signal named that a new DS record has been seen published in the
parent, or that an existing DS record has been withdrawn from the
parent.

Upon the 'checkds' request, 'named' will write out the new state for
the key, updating the 'DSPublish' or 'DSRemoved' timing metadata.

This replaces the "parent-registration-delay" configuration option,
this was unreliable because it was purely time based (if the user
did not actually submit the new DS to the parent for example, this
could result in an invalid DNSSEC state).

Because we cannot rely on the parent registration delay for state
transition, we need to replace it with a different guard. Instead,
if a key wants its DS state to be moved to RUMOURED, the "DSPublish"
time must be set and must not be in the future. If a key wants its
DS state to be moved to UNRETENTIVE, the "DSRemoved" time must be set
and must not be in the future.

By default, with '-checkds' you set the time that the DS has been
published or withdrawn to now, but you can set a different time with
'-when'. If there is only one KSK for the zone, that key has its
DS state moved to RUMOURED. If there are multiple keys for the zone,
specify the right key with '-key'.

(cherry picked from commit 04d8fc0143)
2020-08-07 13:30:19 +02:00
Ondřej Surý
f9711481ad Expire the 0 TTL RRSet quickly rather using them for serve-stale
When a received RRSet has TTL 0, they would be preserved for
serve-stale (default `max-stale-cache` is 12 hours) rather than expiring
them quickly from the cache database.

This commit makes sure the RRSet didn't have TTL 0 before marking the
entry in the database as "stale".

(cherry picked from commit 6ffa2ddae0)
2020-08-05 09:09:16 +02:00
Ondřej Surý
b48e9ab201 Add stale-cache-enable option and disable serve-stable by default
The current serve-stale implementation in BIND 9 stores all received
records in the cache for a max-stale-ttl interval (default 12 hours).

This allows DNS operators to turn the serve-stale answers in an event of
large authoritative DNS outage.  The caching of the stale answers needs
to be enabled before the outage happens or the feature would be
otherwise useless.

The negative consequence of the default setting is the inevitable
cache-bloat that happens for every and each DNS operator running named.

In this MR, a new configuration option `stale-cache-enable` is
introduced that allows the operators to selectively enable or disable
the serve-stale feature of BIND 9 based on their decision.

The newly introduced option has been disabled by default,
e.g. serve-stale is disabled in the default configuration and has to be
enabled if required.

(cherry picked from commit ce53db34d6)
2020-08-05 09:09:16 +02:00
Mark Andrews
2dc26ebdb6 Map DNS_R_BADTSIG to FORMERR
Now that the log message has been printed set the result code to
DNS_R_FORMERR.  We don't do this via dns_result_torcode() as we
don't want upstream errors to produce FORMERR if that processing
end with DNS_R_BADTSIG.

(cherry picked from commit 20488d6ad3)
2020-08-04 23:04:34 +10:00
Diego Fronza
fca1000ee9 Fix ns_statscounter_recursclients underflow
The basic scenario for the problem was that in the process of
resolving a query, if any rrset was eligible for prefetching, then it
would trigger a call to query_prefetch(), this call would run in
parallel to the normal query processing.

The problem arises due to the fact that both query_prefetch(), and,
in the original thread, a call to ns_query_recurse(), try to attach
to the recursionquota, but recursing client stats counter is only
incremented if ns_query_recurse() attachs to it first.

Conversely, if fetch_callback() is called before prefetch_done(),
it would not only detach from recursionquota, but also decrement
the stats counter, if query_prefetch() attached to te quota first
that would result in a decrement not matched by an increment, as
expected.

To solve this issue an atomic bool was added, it is set once in
ns_query_recurse(), allowing fetch_callback() to check for it
and decrement stats accordingly.

For a more compreensive explanation check the thread comment below:
https://gitlab.isc.org/isc-projects/bind9/-/issues/1719#note_145857
2020-08-03 19:18:04 -03:00
Witold Kręcicki
a12076cc52 netmgr: retry binding with IP_FREEBIND when EADDRNOTAVAIL is returned.
When a new IPv6 interface/address appears it's first in a tentative
state - in which we cannot bind to it, yet it's already being reported
by the route socket. Because of that BIND9 is unable to listen on any
newly detected IPv6 addresses. Fix it by setting IP_FREEBIND option (or
equivalent option on other OSes) and then retrying bind() call.

(cherry picked from commit a0f7d28967)
2020-07-31 13:33:06 +02:00
Mark Andrews
14fe6e77a7 Always check the return from isc_refcount_decrement.
Created isc_refcount_decrement_expect macro to test conditionally
the return value to ensure it is in expected range.  Converted
unchecked isc_refcount_decrement to use isc_refcount_decrement_expect.
Converted INSIST(isc_refcount_decrement()...) to isc_refcount_decrement_expect.

(cherry picked from commit bde5c7632a)
2020-07-31 12:54:47 +10:00
Mark Andrews
1981fb1327 Refactor the code that counts the last log version to keep
When silencing the Coverity warning in remove_old_tsversions(), the code
was refactored to reduce the indentation levels and break down the long
code into individual functions.  This improve fix for [GL #1989].

(cherry picked from commit aca18b8b5b)
2020-07-31 10:01:36 +10:00
Ondřej Surý
0fff3008ac Change the dns_name hashing to use 32-bit values
Change the dns_hash_name() and dns_hash_fullname() functions to use
isc_hash32() as the maximum hashtable size in rbt is 0..UINT32_MAX
large.

(cherry picked from commit a9182c89a6)
2020-07-30 11:57:24 +02:00
Ondřej Surý
ebb2b055cc Add isc_hash32() and rename isc_hash_function() to isc_hash64()
As the names suggest the original isc_hash64 function returns 64-bit
long hash values and the isc_hash32() returns 32-bit values.

(cherry picked from commit f59fd49fd8)
2020-07-30 11:57:24 +02:00
Ondřej Surý
1e5df7f3bf Add HalfSipHash 2-4 reference implementation
The HalfSipHash implementation has 32-bit keys and returns 32-bit
value.

(cherry picked from commit 344d66aaff)
2020-07-30 11:57:24 +02:00
Ondřej Surý
d89eb403f3 Remove OpenSSL based SipHash 2-4 implementation
Creation of EVP_MD_CTX and EVP_PKEY is quite expensive, so until we fix the code
to reuse the OpenSSL contexts and keys we'll use our own implementation of
siphash instead of trying to integrate with OpenSSL.

(cherry picked from commit 21d751dfc7)
2020-07-30 11:57:24 +02:00
Ondřej Surý
aa72c31422 Fix the rbt hashtable and grow it when setting max-cache-size
There were several problems with rbt hashtable implementation:

1. Our internal hashing function returns uint64_t value, but it was
   silently truncated to unsigned int in dns_name_hash() and
   dns_name_fullhash() functions.  As the SipHash 2-4 higher bits are
   more random, we need to use the upper half of the return value.

2. The hashtable implementation in rbt.c was using modulo to pick the
   slot number for the hash table.  This has several problems because
   modulo is: a) slow, b) oblivious to patterns in the input data.  This
   could lead to very uneven distribution of the hashed data in the
   hashtable.  Combined with the single-linked lists we use, it could
   really hog-down the lookup and removal of the nodes from the rbt
   tree[a].  The Fibonacci Hashing is much better fit for the hashtable
   function here.  For longer description, read "Fibonacci Hashing: The
   Optimization that the World Forgot"[b] or just look at the Linux
   kernel.  Also this will make Diego very happy :).

3. The hashtable would rehash every time the number of nodes in the rbt
   tree would exceed 3 * (hashtable size).  The overcommit will make the
   uneven distribution in the hashtable even worse, but the main problem
   lies in the rehashing - every time the database grows beyond the
   limit, each subsequent rehashing will be much slower.  The mitigation
   here is letting the rbt know how big the cache can grown and
   pre-allocate the hashtable to be big enough to actually never need to
   rehash.  This will consume more memory at the start, but since the
   size of the hashtable is capped to `1 << 32` (e.g. 4 mio entries), it
   will only consume maximum of 32GB of memory for hashtable in the
   worst case (and max-cache-size would need to be set to more than
   4TB).  Calling the dns_db_adjusthashsize() will also cap the maximum
   size of the hashtable to the pre-computed number of bits, so it won't
   try to consume more gigabytes of memory than available for the
   database.

   FIXME: What is the average size of the rbt node that gets hashed?  I
   chose the pagesize (4k) as initial value to precompute the size of
   the hashtable, but the value is based on feeling and not any real
   data.

For future work, there are more places where we use result of the hash
value modulo some small number and that would benefit from Fibonacci
Hashing to get better distribution.

Notes:
a. A doubly linked list should be used here to speedup the removal of
   the entries from the hashtable.
b. https://probablydance.com/2018/06/16/fibonacci-hashing-the-optimization-that-the-world-forgot-or-a-better-alternative-to-integer-modulo/

(cherry picked from commit e24bc324b4)
2020-07-30 11:57:24 +02:00
Michał Kępień
b6c33087b0 Fix idle timeout for connected TCP sockets
When named acting as a resolver connects to an authoritative server over
TCP, it sets the idle timeout for that connection to 20 seconds.  This
fixed timeout was picked back when the default processing timeout for
each client query was hardcoded to 30 seconds.  Commit
000a8970f8 made this processing timeout
configurable through "resolver-query-timeout" and decreased its default
value to 10 seconds, but the idle TCP timeout was not adjusted to
reflect that change.  As a result, with the current defaults in effect,
a single hung TCP connection will consistently cause the resolution
process for a given query to time out.

Set the idle timeout for connected TCP sockets to half of the client
query processing timeout configured for a resolver.  This allows named
to handle hung TCP connections more robustly and prevents the timeout
mismatch issue from resurfacing in the future if the default is ever
changed again.

(cherry picked from commit 953d704bd2)
2020-07-30 11:16:09 +02:00
Diego Fronza
a8ce7b461c Fix rpz wildcard name matching
Whenever an exact match is found by dns_rbt_findnode(),
the highest level node in the chain will not be put into
chain->levels[] array, but instead the chain->end
pointer will be adjusted to point to that node.

Suppose we have the following entries in a rpz zone:
example.com     CNAME rpz-passthru.
*.example.com   CNAME rpz-passthru.

A query for www.example.com would result in the
following chain object returned by dns_rbt_findnode():

chain->level_count = 2
chain->level_matches = 2
chain->levels[0] = .
chain->levels[1] = example.com
chain->levels[2] = NULL
chain->end = www

Since exact matches only care for testing rpz set bits,
we need to test for rpz wild bits through iterating the nodechain, and
that includes testing the rpz wild bits in the highest level node found.

In the case of an exact match, chain->levels[chain->level_matches]
will be NULL, to address that we must use chain->end as the start point,
then iterate over the remaining levels in the chain.
2020-07-27 17:02:16 -03:00
Mark Andrews
b0942c2442 Check walking the hip rendezvous servers.
Also fixes extraneous white space at end of record when
there are no rendezvous servers.

(cherry picked from commit 78db46d746)
2020-07-24 15:24:49 +10:00
Petr Menšík
ac79d68765 Remove few lines in unix socket handling
Reuse the same checks two times, make difference minimal.

(cherry picked from commit 72d81c4768)
2020-07-24 13:47:26 +10:00
Tinderbox User
b03a635f68 prep 9.16.5 2020-07-15 23:10:55 +02:00
Matthijs Mekking
4dabb688db Check return value of dst_key_getbool()
Fix Coverity CHECKED_RETURN reports for dst_key_getbool().  In most
cases we do not really care about its return value, but it is prudent
to check it.

In one case, where a dst_key_getbool() error should be treated
identically as success, cast the return value to void and add a relevant
comment.

(cherry picked from commit e645d2ef1e)
2020-07-14 17:48:21 +02:00
Mark Andrews
d47c42a0ab Mark 'addr' as unused if HAVE_IF_NAMETOINDEX is not defined
Also 'zone' should be initialised to zero.

(cherry picked from commit e7662c4c63)
2020-07-14 10:53:06 +10:00
Mark Andrews
b955da48aa Handle namespace clash over 'SEC' on illumos.
(cherry picked from commit 18eef20241)
2020-07-14 09:06:46 +10:00
Mark Andrews
f771d75c9b Address potential double unlock in process_fd
(cherry picked from commit cc0089c66b)
2020-07-14 07:35:17 +10:00
Mark Andrews
94288631a9 Add changes for [GL #1989]
(cherry picked from commit 42b2290c3a)
2020-07-13 14:04:53 +10:00
Mark Andrews
67f85d648f Address overrun in remove_old_tsversions
If too many versions of log / dnstap files to be saved where requests
the memory after to_keep could be overwritten.  Force the number of
versions to be saved to a save level.  Additionally the memmove length
was incorrect.

(cherry picked from commit 6ca78bc57d)
2020-07-13 14:04:04 +10:00
Mark Andrews
e67b7a62d0 Assert tsigout is non-NULL
(cherry picked from commit 827746e89b)
2020-07-13 13:21:12 +10:00
Mark Andrews
12fac1ce70 check returns from inet_pton()
(cherry picked from commit 9499adeb5e)
2020-07-13 11:44:58 +10:00
Michał Kępień
0bc4d6cc7a Fix locking for LMDB 0.9.26
When "rndc reconfig" is run, named first configures a fresh set of views
and then tears down the old views.  Consider what happens for a single
view with LMDB enabled; "envA" is the pointer to the LMDB environment
used by the original/old version of the view, "envB" is the pointer to
the same LMDB environment used by the new version of that view:

 1. mdb_env_open(envA) is called when the view is first created.
 2. "rndc reconfig" is called.
 3. mdb_env_open(envB) is called for the new instance of the view.
 4. mdb_env_close(envA) is called for the old instance of the view.

This seems to have worked so far.  However, an upstream change [1] in
LMDB which will be part of its 0.9.26 release prevents the above
sequence of calls from working as intended because the locktable mutexes
will now get destroyed by the mdb_env_close() call in step 4 above,
causing any subsequent mdb_txn_begin() calls to fail (because all of the
above steps are happening within a single named process).

Preventing the above scenario from happening would require either
redesigning the way we use LMDB in BIND, which is not something we can
easily backport, or redesigning the way BIND carries out its
reconfiguration process, which would be an even more severe change.

To work around the problem, set MDB_NOLOCK when calling mdb_env_open()
to stop LMDB from controlling concurrent access to the database and do
the necessary locking in named instead.  Reuse the view->new_zone_lock
mutex for this purpose to prevent the need for modifying struct dns_view
(which would necessitate library API version bumps).  Drop use of
MDB_NOTLS as it is made redundant by MDB_NOLOCK: MDB_NOTLS only affects
where LMDB reader locktable slots are stored while MDB_NOLOCK prevents
the reader locktable from being used altogether.

[1] 2fd44e3251

(cherry picked from commit 53120279b5)
2020-07-10 11:30:31 +02:00
Mark Andrews
86681ca6f1 Adjust range limit of unknown meta types
(cherry picked from commit 092a159dcd)
2020-07-08 13:44:47 +10:00
Ondřej Surý
0279cc76a7 Update STALE and ANCIENT header attributes atomically
The ThreadSanitizer found a data race when updating the stale header.
Instead of trying to acquire the write lock and failing occasionally
which would skew the statistics, the dns_rdatasetheader_t.attributes
field has been promoted to use stdatomics.  Updating the attributes in
the mark_header_ancient() and mark_header_stale() now uses the cmpxchg
to update the attributes forfeiting the need to hold the write lock on
the tree.  Please note that mark_header_ancient() still needs to hold
the lock because .dirty is being updated in the same go.

(cherry picked from commit 81d4230e60)
2020-07-08 12:01:46 +10:00
Mark Andrews
dd32fb9284 Make the stdatomic shim and mutexatomic type complete
The stdatomic shims for non-C11 compilers (Windows, old gcc, ...) and
mutexatomic implemented only and minimal subset of the atomic types.
This commit adds 16-bit operations for Windows and all atomic types as
defined in standard.

(cherry picked from commit bccea5862d)
2020-07-08 10:29:59 +10:00
Mark Andrews
244ebdfb8c remove redundant rctx != NULL check
(cherry picked from commit 2fa2dbd5fb)
2020-07-06 10:30:25 +10:00
Witold Kręcicki
000c7d1340 rbtdb: cleanup_dead_nodes should ignore alive nodes on the deadlist
(cherry picked from commit c8f2d55acf)
2020-07-01 15:35:21 +02:00
Witold Kręcicki
03e583ffa8 Fix assertion failure during startup when the server is under load.
When we're coming back from recursion fetch_callback does not accept
DNS_R_NXDOMAIN as an rcode - query_gotanswer calls query_nxdomain in
which an assertion fails on qctx->is_zone. Yet, under some
circumstances, qname minimization will return an DNS_R_NXDOMAIN - when
root zone mirror is not yet loaded. The fix changes the DNS_R_NXDOMAIN
answer to DNS_R_SERVFAIL.
2020-07-01 12:55:12 +02:00