Commit graph

45355 commits

Author SHA1 Message Date
Matthijs Mekking
d36d775f0f Rename private zone functions
Rename functions that are defined in the private header file to start
with 'dns__zone_'.
2026-04-08 14:24:17 +02:00
Matthijs Mekking
1a0b419991 Lock zone when incrementing statistics
dns__zone_stats_increment() requires the zone to be locked. This was
not always the case. This commit fixes that.
2026-04-08 14:24:17 +02:00
Matthijs Mekking
d3eba4e78f Replace static functions with private functions
Replace 'inc_stats()' with 'dns__zone_stats_increment()'.

Replace 'get_request_transport_type()' with
'dns_zone_getrequesttransporttype()'.
2026-04-08 14:24:17 +02:00
Matthijs Mekking
080e849eaa Move zonemgr to own source file
In order to make zone.c more readable, we are splitting it up in
separate source files. This moves the zonemgr to its own file
("zonemgr.c").

Since this code accesses the zone structure directly, move the
'struct dns_zonemgr' and its prerequisites to "zone_p.h".

The helper functions 'forward_cancel()', 'zone_xfrdone()',
'zmgr_start_xfrin_ifquota()', and 'zmgr_resume_xfrs() need to be
internally accessible to both source files.

Note: This commit does not compile.
2026-04-08 14:24:17 +02:00
Ondřej Surý
634194484d fix: test: Check exit status of dig and nsupdate in nsupdate system test
Add missing failure checks to six dig and nsupdate invocations in nsupdate system test so that command failures are properly caught instead of silently ignored.

Merge branch 'marka/check-return-codes-in-nsupdate-test' into 'main'

See merge request isc-projects/bind9!11811
2026-04-07 19:32:28 +02:00
Mark Andrews
9ba03a1848
Check exit status of dig and nsupdate in nsupdate system test
Add missing `|| ret=1` to six dig and nsupdate invocations in
tests.sh so that command failures are properly caught instead
of silently ignored.
2026-04-07 16:21:45 +02:00
Michal Nowak
114ea31f42 new: doc: Use ubuntu-24.04 for RTD, bump Python version, add Sphinx 9.1.0
Merge branch 'mnowak/rtd-image-bump' into 'main'

See merge request isc-projects/bind9!11806
2026-04-07 16:11:55 +02:00
Michal Nowak
ca3a582099
Add Sphinx 9.1.0
Update Sphinx Python package to the current version pulled in by "pip3
install sphinx_rtd_theme" run in a fresh Debian "trixie" container.
2026-04-07 15:53:03 +02:00
Michal Nowak
3a8e2f7427
Use ubuntu-24.04 for RTD, bump Python version 2026-04-07 13:35:03 +02:00
Matthijs Mekking
69d439cd1b chg: dev: Revert isdelegation() to return boolean value again
Closes #5838

Merge branch '5838-cid-645252-control-flow-issues-deadcode-in-validator' into 'main'

See merge request isc-projects/bind9!11792
2026-04-07 07:17:30 +00:00
Matthijs Mekking
e0f09bb374 Rename isdelegation() to is_insecure_referral()
The name 'isdelegation()' was confusing. This function is not checking
whether this message is a delegation, but whether the denial of
existence proofs in this message is a proof of a referral to an
unsigned zone.

The name 'is_unsecure_referral()' is more appropriate.
2026-04-07 08:38:57 +02:00
Matthijs Mekking
3ac1bb1c39 Revert isdelegation() to return boolean value again
The isdelegation() was changed to return an isc_result_t because the
idea was to have a separate return value DNS_R_NSEC3ITERRANGE to signal
to the caller we could not verify the proof because of too many
iterations in the NSEC3 record, or perhaps ISC_R_UNEXPECTED for a more
generic cause that verification was not done.

But this would make error handling more fragile and all we care about
is whether we can reliably say the NS bit was not set.

If we can not reliably say so, we have to treat it as an insecure
referrral.

Since the answer is either yes or no, we can revert back to returning
a boolean value.
2026-04-07 08:38:46 +02:00
Aydın Mercan
7c60b7da8a chg: dev: embed default sanitizer flags in executables
Replicating CI failures requires the developer to piece together the
sanitizer flags by hand, reducing ergonomics.

Fix this problem by embedding the relevant settings to the executables.
Symbol resolution still needs manual intervention by setting the env
variable `*SAN_SYMBOLIZER_PATH`. However, this doesn't affect any behavior.

The flags are passed though a meson-configured `sanitize.c.in` template file
to toggle which flags are included for the executable. Using the built-in
`__SANITIZE_XXX__` or `__has_feature` for this task is more trouble than it's
worth because only one of the two is available in most GCC/clang versions,
alongside the lack of `__SANITIZE_UNDEFINED__` from GCC.

