Commit graph

8384 commits

Author SHA1 Message Date
Ondřej Surý
c960236adb Don't schedule next zone events when shutting down
When the named is shutting down, the zone event callbacks could
re-schedule the stub and refresh events leading to assertion failure.

Handle the ISC_R_SHUTTINGDOWN event state gracefully by bailing out.
2022-01-13 17:58:33 +01:00
Ondřej Surý
efca93942c Refactor zone stub, refresh and notify event callbacks
This commit cleanups the way how we handle the revent->result in the
stub_callback(), refresh_callback() and notify_done() zone callbacks.
2022-01-13 17:58:33 +01:00
Ondřej Surý
8a0c4355d2 Remove the workaround for broken handling of NOTIFY with SOA
In 2000, old BIND instances (BIND 8?) would return FORMERR if the SOA is
included in the NOTIFY.

Remove the workaround that detected the state and resent the NOTIFY
without SOA record.
2022-01-13 17:09:43 +01:00
Ondřej Surý
58bd26b6cf Update the copyright information in all files in the repository
This commit converts the license handling to adhere to the REUSE
specification.  It specifically:

1. Adds used licnses to LICENSES/ directory

2. Add "isc" template for adding the copyright boilerplate

3. Changes all source files to include copyright and SPDX license
   header, this includes all the C sources, documentation, zone files,
   configuration files.  There are notes in the doc/dev/copyrights file
   on how to add correct headers to the new files.

4. Handle the rest that can't be modified via .reuse/dep5 file.  The
   binary (or otherwise unmodifiable) files could have license places
   next to them in <foo>.license file, but this would lead to cluttered
   repository and most of the files handled in the .reuse/dep5 file are
   system test files.
2022-01-11 09:05:02 +01:00
Matthijs Mekking
beeefe35c4 Fix bug introduced by #763 related to offline keys
In some cases we want to keep expired signatures. For example, if the
KSK is offline, we don't want to fall back to signing with the ZSK.
We could remove the signatures, but in any case we end up with a broken
zone.

The change made for GL #763 prevented the behavior to sign the DNSKEY
RRset with the ZSK if the KSK was offline (and signatures were expired).

The change causes the definition of "having both keys": if one key is
offline, we still consider having both keys, so we don't fallback
signing with the ZSK if KSK is offline.

That change also works the other way, if the ZSK is offline, we don't
fallback signing with the KSK.

This commit fixes that, so we only fallback signing zone RRsets with
the KSK, not signing key RRsets with the ZSK.
2022-01-06 09:32:32 +01:00
Matthijs Mekking
2d2858841a Only warn if we could not delete signature
BIND can log this warning:

    zone example.ch/IN (signed): Key example.ch/ECDSAP256SHA256/56340
      missing or inactive and has no replacement: retaining signatures.

This log can happen when BIND tries to remove signatures because the
are about to expire or to be resigned. These RRsets may be signed with
the KSK if the ZSK files has been removed from disk. When we have
created a new ZSK we can replace the signatures creeated by the KSK
with signatures from the new ZSK.

It complains about the KSK being missing or inactive, but actually it
takes the key id from the RRSIG.

The warning is logged if BIND detects the private ZSK file is missing.

The warning is logged even if we were able to delete the signature.

With the change from this commit it only logs this warning if it is not
okay to delete the signature.
2022-01-06 09:32:32 +01:00
Michał Kępień
ef625f5f06 Do not detach raw zone until dumping is complete
When the signed version of an inline-signed zone is dumped to disk, the
serial number of the unsigned version of the zone is stored in the
raw-format header so that the contents of the signed zone can be
resynchronized after named restart if the unsigned zone file is modified
while named is not running.

In order for the serial number of the unsigned zone to be determined
during the dump, zone->raw must be set to a non-NULL value.  This should
always be the case as long as the signed version of the zone is used for
anything by named.

However, a scenario exists in which the signed version of the zone has
zone->raw set to NULL while it is being dumped:

 1. Zone dump is requested; zone_dump() is invoked.

 2. Another zone dump is already in progress, so the dump gets deferred
    until I/O is available (see zonemgr_getio()).

 3. The last external reference to the zone is released.
    zone_shutdown() gets queued to the zone's task.

 4. I/O becomes available for zone dumping.  zone_gotwritehandle() gets
    queued to the zone's task.

 5. The zone's task runs zone_shutdown().  zone->raw gets set to NULL.

 6. The zone's task runs zone_gotwritehandle().  zone->raw is determined
    to be NULL, causing the serial number of the unsigned version of the
    zone to be omitted from the raw-format dump of the signed zone file.

