Commit graph

14927 commits

Author SHA1 Message Date
Timo Teräs
628dd278d3 Rework opensslecdsa_link to handle legacy key objects w/ openssl3
Due to bug in openssl3, the pkcs11-engine is made the default
provider if enabled. This causes key generation and load to
return legacy objects.

Openssl3 has limited glue and does not support the full set
of new style parameter to be inqueried from legacy key objects

Rewrite required functions to use first the new API (if available),
but fallback to the old API (if available). For the methods that
have proper OpenSSL compatiblity glue, ship only one version.
2023-08-25 14:59:16 +03:00
Aram Sargsyan
a33dc921dc Fix a condition in isc_dnsstream_assembler_incoming()
Before calling isc_buffer_putmem(), there is a condition to check
that 'buf_size' is greater than 0. At this point 'buf_size' is
guaranteed to be greater than zero, so either the condition is
redundant, or 'unprocessed_size' should be checked instead, which
seems more logical, because calling isc_buffer_putmem() with
'unprocessed_size' being zero is not useful, although harmless.
2023-08-24 11:59:57 +00:00
Aram Sargsyan
9a271371d3 Handle cases when buf_size is zero
The isc_dnsstream_assembler_incoming() inline function expects that
when 'buf_size' is zero, then 'buf' must be NULL. The expectation is
not correct, because those values come from the libuv read callback,
and its documentation notes[1] that 'nread' ('buf_size' here) might
be 0, which does not indicate an error or EOF, but is equivalent to
EAGAIN or EWOULDBLOCK under read(2).

Change the isc_dnsstream_assembler_incoming() inline function to
remove the invalid expectation.

[1] https://docs.libuv.org/en/v1.x/stream.html#c.uv_read_cb
2023-08-24 11:59:57 +00:00
Ondřej Surý
2e3eae6b91
Refactor cleanup code in the qp-trie for the forwarders table
Instead of duplicating the destroy_forwarders() code in the cleanup
sections, just call dns_forwarders_detach() every time - in case of
failure, the forwarders aren't going to be attached, and forwarders
object will be destroyed right away.
2023-08-23 15:49:17 +02:00
Tony Finch
52fcc9fc0f
Remove some unnecessary token pasting macrology
There used to be an extra layer of indirection in the memory functions
for certain dynamic linking scenarios. This involved variant spellings
like isc__mem and isc___mem. The isc___mem variants were removed in
commit 7de846977b so the token pasting is no longer needed and
only serves to obfuscate.
2023-08-23 14:49:15 +02:00
Evan Hunt
0ae8b2e056 prevent query_coveringnsec() from running twice
when synthesizing a new CNAME, we now check whether the target
matches the query already being processed. if so, we do not
restart the query; this prevents a waste of resources.
2023-08-21 12:22:47 -07:00
Ondřej Surý
9b858769dc
Add zone name to the LIBDNS_XFRIN probes
We already print the formatted zone name via the xfrin_log() function,
generate the text once and store it in xfr->info static buffer.  Then we
can reuse the string to pass it to the LIBDNS_XFRIN probes.
2023-08-21 18:39:53 +02:00
Ondřej Surý
d332f07f38
Add a probe when the response rate limiting drops or slips query
Add a trace point that would report when a query gets dropped or slipped
by rate limits. It reports the client IP, the zone, and the RRL result
code.

Co-authored-by: Paul Frieden <pfrieden@yahooinc.com>
2023-08-21 18:39:53 +02:00
Ondřej Surý
96ccba5d51
Add tracing probes to the dns_xfrin unit
Add tracing probes to incoming transfers, so we can accurately measure
the individual events when sending, receiving and parsing the incoming
transfers.
2023-08-21 18:39:53 +02:00
Ondřej Surý
2484a3702a
Add tracing probes to the isc_job unit
Add tracing probes to isc_job unit:

 * libisc:job_cb_before - before the job callback is called
 * libisc:job_cb_after - after the job callback is called
2023-08-21 18:39:53 +02:00
Ondřej Surý
dcd60215ac
Add tracing probes to the custom isc_rwlock implementation
Add tracing probes to ISC own isc_rwlock implementation to allow
fine-grained tracing.  The pthread rwlock already has probes inside
glibc, and it's difficult to add probes to headers included from the
other libraries.
2023-08-21 18:39:53 +02:00
Ondřej Surý
784d055809
Add support for User Statically Defined Tracing (USDT) probes
This adds support for User Statically Defined Tracing (USDT).  On
Linux, this uses the header from SystemTap and dtrace utility, but the
support is universal as long as dtrace is available.

