Commit graph

43503 commits

Author SHA1 Message Date
Matthijs Mekking
6f2fe873be [9.20] chg: doc: Clarify rndc sign
It was not explicitly clear that ``rndc sign`` replaces signatures of inactive keys and updates signatures that are not so fresh.

Closes #5490

Backport of MR !11396

Merge branch 'backport-5490-clear-rndc-sign-on-error-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11409
2025-12-22 15:12:49 +00:00
Matthijs Mekking
aec7f3586e Clarify rndc sign
It was not explicitly clear that 'rndc sign' replaces signatures of
inactive keys and updates signatures that are not so fresh.

(cherry picked from commit 3f52303ef7)
2025-12-22 14:12:24 +00:00
Michał Kępień
7861d0264c [9.20] [CVE-2025-40778] sec: test: Add various bailiwick-related tests
Closes #5414

Backport of MR !11406

Merge branch 'backport-5414-add-various-bailiwick-related-tests-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11407
2025-12-22 13:42:18 +01:00
Petr Špaček
3fc64f1b5e Test that spoofed DNAME is not accepted via spoofable transport
A single spoofed DNAME answer can impact many names, and because of the
nature of DNAME, the attacker can use randomized query names to get
unlimited number of tries to spoof the answer.  To limit impact, we
should not be accepting DNAME over insecure transport, like UDP without
cookies etc.

In short, the attacker tries to spoof at least one answer that has the
following form:

    opcode QUERY
    rcode NOERROR
    flags QR AA
    ;QUESTION
    trigger$RANDOM.test. IN A
    ;ANSWER
    trigger$RANDOM.test. 3600 IN CNAME trigger$RANDOM.attacker.net.
    test. 3600 IN DNAME attacker.net.
    ;AUTHORITY
    ;ADDITIONAL

This has been discovered internally.

Co-authored-by: Michał Kępień <michal@isc.org>
(cherry picked from commit e223ee7097)
2025-12-22 11:47:26 +00:00
Petr Špaček
6b315c08eb Test that fake child delegation cannot overwrite parent's glue RR
In short, the attacker tries to spoof at least one answer that has the
following form:

    rcode NOERROR
    flags QR
    ;QUESTION
    trigger$RANDOM.victim. IN TXT
    ;ANSWER
    ;AUTHORITY
    trigger$RANDOM.victim. 3600 IN NS ns.victim.
    ;ADDITIONAL
    ns.victim. 3600 IN A 10.53.0.3

This attack was originally reported as "test case 2".

Co-authored-by: Michał Kępień <michal@isc.org>
(cherry picked from commit b5dc46fe6e)
2025-12-22 11:47:26 +00:00
Petr Špaček
ae0afc1d42 Test that unsolicited NS in positive answer cannot overwrite current NS
Before the fixes for CVE-2025-40778, an unsolicited in-bailiwick NS
record was accepted from a (spoofed) answer, enabling a single spoofed A
query/response to redirect traffic for a whole delegation.

In short, the attacker tries to spoof at least one answer that has the
following form:

    rcode NOERROR
    flags QR AA
    ;QUESTION
    trigger$RANDOM.victim. IN TXT
    ;ANSWER
    trigger$RANDOM.victim. 3600 IN TXT "spoofed answer with extra NS"
    ;AUTHORITY
    victim. 3600 IN NS ns.attacker.
    ;ADDITIONAL

This attack was originally reported as "test case 1".

Co-authored-by: Michał Kępień <michal@isc.org>
(cherry picked from commit 658d2e9f8e)
2025-12-22 11:47:26 +00:00
Petr Špaček
0a00d3c2c9 Test that positive answer cannot overwrite sibling NS RRs
Before the fixes for CVE-2025-40778, a positive answer was allowed to
overwrite sibling NS RRs.  The answer had to be a positive AA=1 answer
with a fake NS along with it.  This combination of conditions avoided
the code path with "unrelated <RRTYPE>" detection logic.

If it were some other answer, named from the main branch would detect
the attempt and log:

    DNS format error from 10.53.0.1#16386 resolving trigger/A for <unknown>: unrelated NS victim in trigger authority section