Note that the naïve solution - deferring the dns_zone_detach() call for
zone->raw until zone_free() gets called for the secure version of the
zone - does not work because it leads to a chicken-and-egg problem when
the inline-signed zone is about to get freed: the raw zone holds a weak
reference to the secure zone and that reference does not get released
until the reference count for the raw zone reaches zero, which in turn
would not happen until all weak references to the secure zone were
released.

Defer detaching from zone->raw in zone_shutdown() if the zone is in the
process of being dumped to disk.  Ensure zone->raw gets detached from
after the dump is finished if detaching gets deferred.  Prevent zone
dumping from being requeued upon failure if the zone is in the process
of being cleaned up as it opens up possibilities for the zone->raw
reference to leak, triggering a shutdown hang.
2022-01-05 17:53:49 +01:00
Ondřej Surý
1064b2fc47 Revert "Ensure the correct ordering zone_shutdown() vs zone_gotwritehandle()"
This reverts commit cc1d4e1aa6.
2022-01-05 17:53:49 +01:00
Ondřej Surý
ab5b2ef43c Add isc_refcount_destroy() for dns_zt reference counters
The zt_destroy() function was missing isc_refcount_destroy() on the two
reference counters.  The isc_refcount_destroy() adds proper memory
ordering on destroy and also ensures that the reference counters have
been zeroed before destroying the object.
2022-01-05 16:56:16 +01:00
Ondřej Surý
f326d45135 Lock view while accessing its zone table
Commit 308bc46a59 introduced a change to
the view_flushanddetach() function which makes the latter access
view->zonetable without holding view->lock.  As confirmed by TSAN, this
enables races between threads for view->zonetable accesses.

Swap the view->zonetable pointer under view lock and then detach the
local swapped dns_zt_t later when the view lock is already unlocked.

This commit also changes the dns_zt interfaces, so the setting the
zonetable "flush" flag is separate operation to dns_zt_detach,
e.g. instead of doing:

    if (view->flush) {
        dns_zt_flushanddetach(&zt);
    } else {
        dns_zt_detach(&zt);
    }

the code is now:

    if (view->flush) {
        dns_zt_flush(zt);
    }
    dns_zt_detach(&zt);