Meson's own unit test execution sets its own `ASAN_OPTIONS` etc. To prevent it
from overriding the default options, we also pass the same options to unit tests
environment variables.

A new script `ci/sanitizer-default-check.py` is used in CI to detect if
a build directory with sanitizers enabled has a meson `executable` definition
that doesn't include the sanitizer flag source file.

Closes #5469

Merge branch '5469-embed-default-sanitizer-flags-in-the-executable' into 'main'

See merge request isc-projects/bind9!10919
2026-04-05 13:25:31 +03:00
Aydın Mercan
e16a3d7a8e
embed default sanitizer flags in executables
Replicating CI failures requires the developer to piece together the
sanitizer flags by hand, reducing ergonomics.

Fix this problem by embedding the relevant settings to the executables.
Symbol resolution still needs manual intervention by setting the env
variable `*SAN_SYMBOLIZER_PATH`. However, this doesn't affect any behavior.
2026-04-05 12:46:38 +03:00
Arаm Sаrgsyаn
175b121bc3 fix: usr: Fix a possible race condition during zone transfers
The :iscman:`named` process could terminate unexpectedly
when processing an IXFR message during a zone transfer.
This has been fixed.

Closes #5767

Merge branch '5767-use-after-free-xfrin_reset' into 'main'

See merge request isc-projects/bind9!11781
2026-04-03 12:05:17 +00:00
Nicki Křížek
187e571f4d Rewrite xfer/ans11/ans.py to use AsyncDnsServer
Replace the hand-rolled threaded socket server with the standard
AsyncDnsServer framework used by other ans.py servers in the test suite.

The DNS wire-format message builders (IXFR diff, AXFR, SOA, SERVFAIL)
are retained unchanged since they produce carefully crafted messages
needed to trigger the IXFR->AXFR race condition. The server
infrastructure is replaced:

- Manual TCP/UDP socket management and threading replaced by
  AsyncDnsServer, which handles both protocols, pidfile lifecycle,
  and signal handling.
- Query parsing replaced by the framework's dns.message-based parser;
  query dispatch moved into IxfrRaceHandler.get_responses().
- The axfr_done_event threading.Event replaced by a boolean instance
  variable on IxfrRaceHandler, safe within the single asyncio event
  loop.
- For IXFR over TCP, the handler yields two BytesResponseSend actions
  (msg1 then msg2) so the framework sends both with TCP length prefixes,
  preserving the race-triggering sequence.
- For IXFR over UDP, the TC flag is set on the response to force TCP
  retry.
- Unused encode_name_compressed() and parse_dns_query() removed.

Also fix a timing issue that might result in the initial transfer not
being done by the time the test is executed -- since ns11 is started
after ns6. Ensure the initial transfer has happened before running the
ixfr_race test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 11:01:34 +00:00
Aram Sargsyan
141ff7bfa7 Fix a race condition in xfrin_recv_done() when calling xfrin_reset()
When the xfrin_recv_done() function decides to retry the transfer
using AXFR because of a previous error, it calls the xfrin_reset()
function which calls dns_db_closeversion() on 'xfr->ver'. The problem
is that the ixfr processing of a previous message could be still
in process in a worker thread, which then can use freed 'xfr->ver'.

If there is an ongoing worker thread delay the AXFR retry until after
the worker thread has finished its work.
2026-04-03 11:01:34 +00:00
Aram Sargsyan
5c248e7d1a Add a test to check for IXFR->AXFR race-condition
The test initiates a zone transfer with IXFR, which produces
a big amount of differences and then generates an error. The
secondary should be able to gracefully shutdown the ongoing
IXFR transfer and retry with AXFR without race conditions
between them.