In short, the attacker tries to spoof at least one answer that has the
following form:

    opcode QUERY
    rcode NOERROR
    flags QR AA
    ;QUESTION
    trigger$RANDOM. IN A
    ;ANSWER
    trigger$RANDOM. 3600 IN A 10.53.0.3
    ;AUTHORITY
    victim. 3600 IN NS ns.attacker.
    ;ADDITIONAL
    ns.attacker. 3600 IN A 10.53.0.3

This attack was originally reported as "test case 1c".

Co-authored-by: Michał Kępień <michal@isc.org>
(cherry picked from commit 26eed16d61)
2025-12-22 11:47:26 +00:00
Petr Špaček
f5b5a94439 Add a common base for CVE-2025-40778 tests
Add the zone files, configuration, and code that will be reused by all
tests related to CVE-2025-40778.

Co-authored-by: Michał Kępień <michal@isc.org>
(cherry picked from commit 607974b1bc)
2025-12-22 11:47:26 +00:00
Michał Kępień
1a4c816344 Add a reusable, bare-bones AsyncDnsServer
Add bin/tests/system/ans.py, a bare-bones DNS server that can be used in
system tests instead of full-blown named instances when a server is only
required to return zone-based data.  Where applicable, this reduces load
on the test host and the amount of generated logs.

(cherry picked from commit 440e510f75)
2025-12-22 11:47:26 +00:00
Mark Andrews
1d0e19c612 [9.20] fix: usr: Reconfigure NSEC3 opt-out zone to NSEC causes zone to be invalid
A zone that is signed with NSEC3, opt-out enabled, and then reconfigured to use NSEC, causes the zone to be published with missing NSEC records. This has been fixed.

Closes #5679

Backport of MR !11359

Merge branch 'backport-5679-nsec3-optout-to-nsec-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11401
2025-12-22 16:09:08 +11:00
Matthijs Mekking
1b3fb1b966 Refactor code that checks if records are seen
There are three places that do roughly the same. Refactor the code to
a helper function.

(cherry picked from commit ae151a7a76)
2025-12-22 15:31:43 +11:00
Matthijs Mekking
07a4d63fd9 Add NSEC for opt-out names
When switching from NSEC3 opt-out to NSEC, add NSEC records if we saw an
RR. This corrects a mistake in style cleanups done in commit
308ab1b4a5.

(cherry picked from commit 6f285bff6a)
2025-12-22 15:31:43 +11:00
Matthijs Mekking
d3e74983bb Nit fix removing a newline in the logs
(cherry picked from commit 780e8e8f1c)
2025-12-22 15:31:42 +11:00
Matthijs Mekking
95187ee3de Update optout test to reconfig to NSEC
If we change from NSEC3 to NSEC we should not produce a zone with
missing NSEC records.

The code only considered having seen a record if there was previously
a signature present at the owner name. However with opt-out, insecure
delegations don't have a RRSIG record. Reconfiguring to NSEC causes
all insecure delegations to have a missing NSEC record.

Add a DNAME record to the test zone to also cover DNAME delegations.

(cherry picked from commit 3679bd4888)
2025-12-22 15:31:42 +11:00
Michał Kępień
596f1adbb4 [9.20] fix: test: AsyncServer: low-level fixes
Backport of MR !11398

Merge branch 'backport-michal/asyncserver-low-level-fixes-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11404
2025-12-21 08:26:33 +01:00
Michał Kępień
5ec598aec7 Prevent garbage-collecting ignored TCP connections
Due to the way various asyncio-related objects (tasks, streams,
transports, selectors) are referencing each other, pausing reads for a
TCP transport (which in practice means removing the client socket from
the set of descriptors monitored by a selector) can cause the client
task (AsyncDnsServer._handle_tcp()) to be prematurely garbage-collected,
causing asyncio code to raise a "Task was destroyed but it is pending!"
exception.  Who knew that solutions as elegant as the one introduced by
e407888507 could cause unexpected trouble?