Also add the required infrastructure to add probes to libisc, libdns and
libns libraries, where most of the probes will be.
2023-08-21 18:39:53 +02:00
Ondřej Surý
0c9cf8fabb
Limit the memory pool for the uvreqs
Set the number of maximum free items for the uvreq memory pool to 64.
2023-08-21 16:34:30 +02:00
Ondřej Surý
f36e118b9a
Limit the number of inactive handles kept for reuse
Instead of growing and never shrinking the list of the inactive
handles (to be reused mostly on the UDP connections), limit the number
of maximum number of inactive handles kept to 64.  Instead of caching
the inactive handles for all listening sockets, enable the caching on on
UDP listening sockets.  For TCP, the handles were cached for each
accepted socket thus reusing the handles only for long-standing TCP
connections, but not reusing the handles across different TCP streams.
2023-08-21 16:34:30 +02:00
Tony Finch
26e10e8fb5
Parse statschannel Content-Length: more carefully
A negative or excessively large Content-Length could cause a crash
by making `INSIST(httpd->consume != 0)` fail.
2023-08-21 14:14:18 +02:00
Ondřej Surý
d76ab69772 Attach to the dns_dispatchmgr in the dns_view object
The dns_dispatchmgr object was only set in the dns_view object making it
prone to use-after-free in the dns_xfrin unit when shutting down named.

Remove dns_view_setdispatchmgr() and optionally pass the dispatchmgr
directly to dns_view_create() when it is attached and not just assigned,
so the dns_dispatchmgr doesn't cease to exist too early.

The dns_view_getdnsdispatchmgr() is now protected by the RCU lock, the
dispatchmgr reference is incremented, so the caller needs to detach from
it, and the function can return NULL in case the dns_view has been
already shut down.
2023-08-15 10:25:37 -07:00
Evan Hunt
b466439437
use a qp-trie for the keytable
Instead of an RBT for the trust anchor tables, use a QP-trie.
2023-08-15 14:25:24 +02:00
Evan Hunt
dea79e7053
use a qp-trie for the forwarders table
Instead of an RBT for the forwarders table, use a QP trie.

We now use reference counting for dns_forwarders_t. When a forwarders
object is retrieved by dns_fwdtable_find(), it must now be explicitly
detached by the caller afterward.

QP tries require stored objects to include their names, so the
the forwarders object now has that. This obviates the need to
pass back a separate 'foundname' value from dns_fwdtable_find().
2023-08-15 14:25:24 +02:00
Evan Hunt
5768dd96ea
clean up some unused functions
dns_fwdtable_delete() was only used by dns_client_clearservers(),
which in turn was never used. both functions have now been deleted.
2023-08-15 14:24:46 +02:00
Evan Hunt
aff01bda54
use a qp-trie for the NTA table
replace the red-black tree used by the negative trust anchor table
with a QP trie.

because of this change, dns_ntatable_init() can no longer fail, and
neither can dns_view_initntatable(). these functions have both been
changed to type void.
2023-08-15 14:24:46 +02:00
Evan Hunt
06216f4f90
rename dns_qp_findname_parent() to _findname_ancestor()
this function finds the closest matching ancestor, but the function
name could be read to imply that it returns the direct parent node;
this commit suggests a slightly less misleading name.
2023-08-15 14:24:46 +02:00
Tony Finch
b38c71961d
Improve qp-trie leaf return values
Make the `pval_r` and `ival_r` out arguments optional.

Add `pval_r` and `ival_r` out arguments to `dns_qp_deletekey()`
and `dns_qp_deletename()`, to return the deleted leaf.
2023-08-15 14:24:39 +02:00
Tony Finch
c622b349e4
Apply the SET_IF_NOT_NULL() semantic patch
spatch --sp-file cocci/set_if_not_null.spatch --use-gitgrep --dir "." --include-headers --in-place
2023-08-15 12:21:41 +02:00
Tony Finch
0d6dcd217d
A SET_IF_NOT_NULL() macro for optional return values
The SET_IF_NOT_NULL() macro avoids a fair amount of tedious boilerplate,
checking pointer parameters to see if they're non-NULL and updating
them if they are.  The macro was already in the dns_zone unit, and this
commit moves it to the <isc/util.h> header.