This test checks for an issue (GL#5767) but since a race
condition is usually time-sensitive it might require several
attempts before it reproduces the issue.
2026-04-03 11:01:34 +00:00
Ondřej Surý
15f058b5a2 fix: usr: Fix wrong NSEC proof for empty non-terminals after IXFR
When a secondary received an IXFR that transitioned a zone from unsigned to NSEC-signed, queries for empty non-terminal names returned the zone apex NSEC record instead of the NSEC that actually covers the queried name.  The issue only occurred with incremental transfers; a full AXFR or a server restart resolved it.

Closes #5824

Merge branch 'ondrej/fix-nsec-ixfr' into 'main'

See merge request isc-projects/bind9!11786
2026-04-03 06:33:54 +02:00
Ondřej Surý
3fe3751c22 Fix wrong NSEC proof for empty non-terminals after IXFR
When receiving NSEC records via IXFR, the node was not marked with
havensec because the condition checked the uninitialized output
rdataset type instead of the input rdataset type.  This caused
queries for empty non-terminal names in NSEC-signed zones received
via IXFR to return the zone apex NSEC instead of the correct
covering NSEC record.

The bug was introduced in f4b4f030.
2026-04-03 06:33:31 +02:00
Ondřej Surý
8a4990d6ff Add regression test for NSEC proof after unsigned-to-signed IXFR
Test that a secondary receiving an IXFR transitioning a zone from
unsigned to NSEC-signed returns the correct covering NSEC record
for empty non-terminal names.

Add isctest.query.wait_for_serial() shared helper for waiting until
a server has a specific SOA serial.
2026-04-03 06:33:31 +02:00
Ondřej Surý
245c71dfac chg: dev: Change NSEC3 and NSEC3PARAM rdata struct fields to use isc_region_t
Replace the separate pointer+length field pairs in the NSEC3 and NSEC3PARAM rdata structures (salt/salt_length, next/next_length, typebits/len) with isc_region_t, making the fields self-describing and eliminating a class of length-mismatch bugs.

Merge branch 'ondrej/change-nsec3-and-nsec3param-to-use-isc_region_t' into 'main'

See merge request isc-projects/bind9!11592
2026-04-02 18:05:58 +02:00
Ondřej Surý
14cebe4d61 Change NSEC3 and NSEC3PARAM struct fields to use isc_region_t
Replace the separate pointer+length field pairs in dns_rdata_nsec3_t
(salt/salt_length, next/next_length, typebits/len) and
dns_rdata_nsec3param_t (salt/salt_length) with isc_region_t.  This
makes the structs self-describing and eliminates a class of
length-mismatch bugs.

The dns_zone_setnsec3param() signature is updated to take
isc_region_t *salt instead of separate saltlen and salt arguments.

Function signatures for dns_nsec3_addnsec3, dns_db_getnsec3parameters,
and related internal functions still use separate pointer+length pairs
and should be updated in a follow-up.
2026-04-02 16:53:18 +02:00
Matthijs Mekking
ae739daec2 chg: dev: Fix off by one error in dnssec-ksr sign
If the inception time of the signature is exactly equal to the inactive time of the key, add the signature.

Merge branch 'matthijs-skr-off-by-one-bug' into 'main'

See merge request isc-projects/bind9!11791
2026-04-02 14:47:46 +00:00
Matthijs Mekking
d9b6036e0f Also fix off by one error in system test
The system test was also subject to the same off by one bug that also
existed in the code. That is: if the inception time of the signature
is exactly equal to the inactive time of the key, we still have to
expect the signature.
2026-04-02 14:47:18 +00:00
Matthijs Mekking
784a441e2d Add fast test case
This specific test case triggered a bug where the SKR included bundles
with unsigned DNSKEY RRsets (signatures where omitted because the
inception time was equal to the inactive time of the key).
2026-04-02 14:47:18 +00:00
Matthijs Mekking
bc6dad585d Fix off by one error in dnssec-ksr sign
If the inception time of the signature is exactly equal to the
inactive time of the key, still include the signature. Otherwise there
may be corner cases where signatures are omitted erroneously.
2026-04-02 14:47:18 +00:00
Matthijs Mekking
36acc92131 chg: dev: Split up zone.c (zone properties)
In order to make `zone.c` more readable, split it up in separate source files. This moves most of the set and get functions to `zoneproperties.c`.

Merge branch 'matthijs-refactor-zone-1' into 'main'

See merge request isc-projects/bind9!11501
2026-04-02 14:29:27 +00:00
Matthijs Mekking
93376b8f67 Return void in functions that cannot fail
dns_zone_getloadtime(), dns_zone_getexpiretime(),
dns_zone_getrefreshtime(), and dns_zone_getrefreshkeytime()
cannot fail, so return void instead of ISC_R_SUCCESS.
2026-04-02 15:50:09 +02:00
Matthijs Mekking
f015170ec7 Fix some documentation issues
dns_zone_setorigin() does not return ISC_R_SUCCESS, but void.

dns_zone_setalsonotify() referred to non-existing
dns_zone_alsonotifywithkeys().
2026-04-02 15:50:09 +02:00
Matthijs Mekking
f04590d006 Remove unneccesary functions
Remove dns_zone_getmem() (duplicate of dns_zone_getmctx()).
Remove dns_zone_getrdclass() (duplicate of dns_zone_getclass()).
Remove obsoleted dns_zone_getstatscounters().
Remove obsoleted dns_zone_setstatistics().
2026-04-02 15:50:09 +02:00
Matthijs Mekking
af505bc44f Small refactor 'dns_zone_set*acl()'
The various 'dns_zone_set*acl()' functions can be refactored to
call 'dns_zone_clear*acl()', to avoid code duplication.
2026-04-02 15:50:09 +02:00
Matthijs Mekking
6c69fd16d0 Lock zone when checking for inline raw/secure
The caller is supposed to hold the zone lock for 'inline_raw()' and
'inline_secure()', but when adding 'REQUIRE(LOCKED_ZONE(zone));' to
these functions it turned out to be not always the case.
2026-04-02 15:50:09 +02:00
Matthijs Mekking
94788446db Rename private zone functions
Rename functions that are defined in the private header file to start
with 'dns__zone_'.
2026-04-02 15:50:09 +02:00
Matthijs Mekking
2893e128a7 Move zone set/get properties to own source file
In order to make zone.c more readable, we are splitting it up in
separate source files. This moves the set and get functions to its
own file ("zoneproperties.c").

Since this code accesses the zone structure directly, move the
'struct dns_zone' and its prerequisites to "zone_p.h".

The helper functions 'inline_raw()', 'inline_secure()',
'dns_zone_setview_helper()', 'zone_settimer(), 'set_resigntime()', and
'zone_freedbargs()' need to be internally accessible to both source
files.

A few set/get functions remain in zone.c for now:
- dns_zone_getserial
- dns_zone_getversion
- dns_zone_setviewcommit
- dns_zone_setviewrevert
- dns_zone_get_rpz_num
- dns_zone_set_parentcatz
- dns_zone_get_parentcatz
- dns_zone_setrawdata
- dns_zone_setskr
- dns_zone_getskrbundle
- dns_zone_setnsec3param
- dns_zone_setoption
- dns_zone_getoptions
- dns_zone_getrequesttransporttype
- dns_zone_getredirecttype
- dns__zone_getnotifyctx
- dns_zone_getgluecachestats
- dns_zone_setplugins
- dns_zone_setserial
- dns_zone_getxfr
- dns_zone_getkeystores
2026-04-02 15:50:07 +02:00
Matthijs Mekking
c56d4c13f9 fix: usr: Fix rndc modzone behavior for a zone in named.conf
If a zone was present in the configuration file and not originally added by `rndc addzone`, `rndc modzone` for that zone would succeed once but subsequent `modzone` attempts would fail. This has been fixed.

Closes #5826

Merge branch '5826-fix-subsequenrt-rndc-modzone' into 'main'

See merge request isc-projects/bind9!11744
2026-04-02 13:27:32 +00:00
Matthijs Mekking
ccb01b15e5 Also remove modded catalog zones from NZD
In the rare case where a catalog zone member is being modified with
'rndc modzone', also mark the zone as modded, so when the zone is
deleted again with 'rndc delzone', the configuration is also removed
from the NZD.
2026-04-02 12:35:54 +00:00
Matthijs Mekking
daa9e57448 Remove modified zone configuration from NZD
When a zone that is configured in named.conf is modified with
'rndc modzone', the new zone configuration is now also stored in the
NZD.

This must be removed when the zone is deleted with 'rndc delzone',
otherwise a restart will fail.
2026-04-02 12:35:54 +00:00
Matthijs Mekking
b8e16cf1cb Test restart works after rndc modzone
When a zone that is configured in named.conf is modified with
'rndc modzone', the new zone configuration is now also stored in the
NZD. Add a test to ensure that after a restart, the old zone
configuration is used.
2026-04-02 12:35:54 +00:00
Matthijs Mekking
98784ed753 Add the modified zone configuration to NZD
When a zone that is configured in named.conf is modified with
'rndc modzone', the zone configuration is deleted from the effective
config. Store the new configuration in the NZD. Mark the zone
as 'modified by rndc modzone'. Otherwise, subsequent calls to
'rndc modzone' would fail because the zone configuration cannot be
found.
2026-04-02 12:35:54 +00:00
Matthijs Mekking
e1bd1a4003 Introduce zone functions dns_zone_(get|set)modded
Introduce new functions to set and get whether the zone configuration
has been modified with 'rndc modzone'.
2026-04-02 12:35:54 +00:00
Matthijs Mekking
13414c640b Remove unused zoneconf from do_addzone
This is unused, so we can make the function call shorter.
2026-04-02 12:35:54 +00:00
JINMEI Tatuya
cbd1d71a1f Test rndc modzone succeeds twice for a zone in named.conf
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 test is copied from commit b737171ee215446701e7c8d4ac55d8a0e13426aa.
2026-04-02 12:35:54 +00:00
Colin Vidal
b8dcabbd72 fix: usr: possible crash when a resolver validate a static-stub zone
A NULL pointer dereference could be made in some circumstances when resolving and validating a name under a `static-stub` zone. This is now fixed.

Merge branch 'colin/fix-dns_view_bestzonecut-nullptrderef' into 'main'

See merge request isc-projects/bind9!11788
2026-04-02 14:16:58 +02:00
Colin Vidal
fc03a876ae fix NULL dereference in dns_view_bestzonecut()
When `dns_view_bestzonecut()` is called with a NULL `delegsetp`, it
calls `bestzonecut_zone()` with a NULL `rdataset` pointer but there is a
non-guarded de-reference of the `rdataset` pointer in
`bestzonecut_zone()`.

In practice, the only current situation where `dns_view_bestzonecut()`
is called with NULL `delegsetp` is from a case of `seek_ds()` _and_ the
non-guarded dereference occurs only if there is a static-stub local
zone matching the zonecut `seek_ds()` is looking for. It's unclear if
such flow is actually possible.

The `rdataset` is now always valid inside `dns_view_bestzonecut()`. (It
was initially set only if `delegsetp` was set to avoid extra works in
the qpzone, which can be skipped when `rdataset` is NULL, but this
doesn't really make a difference, considering we are in a slow path
considering the result wasn't found in this case.)
2026-04-02 12:16:12 +02:00
Colin Vidal
43c58dafcc fix: dev: remove deadcode in query_addbestns()
The local variable `zfname` was released in the cleanup part of the
function if not NULL, but it turns out it is now always NULL at that
point.

The flow can get to that part only in two cases: either `zfname` is not
NULL, and then it's ownership is moved to a different variable (thus, it
is now NULL), or `zfname` is already NULL.

Removing the bit of deadcode releasing it.

Merge branch 'colin/fix-getbestns-deadcode' into 'main'

See merge request isc-projects/bind9!11790
2026-04-02 11:51:25 +02:00
Colin Vidal
50a2fce68f remove deadcode in query_addbestns()
The local variable `zfname` was released in the cleanup part of the
function if not NULL, but it turns out it is now always NULL at that
point.

The flow can get to that part only in two cases: either `zfname` is not
NULL, and then it's ownership is moved to a different variable (thus, it
is now NULL), or `zfname` is already NULL.