making the code more consistent with how we handle flushing and
detaching dns_zone_t pointers from the view.
2022-01-05 16:56:16 +01:00
Michał Kępień
cc1d4e1aa6 Ensure the correct ordering zone_shutdown() vs zone_gotwritehandle()
When the signed version of an inline-signed zone is dumped to disk, the
serial number of the unsigned version of the zone is written in the
raw-format header so that the contents of the signed zone can be
resynchronized after named restart if the unsigned zone file is
modified while named is not running (see RT #26676).

In order for the serial number of the unsigned zone to be determined
during the dump, zone->raw must be set to a non-NULL value.  This
should always be the case as long as the signed version of the zone is
used for anything by named.

However, under certain circumstances the zone->raw could be set to NULL
while the zone is being dumped.

Defer detaching from zone->raw in zone_shutdown() if the zone is in the
process of being dumped to disk.
2022-01-05 10:27:55 +01:00
Artem Boldariev
64f7c55662 Use the TLS context cache for client-side contexts (XoT)
This commit enables client-side TLS contexts re-use for zone transfers
over TLS. That, in turn, makes it possible to use the internal session
cache associated with the contexts, allowing the TLS connections to be
established faster and requiring fewer resources by not going through
the full TLS handshake procedure.

Previously that would recreate the context on every connection, making
TLS session resumption impossible.

Also, this change lays down a foundation for Strict TLS (when the
client validates a server certificate), as the TLS context cache can
be extended to store additional data required for validation (like
intermediates CA chain).
2021-12-29 10:25:15 +02:00
Mark Andrews
dc8595936c remove broken-nsec and reject-000-label options 2021-12-23 15:13:46 +11:00
Mark Andrews
a23507c4fa Pass the digest buffer length to EVP_DigestSignFinal
OpenSSL 3.0.1 does not accept 0 as a digest buffer length when
calling EVP_DigestSignFinal as it now checks that the digest buffer
length is large enough for the digest.  Pass the digest buffer
length instead.
2021-12-17 20:28:01 +11:00
Ondřej Surý
72cc25465f Reduce freemax values for dns_message mempools
It was discovered that NAME_FREEMAX and RDATASET_FREEMAX was based on
the NAME_FILLCOUNT and RDATASET_FILLCOUNT respectively multiplied by 8
and then when used in isc_mempool_setfreemax, the value would be again
multiplied by 32.

Keep the 8 multiplier in the #define and remove the 32 multiplier as it
was kept in error.  The default fillcount can fit 99.99% of the requests
under normal circumstances, so we don't need to keep that many free
items on the mempool.
2021-12-15 21:25:00 +01:00
Ondřej Surý
ce75d4a96b Set the clientmgr isc_mem_t context name
The memory context created in the clientmgr context was missing a name,
so it was nameless in the memory context statistics.

Set the clientmgr memory context name to "clientmgr".
2021-12-14 19:15:58 +00:00
Michal Nowak
9c013f37d0
Drop cppcheck workarounds
As cppcheck was removed from the CI, associated workarounds and
suppressions are not required anymore.
2021-12-14 15:03:56 +01:00
Evan Hunt
157d7bd0e9 incidental cleanups
the 'dipsatchmgr->state' was never set, so the MGR_IS_SHUTTINGDOWN
macro was always false. both of these have been removed.

renamed the 'dispatch->state' field to 'tcpstate' to make its purpose
less ambiguous.

changed an FCTXTRACE log message from "response did not match question"
to the more correctly descriptive "invalid question section".
2021-12-08 10:22:03 -08:00
Evan Hunt
5f82fc11a9 prevent a shutdown hang on non-matching TCP responses
When a non-matching DNS response is received by the resolver,
it calls dns_dispatch_getnext() to resume reading. This is necessary
for UDP but not for TCP, because TCP connections automatically
resume reading after any valid DNS response.

This commit adds a 'tcpreading' flag to TCP dispatches, so that
`dispatch_getnext()` can be called multiple times without subsequent
calls having any effect.
2021-12-08 10:22:03 -08:00
Evan Hunt
4d4cea243a restore the fetch lifetime timer
the lifetime expiry timer for the fetch context was removed
when we switched to using in-band netmgr timeouts. however,
it turns out some dependency loops can occur between a fetch
and the ADB the validator; these deadlocks were formerly broken
when the timer fired, and now there's no timer. we can fix these
errors individually, but in the meantime we don't want the server
to get hung at shutdown because of dangling fetches.

this commit puts back a single timer, which fires two seconds
after the fetch should have completed, and shuts it down. it also
logs a message at level INFO so we know about the problems when
they occur.
2021-12-03 09:49:24 +01:00
Mark Andrews
0aaaa8768f
Reject NSEC records with next field with \000 label
A number of DNS implementation produce NSEC records with bad type
maps that don't contain types that exist at the name leading to
NODATA responses being synthesize instead of the records in the
zone.  NSEC records with these bad type maps often have the NSEC
NSEC field set to '\000.QNAME'.  We look for the first label of
this pattern.

e.g.
	example.com NSEC \000.example.com SOA NS NSEC RRSIG
	example.com RRRSIG NSEC ...
	example.com SOA ...
	example.com RRRSIG SOA ...
	example.com NS ...
	example.com RRRSIG NS ...
	example.com A ...
	example.com RRRSIG A ...

	A is missing from the type map.

This introduces a temporary option 'reject-000-label' to control
this behaviour.
2021-12-02 14:27:18 +01:00
Mark Andrews
733f58a7a5
Allow servers that emit broken NSEC records to be identified
'server <prefix> { broken-nsec yes; };' can now be used to stop
NSEC records from negative responses from servers in the given
prefix being cached and hence available to synth-from-dnssec.
2021-12-02 14:27:14 +01:00
Mark Andrews
454c29046f
Check that SOA and DNSKEY are consistent in NSEC typemaps
If there is a SOA record present then there should also be a
DNSKEY record present as the DNSKEY is supposed to live at the
zone apex like the SOA.
2021-12-02 14:24:37 +01:00
Mark Andrews
5252985a21
Look for covering NSEC under two more conditions
1) when after processing a node there where no headers that
   contained active records.

   When

       if (check_stale_header(node, header, &locktype, lock, &search,
			      &header_prev);

   succeeds or

       if (EXISTS(header) && !ANCIENT(header))

   fails for all entries in the list leading to 'empty_node' remaining
   true.

   If there is are no active records we know nothing about the
   current state of the name so we treat is as ISC_R_NOTFOUND.

2) when there was a covering NOQNAME proof found or all the
   active headers where negative.

   When

	if (header->noqname != NULL &&
	    header->trust == dns_trust_secure)

   succeeds or

	if (!NEGATIVE(header))

   never succeeds.  Under these conditions there could (should be for
   found_noqname) be a covering NSEC earlier in the tree.