Fix by making a horrible hack even more horrible, specifically by
keeping a reference to each incoming TCP connection to protect its
related asyncio objects from getting garbage-collected.  This prevents
AsyncDnsServer from closing any of the ignored TCP connections
indefinitely, which is obviously a pretty brain-dead idea for a
production-grade DNS server, but AsyncDnsServer was never meant to be
one and this hack reliably solves the problem at hand.

Only apply this change for the IgnoreAllConnections handler as the
ConnectionReset handler triggers a connection reset immediately after
pausing reads for an incoming TCP connection.

As pointed out in e407888507, the proper
solution would require implementing a custom asyncio transport from
scratch and that is still deemed to be too much work for the purpose at
hand.  Let's see how much longer we can limp along with the existing
approach.

(cherry picked from commit 1acde358ea)
2025-12-21 06:49:13 +00:00
Michał Kępień
f2b8863691 Make exception/signal handlers idempotent
Calling asyncio.Future.set_exception() or asyncio.Future.set_result()
more than once for a given Future object raises an
asyncio.InvalidStateError exception.

In the case of AsyncServer:

  - it is enough to capture the first exception raised by higher-level
    logic as no exceptions at all are expected to be raised in the first
    place,

  - no distinction is made between SIGINT and SIGTERM; the only purpose
    of the signal handler is to make the server exit cleanly.

Given the above, make both AsyncServer._handle_exception() and
AsyncServer._signal_done() idempotent by ignoring
asyncio.InvalidStateError exceptions raised by the relevant
asyncio.Future.set_*() calls.

(cherry picked from commit 0ec94e501a)
2025-12-21 06:49:13 +00:00
Michal Nowak
1ac8e80916 chg: test: Make pytest.PytestRemovedIn9Warning warning for "make check"
Merge branch 'mnowak/ignore-pytest-PytestRemovedIn9Warning-to-make-check' into 'bind-9.20'

See merge request isc-projects/bind9!11392
2025-12-18 18:41:03 +01:00
Michal Nowak
c10333a340
Make pytest.PytestRemovedIn9Warning warning for "make check" 2025-12-18 17:31:45 +01:00
Štěpán Balážik
932d742d65 [9.20] chg: test: Various isctest.asyncserver refactors
Several changes to the interface of isctest.asyncserver has been made
during the development of the rewrites, propagate these to all the others.

Others have become clear as well but have been deferred as multiple
rewrites have been in review at once.

Introduce all of these in this MR.

Backport of MR !11179

Merge branch 'backport-stepan/asyncserver-improvements-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11389
2025-12-18 13:28:44 +00:00
Štěpán Balážik
9199313a1b Use new AsyncDnsServer features in xfer system test
Use `prepare_new_response()`, `default_aa` and `default_rcode`.

(cherry picked from commit db212153d9)
2025-12-18 12:50:58 +00:00
Štěpán Balážik
59401a2917 Use new AsyncDnsServer features in cookie system test
Take advantage of `default_aa`, `default_rcode` and `keyring` arguments.

(cherry picked from commit f5f84a649b)
2025-12-18 12:50:58 +00:00
Štěpán Balážik
e92a7c9226 Allow ResponseHandlers to roll back changes made to a response
Previously, this was only possible by making a new response by calling
make_response on qctx.query. This however ignored the `default_aa` and
`default_rcode` parameters of AsyncDnsServer.

Add prepare_new_response and save_initialized_response methods to
QueryContext.

(cherry picked from commit 5384998ccd)
2025-12-18 12:50:57 +00:00
Štěpán Balážik
b323b517f1 Add TSIG keyring support to AsyncDnsServer
Previously, ResponseHandlers had to reparse the queries themselves if
they wanted to use TSIG. This led to `default_aa` and `default_rcode`
information being lost from the newly created messages.

Add support for TSIG keyrings to the AsyncDnsServer class directly.

(cherry picked from commit de266fff4c)
2025-12-18 12:50:57 +00:00
Štěpán Balážik
8f0406d5fb Remove dnspython<2.0.0 compatibility hacks from custom servers
isctest.asyncserver requires dnspython 2+ now.