Removing the bit of deadcode releasing it.
2026-04-02 11:51:12 +02:00
Michal Nowak
5eda8a2543 chg: doc: Revert "Add Sphinx 9.1.0"
This reverts commit a31a4c2d2d.

ReadTheDocs will not work with this version:

    python -m pip install -r https://gitlab.isc.org/isc-projects/bind9/-/raw/main/doc/arm/requirements.txt
    ERROR: Ignored the following yanked versions: 8.3.0
    ERROR: Ignored the following versions that require a different python version: 9.1.0 Requires-Python >=3.12; 9.1.0rc1 Requires-Python >=3.12; 9.1.0rc2 Requires-Python >=3.12
    ERROR: Could not find a version that satisfies the requirement Sphinx==9.1.0 (from versions: 0.1.61611, ..., 9.0.4)
    ERROR: No matching distribution found for Sphinx==9.1.0

Merge branch 'mnowak/revert-sphinx-9.1.0' into 'main'

See merge request isc-projects/bind9!11793
2026-04-02 11:46:44 +02:00
Michal Nowak
aef329b18d
Revert "Add Sphinx 9.1.0"
This reverts commit a31a4c2d2d.

ReadTheDocs will not work with this version:

    python -m pip install -r https://gitlab.isc.org/isc-projects/bind9/-/raw/main/doc/arm/requirements.txt
    ERROR: Ignored the following yanked versions: 8.3.0
    ERROR: Ignored the following versions that require a different python version: 9.1.0 Requires-Python >=3.12; 9.1.0rc1 Requires-Python >=3.12; 9.1.0rc2 Requires-Python >=3.12
    ERROR: Could not find a version that satisfies the requirement Sphinx==9.1.0 (from versions: 0.1.61611, ..., 9.0.4)
    ERROR: No matching distribution found for Sphinx==9.1.0
2026-04-02 11:45:46 +02:00
Michal Nowak
91d3c659d3 chg: doc: Add Sphinx 9.1.0
Update Sphinx Python package to the current version pulled in by "pip3
install sphinx_rtd_theme" run in a fresh Debian "trixie" container.

Merge branch 'mnowak/sphinx-9.1.0' into 'main'

See merge request isc-projects/bind9!11783
2026-04-02 10:35:02 +02:00