2021-12-02 14:24:37 +01:00
Mark Andrews
4bdd5a9953
Ignore NSEC records without RRSIG and NSEC present
dns_nsec_noexistnodata now checks that RRSIG and NSEC are
present in the type map.  Both types should be present in
a correctly constructed NSEC record.  This check is in
addition to similar checks in resolver.c and validator.c.
2021-12-02 14:18:42 +01:00
Mark Andrews
8ff2c133b5
Add dns_nsec_requiredtypespresent
checks an NSEC rdataset to ensure that both NSEC and RRSIG are
present in the type map.  These types are required for the NSEC
to be valid
2021-12-02 14:18:42 +01:00
Mark Andrews
43316a40a0
Record how often DNS_R_COVERINGNSEC is returned from the cache
reported as "covering nsec returned" when dumping cache stats
and as "CoveringNSEC" in json and xml cache statistics.
2021-12-02 14:18:41 +01:00
Mark Andrews
62dd9ec9c1
Report Cache NSEC auxilary database size 2021-12-02 14:18:41 +01:00
Mark Andrews
85bfcaeb2e
Extend dns_db_nodecount to access auxilary rbt node counts
dns_db_nodecount can now be used to get counts from the auxilary
rbt databases.  The existing node count is returned by
tree=dns_dbtree_main.  The nsec and nsec3 node counts by dns_dbtree_nsec
and dns_dbtree_nsec3 respectively.
2021-12-02 14:18:41 +01:00
Mark Andrews
c8a7f92b9e
Allow "black lies" to be cached
"black lies" differ from "white lies" in that the owner name of the
NSEC record matches the QNAME and the intent is to return NODATA
instead of NXDOMAIN for all types.  Caching this NSEC does not lead
to unexpected behaviour on synthesis when the QNAME matches the
NSEC owner which it does for the the general "white lie" response.

"black lie" QNAME NSEC \000.QNAME NSEC RRSIG

"white lie" QNAME- NSEC QNAME+ NSEC RRSIG

where QNAME- is a name that is close to QNAME but sorts before QNAME
and QNAME+ is a that is close to QNAME but sorts after QNAME.

Black lies are safe to cache as they don't bring into existence
names that are not intended to exist.  "Black lies" intentional change
NXDOMAIN to NODATA. "White lies" bring QNAME- into existence and named
would synthesis NODATA for QNAME+ if it is queried for that name
instead of discovering the, presumable, NXDOMAIN response.

Note rejection NSEC RRsets with NEXT names starting with the label
'\000' renders this change ineffective (see reject-000-label).
2021-12-02 14:18:41 +01:00
Mark Andrews
6fae151c9d
Do not cache minimal NSEC records (NSEC + RRSIG only)
these are not useful for dnssec synthesis as they can result in
false NODATA responses and just consume cache memory
2021-12-02 14:18:41 +01:00
Mark Andrews
27acf56ba3
Remove unnecessary dns_rbt_fullnamefromnode call
the results from dns_rbt_fullnamefromnode are not used.
2021-12-02 14:18:40 +01:00
Mark Andrews
89542b8a15
Count DNS_R_COVERINGNSEC as a cache {query}hit
Note when synthesising answer involving wildcards we look in the
cache multiple times, once for the QNAME and once for the wildcard
name which is constucted by looking at the names from the covering
NSEC return by the QNAME miss.
2021-12-02 14:18:40 +01:00
Mark Andrews
3a5652ccb1
Rework rbtdb.c:find_coveringnsec() to use the auxilary nsec rbt
this improves the performance of looking for NSEC and RRSIG(NSEC)
records in the cache by skipping lots of nodes in the main trees
in the cache without these records present.  This is a simplified
version of previous_closest_nsec() which uses the same underlying
mechanism to look for NSEC and RRSIG(NSEC) records in authorative
zones.

The auxilary NSEC tree was already being maintained as a side effect
of looking for the covering NSEC in large zones where there can be
lots of glue records that needed to be skipped.  Nodes are added
to the tree whenever a NSEC record is added to the primary tree.
They are removed when the corresponding node is removed from the
primary tree.

