Send various UPDATE requests that are known to have caused
crashes previously with deliberately misconfigured non-IN
zones; confirm that UPDATE is not processed.
(cherry picked from commit e2f7ba2a4b6e7e5dba2fb1a2c9b2f0323e9a88be)
Return NOTIMP for UPDATE and NOTIFY requests received for views with a
class other than IN. Only QUERY is now supported for non-IN views such
as CHAOS.
When running dns dns_rdata_tostruct() with types that are only defined
for class IN, ensure that the class is correct before proceeding.
Add an assertion that any zone being updated is of class IN. (Note
that previously, a DLZ zone could have its class value set incorrectly
to NONE; this has been fixed.)
This addresses YWH-PGM40640-70 and YWH-PGM40640-73 (as well as any
similar problems that might have occurred in the future) by minimizing
the code paths that can be reached by rdata classes other than IN, so it
is safe for the implementation to assume that rdatatypes that are only
defined for class IN, such as SVCB or WKS, have been parsed and
validated, and not accepted as unknown/opaque data.
Fixes: isc-projects/bind9#5777Fixes: isc-projects/bind9#5779
(cherry picked from commit a6d8e330ed6cf0021bff3f00aa1dc7a296f5aec0)
Force recursion off, and set allow-recursion/allow-recursion-on ACLs
to none, for views with a class other than IN. Log a configuration
warning if recursion is explicitly enabled for a non-IN view.
This addresses YWH-PGM40640-74 and YWH-PGM40640-75 by preventing any
attempt at recursive processing in a class-CHAOS view, ensuring that
server addresses used for recursive queries and received in recursive
responses are of the expected format.
Fixes: isc-projects/bind9#5780Fixes: isc-projects/bind9#5781
(cherry picked from commit 7becff1a14684a68208c92b3b0315c045c05ad75)
When named_os_gethostname() was replaced with raw gethostname(), the
success/failure polarity was flipped: the fallback to "localhost" now
runs on success and the hostname buffer is left uninitialized on
failure. In the failure path, snprintf() then reads the uninitialized
stack buffer, disclosing stack contents via the rndc status reply.
(cherry picked from commit f7859247df)
If a zone is in named.conf, not originally added by rndc addzone,
rndc modzone for that zone succeeds once, but subsequent modzone
attempts fail. This is because do_modzone removes the zone config
from global or view options, but it would fail due to 'not found'
once the config is removed.
The fix is to ensure re-adding the updated zone config to the
global or view options. This also works as a more complete fix
for the issue 85453d3 atempted to solve, ensuring rndc showzone
shows the latest config: it now works for multple attemps of
modzone, and with named that is not built with LMDB.
The change in this commit relies on UNCONST in a few places.
That's not clean, but 'add/mod/delzone' generally seems to
need it (for example, delete_zoneconf uses it to modify the list
of zones). In that sense, this change follows the convention
(for a longer term, there may have to be a better API so that we
can modify config obtions that were once parsed).
This reverts commit 85453d393d.
This commit doesn't seem to be a complete solution of what
it appears to fix: showzone succeeds and shows the modified
config after first modzone, but subsequent attempts of modzone
fail (though not because of the commit being reverted), let
alone showing the correct new config.
Revering the change for now, and will provide a more comprehensive
fix in the next commit.
If named is built without LMDB and has a zone in named.conf,
then rndc modzone for that zone triggers an assertion failure
unless there's already an NZF file. This is because load_nzf
doesn't create 'nzf_config' when NZF is missing, while a valid
nzf_config is assumed in do_modzone when it tries to add the
modified zone config to add_parser.
The crash is fixed by skipping the call to cfg_parser_mapadd when
nzf_config is NULL. Skipping it should be okay since the config stored
in add_parser would be needed only for subsequently deleting a zone by
rndc delzone when the zone was originally added by rndc addzone, but
in this case the zone was not 'added'. Checking if nzf_config is NULL
before using it also seems to be consistent with other parts of the
implementation.
'rndc modzone' deletes the old configuration. If we don't store the
new zone config, when we do a 'rndc showzone' it will be a failure.
This is not an issue in the 9.21 version, because of the effective
config behavior.
If we are modifiying the zone, the zone must have been added before.
Don't overwrite this value on modifications.
Also it feels cleaner to pass added=false to configure_zone() in
do_modzone().
(cherry picked from commit 780872e07e)
Some code paths try to lock an already locked view->newzone.lock.
For example, do_modzone() aqcuires the lock and then calls
delete_zoneconf(), that wants to acquire the same lock.
Add a parameter to delete_zoneconf() that informs the function if the
lock has already been acquired.
(cherry picked from commit 71587b0816)
The asynchronous SIG(0) handling improperly used srcaddr, and dstaddr
from the caller's stack and didn't attach to aclenv. This could
possibly lead to ACL bypass as an invalid srcaddr could be matched or
possible assertion failure if the ACL environment would change between
the initial call and the SIG(0) processing due to the server
reconfiguration. This has been fixed.
(cherry picked from commit b4b81deed9)
This better reflects the true nature of the function as we are reading
the ephemeral port range which is not related to UDP at all.
(cherry picked from commit 295139f8ca)
For Linux >= 6.8:
Since 2023, Linux has introduced a change to the IP_LOCAL_PORT_RANGE
socket option that eliminates the need for the random window
shifting (implemented as a fallback in the next commit).
By setting IP_LOCAL_PORT_RANGE option, we tell the kernel to use better
approach to the source port selection.
For Linux << 6.8:
This implement selecting port by random shifting range leveraging the
IP_LOCAL_PORT_RANGE socket option. The network manager is initialized
with the ephemeral port range (on startup and on reconfig) and then for
every outgoing TCP connection, we define a custom port range (1000
ports) and then randomly shift the custom range within the system range.
This helps the kernel to reduce the search space to the custom window
between <random_offset, random_offset + 1000>.
Reference:
https://blog.cloudflare.com/linux-transport-protocol-port-selection-performance/#kernel
(cherry picked from commit 04c81b55d2)
A catalog zone is updated in an offloaded thread, which is not
stopped during a reconfiguration in an exclusive mode, and so
can cause a race condition with it.
Waiting for the offloaded threads to complete their work before
entering into the exclusive mode can potentially cause unwanted
delays, because offloaded threads are generally "allowed" to take
a longer amount of time before they complete.
Add a dns_catz_zone_prereconfig()/dns_catz_zone_postreconfig() pair
of functions which currently just lock the catalog zone when
reconfiguring it. The change should eliminate the race.
As a side note, there was already a similar pair of functions,
dns_catz_prereconfig() and dns_catz_postreconfig() which are called
before and after reconfiguring a 'dns_catz_zones_t' object.
Below are the stack traces of the reconfiguration thread which has
asserted, and a catalog zone update thread which was caught in the
middle of its work despite the fact that the exclusive mode is
turned on.
Stack trace of thread 23859:
#0 0x00007f80e7b8e52f raise (libc.so.6)
#1 0x00007f80e7b61e65 abort (libc.so.6)
#2 0x0000000000422558 assertion_failed (named)
#3 0x00007f80eaa6799e isc_assertion_failed (libisc-9.18.41.so)
#4 0x00007f80ea5bc788 dns_catz_entry_getname (libdns-9.18.41.so)
#5 0x000000000042ce0e catz_reconfigure (named)
#6 0x000000000042d3c5 configure_catz_zone (named)
#7 0x000000000042d7a4 configure_catz (named)
#8 0x0000000000430645 configure_view (named)
#9 0x000000000043d998 load_configuration (named)
#10 0x000000000044184f loadconfig (named)
#11 0x0000000000442525 named_server_reconfigcommand (named)
#12 0x000000000041b277 named_control_docommand (named)
#13 0x000000000041c74a control_command (named)
#14 0x00007f80eaa912ae task_run (libisc-9.18.41.so)
#15 0x00007f80eaa914cd isc_task_run (libisc-9.18.41.so)
#16 0x00007f80eaa46435 isc__nm_async_task (libisc-9.18.41.so)
#17 0x00007f80eaa467aa process_netievent (libisc-9.18.41.so)
#18 0x00007f80eaa475a6 process_queue (libisc-9.18.41.so)
#19 0x00007f80eaa46227 process_all_queues (libisc-9.18.41.so)
#20 0x00007f80eaa462a1 async_cb (libisc-9.18.41.so)
#21 0x00007f80e8d01893 uv__async_io.part.3 (libuv.so.1)
#22 0x00007f80e8d13ac4 uv__io_poll (libuv.so.1)
#23 0x00007f80e8d023fb uv_run (libuv.so.1)
#24 0x00007f80eaa45ced nm_thread (libisc-9.18.41.so)
#25 0x00007f80eaa9bda3 isc__trampoline_run (libisc-9.18.41.so)
#26 0x00007f80e7f1e1ca start_thread (libpthread.so.0)
#27 0x00007f80e7b798d3 __clone (libc.so.6)
...
...
Stack trace of thread 23912:
#0 0x00007f80ea5bc2da dns_catz_options_setdefault (libdns-9.18.41.so)
#1 0x00007f80ea5bd411 dns__catz_zones_merge (libdns-9.18.41.so)
#2 0x00007f80ea5c3c2f dns__catz_update_cb (libdns-9.18.41.so)
#3 0x00007f80eaa4fee9 isc__nm_work_run (libisc-9.18.41.so)
#4 0x00007f80eaa9bda3 isc__trampoline_run (libisc-9.18.41.so)
#5 0x00007f80eaa4ff48 isc__nm_work_cb (libisc-9.18.41.so)
#6 0x00007f80e8cfc75e worker (libuv.so.1)
#7 0x00007f80e7f1e1ca start_thread (libpthread.so.0)
#8 0x00007f80e7b798d3 __clone (libc.so.6)
(cherry picked from commit aed9cafd5c)
previously, there were over 40 separate definitions of CHECK macros, of
which most used "goto cleanup", and the rest "goto failure" or "goto
out". there were another 10 definitions of RETERR, of which most were
identical to CHECK, but some simply returned a result code instead of
jumping to a cleanup label.
this has now been standardized throughout the code base: RETERR is for
returning an error code in the case of an error, and CHECK is for jumping
to a cleanup tag, which is now always called "cleanup". both macros are
defined in isc/util.h.
(cherry picked from commit 52bba5cc34)
Maintain the relationship between the parent and child fetch and when
creating a new child fetch, properly check the resolution loops that
would lead to a new fetch would join one of the parent's fetch contexts.
(cherry picked from commit 4d307ac67a)
Add a default "response-padding" option in the global defaults,
to disable the option, and simplify the configuration code so that
looks at the global defaults if the option is not set in named.conf.
This enables us to remove the 'optionmaps' variable in configure_view(),
which was used for options that only look in named.conf.
(cherry picked from commit cf409e814f)
In the past, "dnssec-validation" was not looked up in the global
defaults unless "dnssec-enable" was true. "dnssec-enable" has been
obsolete for several years, but dnssec-validation was still being
configured in two steps. This commit removes the vestigial bits of
the old logic.
(cherry picked from commit fffae65e27)
"max-cache-size default;" is allowed, according to the documentation
and the parser, but when it's configured, named crashes due to an
INSIST that the only legal string value is "unlimited". this has
been fied.
the configuration has also been simplified. previously, we checked for
max-cache-size in view and options, then determined whether to look in
the global default options based on whether the view had recursion set.
the default value set there was only applicable to views with recursion.
now, the default is an explicit "default", which affects views with
and without recursion in different ways.
the cfg type for "max-cache-size" has been changed from
cfg_type_sizeorpercent to cfg_type_maxcachesize.
(cherry picked from commit cd921cc7ef)
With named-checkconf -k you can check your configuration including
checking the dnssec-policy keys against the configured keystores. If
there is a mismatch in the key files versus the policy, named-checkconf
will fail. This is useful for running before migrating to dnssec-policy.
For logging purposes, introduce a function that writes the identifying
information about a policy key into a string.
Allow a dnssec key to be initialized outside the keymgr code.
Add 'log_errors' to 'cfg_kasp_fromconfig' to avoid duplicate error
logs.
(cherry picked from commit 9fe520ece9)
If the server is reloaded, new views are created and preexisting cache
is attached to those _but_ something goes wrong later, the previous
views are restored but the previous cache list is destroyed. This makes
the subsequent reload to drop the existing cache. This fixes it by
avoiding a mutation of the old cache list.
(cherry picked from commit a1703fa35b)
When dns_catz_zone_add() returns ISC_R_EXISTS and there is no
'default-primaries' or 'default-masters', the ISC_R_EXISTS result
code doesn't get reset to ISC_R_SUCCESS, and the function returns
ISC_R_EXISTS instead of ISC_R_SUCCESS. Which means that the zone
is successfully added, but the caller assumes that the function has
failed.
Reset 'result' to ISC_R_SUCCESS when dns_catz_zone_add() returns
ISC_R_EXISTS (it's not an error condition).
Refactor the code go call dns_catz_zone_add() when all other error
conditions are already checked.
(cherry picked from commit db36ae47d2)
The 'scan-build' job in the CI reports a false positive:
/*
2705 * We are reusing the old rpzs, so it can no longer be its
2704 * first time.
2707 */
2708 pview->rpzs->first_time = false;
>> Access to field 'first_time' results in a dereference of a null pointer (loaded from field 'rpzs')
Add INSISTs to silence the report.
When a DNS Response Policy Service (DNSRPS) interface is used, the
'servfail-until-ready yes' option is ignored, because RPZ zones are
not processed by BIND.
By default, when named is started it may start answering to
queries before the response policy zones are completely loaded
and processed. This new feature gives an option to the users to
tell named that incoming requests should result in SERVFAIL anwser
until all the response policy zones are procesed and ready.
(cherry picked from commit 41387b8d30)
During the initial configuration of named after startup, 'first_time'
is true. This is needed for implementing the new 'servfail-until-ready'
configuration option, which should take into effect only during the
initial configuration.
(cherry picked from commit 88ed81e12d)
When a key retire, key generation/introduction, or a state transition
to RUMOURED/UNRETENTIVE should happen, instead they are logged.
When those logs look good, you can run 'rndc dnssec -step' to run the
keymgr and apply those steps.
(cherry picked from commit aa49850b5e)
The LSP server (using clangd) was always complaining about:
Suspicious string literal, probably missing a comma
for the two Local IPv6 Unicast Addresses strings that spanned
across multiple lines. Disable clang-format for these two lines.
(cherry picked from commit 6b7c99027d)
libsystemd, despite being useful, adds a huge surface area for just
using the sd_notify API. libsystemd's surface has been exploited in the
past [1].
Implement the systemd notification protocol by hand since it is just
sending newline-delimited datagrams to a UNIX socket. The code shouldn't
need more attention in the future since the notification protocol is
covered under systemd's stability promise [2].
We don't need to support VSOCK-backed service notifications since they
are only intended for virtual machine inits.
[1]: https://www.openwall.com/lists/oss-security/2024/03/29/4
[2]: https://systemd.io/PORTABILITY_AND_STABILITY/
(cherry picked from commit 3eb253e81f)
This new option sets the delay, in seconds, to wait before sending
a set of NOTIFY messages for a zone. Whenever a NOTIFY message is
ready to be sent, sending will be deferred for this duration.
(cherry picked from commit e42d6b4810)
This new rndc option allows to reset some statistics counters during
runtime. At this moment only the high-water type counters are supported
as such an ability to reset them after the initial peaks during the
server's "warm-up" phase can be useful for some operators.
(cherry picked from commit bab20802b3)
In the case where 'clients-per-query' is larger than
'max-clients-per-query', raise 'max-clients-per-query' so that
'clients-per-query' equals 'max-clients-per-query' and log a warning
that this is what happened.
(cherry picked from commit f6f9645ed1)
Previously a hard-coded limitation of maximum two key or message
verification checks were introduced when checking the message's
SIG(0) signature. It was done in order to protect against possible
DoS attacks. The logic behind choosing the number two was that more
than one key should only be required only during key rotations, and
in that case two keys are enough. But later it became apparent that
there are other use cases too where even more keys are required, see
issue number #5050 in GitLab.
This change introduces two new configuration options for the views,
sig0key-checks-limit and sig0message-checks-limit, which define how
many keys are allowed to be checked to find a matching key, and how
many message verifications are allowed to take place once a matching
key has been found. The latter protects against expensive cryptographic
operations when there are keys with colliding tags and algorithm
numbers, with default being 2, and the former protects against a bit
less expensive key parsing operations and defaults to 16.
(cherry picked from commit 716b936045)
The new command is `rndc memprof`. The memory profiling status is also
reported inside `rndc status`. The status also shows whether named can
toggle memory profiling or not and if the server is built with jemalloc.
(cherry picked from commit b495e9918e)
Instead of mixing the dns_resolver and dns_validator units directly with
the EDE code, split-out the dns_ede functionality into own separate
compilation unit and hide the implementation details behind abstraction.
Additionally, the EDE codes are directly copied into the ns_client
buffers by passing the EDE context to dns_resolver_createfetch().
This makes the dns_ede implementation simpler to use, although sligtly
more complicated on the inside.
Co-authored-by: Colin Vidal <colin@isc.org>
Co-authored-by: Ondřej Surý <ondrej@isc.org>
(cherry picked from commit 2f8e0edf3b)
If the generated status output exceeds 4096 it was silently truncated,
now we output that the status was truncated.
(cherry picked from commit 7ae7851173)
Having zone statements that are also top blocks is confusing, and if
we want to add more in the future (which I suspect will be for
generalized notifications, multi-signer), we need to duplicate a lot
of code.
Remove top blocks 'parental-agents' and 'primaries' and just have one
top block 'remote-servers' that you can refer to with zone statements.
(cherry picked from commit b121f02eac)
Add a none parameter to named configuration option `query-source` (respectively `query-source-v6`) which forbid usage of IPv4 (respectively IPv6) addresses when named is doing an upstream query.
Closes#4981 Turning-off upstream IPv6 queries while still listening to downstream queries on IPv6.
Merge branch 'colin/querysource-none' into 'main'
See merge request isc-projects/bind9!9727
Backport of MR !9727
Some changes had to be done to the existing 9.20.x code in order to
make this backport compatible:
- first, the 9.20.x branches support the `port` parameter in
query-source[-v6], where 9.21.x does not. The original changes
depend on things that can't be backported because that would break
`port` support.
- second, the changes remove the optional `address` parameter from the
canonical form. So `query-source address <ip>` is now printed as
`query-source <ip>`. This means that `named-checkconf -p` will now
generate different output if users have `query-source address <ip>` or
`query-source address <ip> port <port>`; it will now generate
`query-source <ip>` or `query-source <ip> port <port>`. This is a
non-breaking change, because the parser has been updated to support
this form as well.
when the attach-cache option is used in the options block
with an arbitrary name, it causes all views to use the same
cache. however, previously, this could cause the cache to be
deleted and a new cache created every time the server was
reconfigured. this did *not* occur when attach-cache was
used at the view level to refer back to another view's cache.
in this commit we correct the problem by checking for
pre-existing caches during reconfiguration, and moving
them from the old server cache list to the new cache list
before cleaning up and freeing the old cache list.
(cherry picked from commit f3af8a7dc3)
Add another option to configure how many outgoing queries per
client request is allowed. The existing 'max-recursion-queries' is
per restart, this one is a global limit.
(cherry picked from commit bbc16cc8e6)
Add support for Extended DNS Errors (EDE) error 22: No reachable
authority. This occurs when after a timeout delay when the resolver is
trying to query an authority server.
(cherry picked from commit d13e94b930)
Commit amended in order to fix usage of isc_log_write (adding dns_lctx
parameter)
The lame-ttl processing was overriden to be disabled in the config,
but the code related to the lame-ttl was still kept in the resolver
code. More importantly, the DNS_RESOLVER_BADCACHETTL() macro would
cause the entries in the resolver badcache to be always cached for at
least 30 seconds even if the lame-ttl would be set to 0.
Remove the dns_badcache code from the dns_resolver unit, so we save some
processing time and memory in the resolver code.
(cherry picked from commit b61739836d)
Instead of cleaning the dns_badcache opportunistically, add per-loop
LRU, so each thread-loop can clean the expired entries. This also
allows removal of the atomic operations as the badcache entries are now
immutable, instead of updating the badcache entry in place, the old
entry is now deleted from the hashtable and the LRU list, and the new
entry is inserted in the LRU.
(cherry picked from commit 2cb5a6210f)