(cherry picked from commit 8c2a72143c)
2025-12-18 12:50:57 +00:00
Štěpán Balážik
fa27b3df00 Import dnspython modules explicitly in custom servers
Previously, the server relied on the modules being imported by the
isctest.asyncserver module. This is fragile and confuses tooling.

Clean up stray imports in the process.

(cherry picked from commit 5761de5531)
2025-12-18 12:50:57 +00:00
Štěpán Balážik
05b53a0862 Allow adding multiple ResponseHandlers at once
Change this at call sites as well.

(cherry picked from commit d593af3a5f)
2025-12-18 12:50:57 +00:00
Štěpán Balážik
01c05fc461 Use default_rcode for AsyncDnsServer where applicable
Rule of thumb: If a RCode is set unconditionally in all
ResponseHandlers, set it in the server constructor.

(cherry picked from commit e4de7eb4f9)
2025-12-18 12:50:57 +00:00
Štěpán Balážik
a2b831eaea Set default_aa for AsyncDnsServer instances where suitable
Rule of thumb: If all ResponseHandlers said authoritative=True, it
should be default_aa=True instead.

(cherry picked from commit c7d84dc86a)
2025-12-18 12:50:57 +00:00
Štěpán Balážik
36193ee72b Allow users of AsyncDnsServer to set AA bit for all responses
Previously, all responses had to be set as authoritative explicitly
using DnsResponseSend(..., authoritative=True). After using this,
it became obvious that this is obnoxious.

Add an optional keyword-only parameter to AsyncDnsServer that sets the
default value of the AA bit on outgoing responses.

Make all the other parameters keyword-only as well.

(cherry picked from commit 6e684d44e0)
2025-12-18 12:50:57 +00:00
Štěpán Balážik
a2c444760d Refactor ControllableAsyncDnsServer setup
When this class was introduced, the constructor of its base class had no
parameters. This was changed in the meantime and these parameters were
not accessible by users of the subclass.

Don't override the constructor.
Move command setup to methods.
Move subclass-specific storage to cached properties.
Take instances of Command instead of the classes themselves for
symmetry with install_response_handler.

(cherry picked from commit a0970f3d04)
2025-12-18 12:50:57 +00:00
Andoni Duarte
5c897cca32 [9.20] new: ci: Add a tag pipeline CI job to update the stable tag after a release
Add a tag pipeline CI job to update the stable tag after a release.

Backport of MR !11291

Merge branch 'backport-andoni/add-ci-job-to-update-stable-tag-in-a-release-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11385
2025-12-18 08:59:25 +00:00
Andoni Duarte Pintado
c165e07f45 Add a tag pipeline CI job to update the stable tag after a release
Introduce a CI job to update the "stable" tag with the latest released
stable version tag. This is a manual job that only runs in tag
pipelines in the context of a release.

(cherry picked from commit 2bca6c0d5e)
2025-12-18 08:19:47 +00:00
Arаm Sаrgsyаn
911b45b2b3 [9.20] fix: usr: Fix a possible catalog zone issue during reconfiguration
The :iscman:`named` process could terminate unexpectedly during
reconfiguration when a catalog zone update was taking place at
the same time. This has been fixed.

Backport of MR !11366

Merge branch 'backport-aram/catz-reconfig-crash-fix-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11386
2025-12-17 17:49:27 +00:00
Aram Sargsyan
ee6e7e6d00 Lock the catalog zone when reconfiguring it
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)
2025-12-17 17:48:28 +00:00
Andoni Duarte
59946fce4c Merge tag 'v9.20.17' into bind-9.20 2025-12-17 15:33:14 +00:00
Ondřej Surý
9766feb4df [9.20] chg: usr: Add more information to the rndc recursing output about fetches
This adds more information about the active fetches for debugging and diagnostic purposes.

Backport of MR !11305

Merge branch 'backport-ondrej/provide-more-information-in-dns_resolver_dumpfetches-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11358
2025-12-17 11:59:18 +01:00
Ondřej Surý
038b3cd468 Add more information to the rndc recursing output about fetches
It is possible to have a fetch that is active, but it has been cloned,
so it won't be used when found in the hash table.   The fetch options
also prevent matching in the hash table, so add a hexadecimal dump of
the fctx->options to the output.