I have included a Coccinelle semantic patch to use SET_IF_NOT_NULL()
where appropriate. The patch needs an #include in `openssl_shim.c`
in order to work.
2023-08-15 12:04:29 +02:00
Tony Finch
b22c87ca61
Fix a stack buffer overflow in the statistics channel
A long timestamp in an If-Modified-Since header could overflow a
fixed-size buffer.
2023-08-14 11:30:24 +02:00
Matthijs Mekking
fa108db279 Revert a337dbef
Revert commit that always uses OpenSSL 3.0 API when available,
the new APIs should work always, but OpenSSL has non-obvious
omissions in the automatic mappings it provides.
2023-08-09 23:48:17 +00:00
Mark Andrews
00a09e0d35 Only set key->engine if engine != NULL 2023-08-09 23:48:17 +00:00
Mark Andrews
d527ae11c9 Fix clang formatting 2023-08-09 23:48:17 +00:00
Timo Teräs
de486d0ec5 Fix keyfromlabel to not use engine parameter for provider keys
- Rework key checks to not require 'engine' tag, private key
  is valid with 'label' tag alone

- Fix _fromlabel() functions to work with engine == NULL

- Update dst__openssl_fromlabel_engine() to do provider lookup
  only when engine is not set
2023-08-08 17:16:14 +03:00
Timo Teräs
a337dbef22 Always use OpenSSL 3.0 API when available
The new APIs work always as OpenSSL provides glue to access also
old style engines using the new APIs.
2023-08-08 14:08:00 +00:00
Timo Teräs
8de089e514 Fix support for engine/provider ECDSA keys
Exporting private key of on-token keys is not possible. Fix code
to not fail in this case.
2023-08-08 14:08:00 +00:00
Timo Teräs
de45aab184 Fix OpenSSL 3.0 API EC curve names
The OpenSSL man page examples used the NIST curve names which
are supported. But when querying the name, the native OpenSSL
name is returned. Use these names to pass curve type checks for
engine/provider objects.
2023-08-08 14:08:00 +00:00
Evan Hunt
b3c2b64662 use read lock in rdataset_getownercase()
we were incorrectly write-locking the node when retrieving
the owner case of an rdataset.
2023-08-03 13:26:27 -07:00
Matthijs Mekking
32686beabc Change default TTLsig to one week
Commit dc6dafdad1 allows larger TTL values
in zones that go insecure, and ignores the maximum zone TTL.

This means that if you use TTL values larger than 1 day in your zone,
your zone runs the risk of going bogus before it moves safely to
insecure.

Most resolvers by default cap the maximum TTL that they cache RRsets,
at one day (Unbound, Knot, PowerDNS) so that is fine. However, BIND 9's
default is one week.

Change the default TTLsig to one week, so that also for BIND 9
resolvers in the default cases responses for zones that are going
insecure will not be evaluated as bogus.

This change does mean that when unsigning your zone, it will take six
days longer to safely go insecure, regardless of what TTL values you
use in the zone.
2023-08-02 11:16:50 +02:00
Evan Hunt
eeeccec67c deprecate "dialup" and "heartbeat-interval"
these options concentrate zone maintenance actions into
bursts for the benefit of servers with intermittent connections.
that's no longer something we really need to optimize.
2023-08-01 18:10:44 -07:00
Matthijs Mekking
dc6dafdad1 Ignore max-zone-ttl on dnssec-policy insecure
Allow larger TTL values in zones that go insecure. This is necessary
because otherwise the zone will not be loaded due to the max-zone-ttl
of P1D that is part of the current insecure policy.

In the keymgr.c code, default back to P1D if the max-zone-ttl is set
to zero.
2023-08-01 08:56:52 +02:00
Matthijs Mekking
495597a91b Update inline-signing checkconf code
When using automated DNSSEC management, it is required that the zone
is dynamic, or that inline-signing is enabled (or both). Update the
checkconf code to also allow inline-signing to be enabled within
dnssec-policy.
2023-08-01 06:55:48 +00:00
Matthijs Mekking
bbfdcc36c8 Add inline-signing to dnssec-policy
Add an option to enable/disable inline-signing inside the
dnssec-policy clause. The existing inline-signing option that is
set in the zone clause takes priority, but if it is omitted, then the
value that is set in dnssec-policy is taken.

The built-in policies use inline-signing.

This means that if you want to use the default policy without
inline-signing you either have to set it explicitly in the zone
clause:

    zone "example" {
        ...
        dnssec-policy default;
        inline-signing no;
    };

Or create a new policy, only overriding the inline-signing option:

    dnssec-policy "default-dynamic" {
        inline-signing no;
    };

    zone "example" {
        ...
        dnssec-policy default-dynamic;
    };

This also means that if you are going insecure with a dynamic zone,
the built-in "insecure" policy needs to be accompanied with
"inline-signing no;".
2023-08-01 06:55:48 +00:00
Ondřej Surý
8c4cf5b1de
fixup! Use cds_lfht for updatenotify mechanism in dns_db unit 2023-07-31 18:11:34 +02:00
Ondřej Surý
a1afa31a5a
Use cds_lfht for updatenotify mechanism in dns_db unit
The updatenotify mechanism in dns_db relied on unlocked ISC_LIST for
adding and removing the "listeners".  The mechanism relied on the
exclusive mode - it should have been updated only during reconfiguration
of the server.  This turned not to be true anymore in the dns_catz - the
updatenotify list could have been updated during offloaded work as the
offloaded threads are not subject to the exclusive mode.