Having nodes in the NSEC tree w/o NSEC records in the primary tree
should not impact on synth-from-dnssec efficiency as that node would
have held the NSEC we would have been needed to synthesise the
response.  Removing the node when the NSEC RRset expires would only
cause rbtdb to return a NSEC which would be rejected at a higher
level.
2021-12-02 14:18:40 +01:00
Evan Hunt
fa8f409af2 On non-matching answer, check for missed timeout
A TCP connection may be held open past its proper timeout if it's
receiving a stream of DNS responses that don't match any queries.
In this case, we now check whether the oldest query should have timed
out.
2021-12-01 11:45:55 -08:00
Ondřej Surý
ba1cadf14a Tear down the TCP connection on too many unexpected DNS messages
When the outgoing TCP dispatch times-out active response, we might still
receive the answer during the lifetime of the connection.  Previously,
we would just ignore any non-matching DNS answers, which would allow the
server to feed us with otherwise valid DNS answer and keep the
connection open.

Add a counter for timed-out DNS queries over TCP and tear down the whole
TCP connection if we receive unexpected number of DNS answers.
2021-12-01 11:45:55 -08:00
Ondřej Surý
c84ed5056e Refactor tcp_recv()
The tcp_recv() function used lot of gotos that made the function hard to
read.  Refactor the function by splitting it into smaller logical chunks.
2021-12-01 11:45:55 -08:00
Ondřej Surý
10f4f1a250 Shutdown all TCP connection on invalid DNS message
Previously, when invalid DNS message is received over TCP we throw the
garbage DNS message away and continued looking for valid DNS message
that would match our outgoing queries.  This logic makes sense for UDP,
because anyone can send DNS message over UDP.

Change the logic that the TCP connection is closed when we receive
garbage, because the other side is acting malicious.
2021-12-01 11:45:55 -08:00
Ondřej Surý
9230473324 Shutdown all active TCP connections on error
When outgoing TCP connection was prematurely terminated (f.e. with
connection reset), the dispatch code would not cleanup the resources
used by such connection leading to dangling dns_dispentry_t entries.
2021-12-01 11:45:55 -08:00
Artem Boldariev
7843fb4ece XoT: add support for client-side TLS parameters
This commit adds support for client-side TLS parameters to XoT.

Prior to this commit all client-side TLS contexts were using default
parameters only, ignoring the options from the BIND's configuration
file.

Currently, the following 'tls' parameters are supported:

- protocols;
- ciphers;
- prefer-server-ciphers.
2021-12-01 12:00:28 +02:00
Artem Boldariev
0ee6f66cbd Integrate extended ACLs syntax featuring 'port' and 'transport' opts
This commit completes the integration of the new, extended ACL syntax
featuring 'port' and 'transport' options.

The runtime presentation and ACL loading code are extended to allow
the syntax to be used beyond the 'allow-transfer' option (e.g. in
'acl' definitions and other 'allow-*' options) and can be used to
ultimately extend the ACL support with transport-only
ACLs (e.g. 'transport-acl tls-acl port 853 transport tls'). But, due
to fundamental nature of such a change, it has not been completed as a
part of 9.17.X release series due to it being close to 9.18 stable
release status. That means that we do not have enough time to fully
test it.

The complete integration is planned as a part of 9.19.X release
series.