(cherry picked from commit 23ae5544be)
2025-12-17 11:59:11 +01:00
Michal Nowak
83660f0ebb [9.20] chg: test: Temporarily change pytest.PytestRemovedIn9Warning error to warning
We need this to be able to use pytest 9.0 from Debian "sid".

Additionally, this error needs to be addressed before pytest 9.1 is
released, as the filter will no longer work. Also, all pytests in CI
images need to be upgraded to version 7, where the new API is supported.

Related #5690

Backport of MR !11379

Merge branch 'backport-mnowak/ignore-pytest-PytestRemovedIn9Warning-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11380
2025-12-16 22:08:47 +01:00
Michal Nowak
e3ccabe636 Temporarily change pytest.PytestRemovedIn9Warning error to warning
We need this to be able to use pytest 9.0 from Debian "sid".

Additionally, this error needs to be addressed before pytest 9.1 is
released, as the filter will no longer work. Also, all pytests in CI
images need to be upgraded to version 7, where the new API is supported.

We can't have the "filterwarnings" section in pytest.ini directly as
only pytest 8.0 knows about it.

(cherry picked from commit 0c5d9c00ef)
2025-12-16 20:28:55 +00:00
Michal Nowak
2c45971ac4 [9.20] chg: ci: Add TSAN report and core file globs to expected artifacts
Backport of MR !11370

Merge branch 'backport-mnowak/add-tsan-reports-glob-to-expected-artifacts-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11371
2025-12-15 21:37:08 +01:00
Michal Nowak
30af909750 Add TSAN report and core file globs to expected artifacts
(cherry picked from commit ce23dd4dd3)
2025-12-15 19:28:32 +00:00
Evan Hunt
441158ac18 fix: usr: Allow glue in delegations with QTYPE=ANY
When a query for type ANY triggered a delegation response, all additional data was omitted from the response, including mandatory glue. This has been corrected.


Closes #5659

Merge branch '5659-any-glue' into 'bind-9.20'

See merge request isc-projects/bind9!11283
2025-12-11 19:57:27 +00:00
Mark Andrews
34f4833e61 Check delegation response to ANY query
Glue if present should be returned.
2025-12-11 10:36:09 -08:00
Evan Hunt
aa13e62355 allow glue in delegations with QTYPE=ANY
when a query for type ANY triggers a delegation response, all
additional data was omitted from the response, including
mandatory glue. this has been corrected.
2025-12-11 10:36:09 -08:00
Matthijs Mekking
88f915b77b [9.20] fix: usr: Fix slow speed of NSEC3 optout large delegation zone signing
BIND 9.20 takes much more time signing a large delegation zone with NSEC3 optout compared to version 9.18. This has been restored.

Closes #5672

Backport of MR !11354

Merge branch 'backport-5672-nsec3-optout-takes-too-long-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11362
2025-12-11 13:30:57 +00:00
Matthijs Mekking
64017871a8 Don't create NSEC3 nodes for unsigned delegations
Instead of creating new nodes for every possible NSEC3 record, only
create them if we are actually going to add a new NSEC3 record.

(cherry picked from commit 6f7abbfaac)
2025-12-11 13:53:25 +01:00
Matthijs Mekking
63262fd0f4 Implement dns_dbiterator_seek3
This is a new seek function for dbiterator that is meant to find an
NSEC3 node in a zone database. The difference with dns_dbiterator_seek
is that if the node does not exist, this seek function will point the
iterator to the next NSEC3 name.

(cherry picked from commit 41159e9062)
2025-12-11 13:53:25 +01:00
Matthijs Mekking
71c991d592 Add NSEC3 optout large delegation zone test case
This test signs a large delegation with mostly insecure delegations
with NSEC3 optout. Once the NSEC3PARAM record is published, run
dnssec-verify to ensure the zone is correctly signed.

(cherry picked from commit 5e704bbb59)
2025-12-11 13:53:25 +01:00
Andoni Duarte Pintado
00545e4375 Update BIND version for release 2025-12-11 12:28:49 +01:00