Change the update_listeners to be cds_lfht (lock-free hash-table), and
slightly refactor how register and unregister the callbacks - the calls
are now idempotent (the register call already was and the return value
of the unregister function was mostly ignored by the callers).
2023-07-31 18:11:34 +02:00
Ondřej Surý
c1821ccf92
Call rcu_barrier() five times in the isc__mem_destroy()
Because rcu_barrier() needs to be called as many times as the number of
nested call_rcu() calls (call_rcu() calls made from call_rcu thread),
and currently there's no mechanism to detect whether there are more
call_rcu callbacks scheduled, we simply call the rcu_barrier() multiple
times.  The overhead is negligible and it prevents rare assertion
failures caused by the check for memory leaks in isc__mem_destroy().
2023-07-31 15:51:15 +02:00
Ondřej Surý
4dacdde28f
Refactor dns_badcache to use cds_lfht lock-free hashtable
The dns_badcache unit had (yet another) own locked hashtable
implementation.  Replace the hashtable used by dns_badcache with
lock-free cds_lfht implementation from liburcu.
2023-07-31 15:51:15 +02:00
Ondřej Surý
4ca64c1799
Pin dns_request to the associated loop
When dns_request was canceled via dns_requestmgr_shutdown() the cancel
event would be propagated on different loop (loop 0) than the loop where
request was created on.  In turn this would propagate down to isc_netmgr
where we require all the events to be called from the matching isc_loop.

Pin the dns_requests to the loops and ensure that all the events are
called on the associated loop.  This in turn allows us to remove the
hashed locks on the requests and change the single .requests list to be
a per-loop list for the request accounting.

Additionally, do some extra cleanup because some race condititions are
now not possible as all events on the dns_request are serialized.
2023-07-28 09:01:22 +02:00
Ondřej Surý
b6b0d81a36
Cleanup the __tsan_acquire/__tsan_release
With ThreadSanitizer support added to the Userspace RCU, we no longer
need to wrap the call_rcu and caa_container_of with
__tsan_{acquire,release} hints.  Remove the direct calls to
__tsan_{acquire,release} and the isc_urcu_{container,cleanup} macros.
2023-07-28 08:59:08 +02:00
Mark Andrews
b5076014b9 Return REFUSED if GSSAPI is not configured
Return REFUSED if neither a keytab nor a gssapi credential is
configured to GSSAPI/TKEY requests.
2023-07-28 14:37:32 +10:00
Ondřej Surý
dc3e07572b
Workaround AddressSanitizer overzealous check
The cds_lfht_for_each_entry and cds_lfht_for_each_entry_duplicate macros
had a code that operated on the NULL pointer, at the end of the list it
was calling caa_container_of() on the NULL pointer in the init-clause
and iteration-expression, but the result wasn't actually used anywhere
because the cond-expression in the for loop has prevented executing
loop-statement.  This made AddressSanitizer notice the invalid operation
and rightfully complain.

This was reported to the upstream and fixed there.  Pull the upstream
fix into our <isc/urcu.h> header, so our CI checks pass.
2023-07-27 15:21:39 +02:00
Ondřej Surý
31c43d4b76 Free struct stub_glue_request in stub_glue_response() callback
When stub_glue_response() is called, the associated data is stored in
newly allocated struct stub_glue_request.  The allocated structure is
never freed in the callback, thus we leak a little bit of memory.
2023-07-27 12:34:03 +02:00
Ondřej Surý
57a568e8f9 Unify the naming for struct stub_glue_request
The stub_request_nameserver_address() used 'request' as name for
struct stub_glue_request leading to confusion between 'request'
(stub_glue_request) and 'request->request' (dns_request_t).

Unify the name to 'sgr' already used in struct stub_glue_response().
2023-07-27 12:34:03 +02:00
Ondřej Surý
bf44554889 Refactor ns_server_create() to return void
After isc_stats_create() change, the ns_server_create() cannot fail, so
refactor the function to return void and fix all its uses.
2023-07-27 11:37:44 +02:00
Ondřej Surý
ea2fe8eea4 Refactor dns_zone_create() to return void
After isc_stats_create() change, the dns_zone_create() cannot fail, so
refactor the function to return void and fix all its uses.
2023-07-27 11:37:44 +02:00