The code was manually verified to work as expected by temporarily
enabling the extended syntax for 'acl' statements and 'allow-query'
options, including ACL merging, negated ACLs.
2021-11-30 12:20:22 +02:00
Mark Andrews
08f1cba096 Do not convert ISC_R_NOSPACE to DNS_R_SERVFAIL too early
The parsing loop needs to process ISC_R_NOSPACE to properly
size the buffer.  If result is still ISC_R_NOSPACE at the end
of the parsing loop set result to DNS_R_SERVFAIL.
2021-11-25 19:48:20 +00:00
Michal Nowak
d09447287f
Fix "array subscript is of type 'char'" on NetBSD 9
In file included from rdata.c:602:
    In file included from ./code.h:88:
    ./rdata/in_1/svcb_64.c:259:9: warning: array subscript is of type 'char' [-Wchar-subscripts]
                            if (!isdigit(*region->base)) {
                                 ^~~~~~~~~~~~~~~~~~~~~~
    /usr/include/sys/ctype_inline.h:51:44: note: expanded from macro 'isdigit'
    #define isdigit(c)      ((int)((_ctype_tab_ + 1)[(c)] & _CTYPE_D))
                                                    ^~~~
2021-11-25 18:15:18 +01:00
Michał Kępień
8f8a69aa0a Fix handling of mismatched responses past timeout
When a UDP dispatch receives a mismatched response, it checks whether
there is still enough time to wait for the correct one to arrive before
the timeout fires.  If there is not, the result code is set to
ISC_R_TIMEDOUT, but it is not subsequently used anywhere as 'response'
is set to NULL a few lines earlier.  This results in the higher-level
read callback (resquery_response() in case of resolver code) not being
called.  However, shortly afterwards, a few levels up the call chain,
isc__nm_udp_read_cb() calls isc__nmsocket_timer_stop() on the dispatch
socket, effectively disabling read timeout handling for that socket.
Combined with the fact that reading is not restarted in such a case
(e.g. by calling dispatch_getnext() from udp_recv()), this leads to the
higher-level query structure remaining referenced indefinitely because
the dispatch socket it uses will neither be read from nor closed due to
a timeout.  This in turn causes fetch contexts to linger around
indefinitely, which in turn i.a. prevents certain cache nodes (those
containing rdatasets used by fetch contexts, like fctx->nameservers)
from being cleaned.

Fix by making sure the higher-level callback does get invoked with the
ISC_R_TIMEDOUT result code when udp_recv() determines there is no more
time left to receive the correct UDP response before the timeout fires.
This allows the higher-level callback to clean things up, preventing the
reference leak described above.
2021-11-23 15:35:39 +01:00
Aram Sargsyan
43ac2cd229 Fix catalog zone reconfiguration crash
The following scenario triggers a "named" crash:

1. Configure a catalog zone.
2. Start "named".
3. Comment out the "catalog-zone" clause.
4. Run `rndc reconfig`.
5. Uncomment the "catalog-zone" clause.
6. Run `rndc reconfig` again.

Implement the required cleanup of the in-memory catalog zone during
the first `rndc reconfig`, so that the second `rndc reconfig` could
find it in an expected state.
2021-11-23 11:39:37 +00:00
Mark Andrews
34f3240622 Reject too long ECDSA public keys
opensslecdsa_fromdns() already rejects too short ECDSA public keys.
Make it also reject too long ones.  Remove an assignment made redundant
by this change.
2021-11-23 08:44:47 +11:00
Michał Kępień
a9ab2bf60b Pass key length to raw_key_to_ossl() by value
As raw_key_to_ossl() no longer stores anything at the pointer passed to
it in the 'key_len' parameter, change the type of the latter to size_t.
2021-11-23 08:44:47 +11:00
Michał Kępień
a482a6b204 Fix parsing ECDSA keys
raw_key_to_ossl() assumes fixed ECDSA private key sizes (32 bytes for
ECDSAP256SHA256, 48 bytes for ECDSAP384SHA384).  Meanwhile, in rare
cases, ECDSAP256SHA256 private keys are representable in 31 bytes or
less (similarly for ECDSAP384SHA384) and that is how they are then
stored in the "PrivateKey" field of the key file.  Nevertheless,
raw_key_to_ossl() always calls BN_bin2bn() with a fixed length argument,
which in the cases mentioned above leads to erroneously interpreting
uninitialized memory as a part of the private key.  This results in the
latter being malformed and broken signatures being generated.  Address
by using the key length provided by the caller rather than a fixed one.
Apply the same change to public key parsing code for consistency, adding
an INSIST() to prevent buffer overruns.
2021-11-23 08:44:47 +11:00
Evan Hunt
326a4fc13b fix a use-after-free in resolver
when processing a mismatched response, we call dns_dispatch_getnext().
If that fails, for example because of a timeout, fctx_done() is called,
which cancels all queries. This triggers a crash afterward when
fctx_cancelquery() is called, and is unnecessary since fctx_done()
would have been called later anyway.
2021-11-22 11:35:34 +01:00
Ondřej Surý
7e002d89b4 Fix the data race when shutting down dns_adb
When dns_adb is shutting down, first the adb->shutting_down flag is set
and then task is created that runs shutdown_stage2() that sets the
shutdown flag on names and entries.  However, when dns_adb_createfind()
is called, only the individual shutdown flags are being checked, and the
global adb->shutting_down flag was not checked.  Because of that it was
possible for a different thread to slip in and create new find between
the dns_adb_shutdown() and dns_adb_detach(), but before the
shutdown_stage2() task is complete.  This was detected by
ThreadSanitizer as data race because the zonetable might have been
already detached by dns_view shutdown process and simultaneously
accessed by dns_adb_createfind().

This commit converts the adb->shutting_down to atomic_bool to prevent
the global adb lock when creating the find.
2021-11-22 11:09:21 +01:00