Commit graph

43711 commits

Author SHA1 Message Date
Ondřej Surý
06a671a0ef [9.20] new: doc: Provide guidelines for tool-generated content
In the last few years, the capabilities of coding tools have exploded.
As those capabilities have expanded, contributors and maintainers have
more and more questions about how and when to apply those capabilities.

Add new documentation to guide contributors on how to best use BIND 9
development tools, new and old.

In short: Please show your work and make sure your contribution is
easy to review.

This has been adopted from the Linux Kernel guidelines.

Backport of MR !11447

Merge branch 'backport-ondrej/clarify-the-use-of-tools-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11581
2026-02-23 08:03:24 +01:00
Ondřej Surý
ab490f30c5 Provide guidelines for tool-generated content
In the last few years, the capabilities of coding tools have exploded.
As those capabilities have expanded, contributors and maintainers have
more and more questions about how and when to apply those capabilities.

Add new documentation to guide contributors on how to best use BIND 9
development tools, new and old.

In short: Please show your work and make sure your contribution is
easy to review.

This has been adopted from the Linux Kernel guidelines.

(cherry picked from commit 3fe2215afb)
2026-02-23 06:23:48 +00:00
Ondřej Surý
eb92622f8e [9.20] chg: doc: Add examples to the dig man page
Add a set of short examples at the end of the dig manual page to help new or infrequent users figure out the most basic ways to use dig.

Backport of MR !11577

Merge branch 'backport-examples-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11579
2026-02-22 18:19:59 +01:00
Julia Evans
ee0ae18a13 Add examples to the dig man page
The goal here is to help new or infrequent users figure out the most
basic ways to use dig.

Notes on the choice of examples:

* I wrote examples that users can copy and paste exactly as is, without
  having to come up with an appropriate IP address or domain name to use.
  The one exception is the `dig -x` example which uses an IP from the
  example range.
* `dig +noall +answer` here is because learning about `+noall +answer`
  was lifechanging for me when I learned about it, I've heard from
  others that they find it helpful too, and it's pretty hard to infer
  from the man page as is that it might be useful
* I thought about adding `+trace` but left it out because 5 examples was
  already starting to feel like a lot.

(cherry picked from commit 8972ed9424)
2026-02-22 16:21:13 +00:00
Ondřej Surý
c0c4bf526a [9.20] fix: usr: Fix read UAF in BIND9 dns_client_resolve() via DNAME Response
An attacker controlling a malicious DNS server returns a DNAME record,
and the we stores a pointer to resp->foundname, frees the response
structure, then uses the dangling pointer in dns_name_fullcompare()
possibly causing invalid match.  Only the `delv`is affected.  This has
been fixed.

Closes #5728

Backport of MR !11570

Merge branch 'backport-5728-heap-uaf-in-bind9-dns_client_resolve-via-dname-response-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11571
2026-02-20 19:18:35 +01:00
Ondřej Surý
6212830535 Fix read UAF in BIND9 dns_client_resolve() via DNAME Response
An attacker controlling a malicious DNS server returns a DNAME record,
and the we stores a pointer to resp->foundname, frees the response
structure, then uses the dangling pointer in dns_name_fullcompare()
possibly causing invalid match.  Only the `delv`is affected.  This has
been fixed.

(cherry picked from commit 9135b71a7a)
2026-02-20 19:18:30 +01:00
Ondřej Surý
892c3e7892 [9.20] fix: usr: fetch loop detection improvements
Fixes a case where an in-domain NS with an expired glue would fail to resolve.

Let's consider the following parent-side delegation (both for `foo.example.` and `dnshost.example.`

```
foo.example.            3600    NS      ns.dnshost.example.
dnshost.example.        3600    NS      ns.dnshost.example.
ns.dnshost.example.     3600    A       1.2.3.4
```
    
Then the child-side of `dnshost.example.`:

```    
dnshost.example.        300     NS      ns.dnshost.example.
ns.dnshost.example.     300     A       1.2.3.4
```
    
And then the child-side of `foo.example.`:

```
foo.example             3600    NS      ns.dnshost.example.
a.foo.example           300     A       5.6.7.8
```

While there is a zone misconfiguration (the TTL of the delegation and glue doesn't match in the parent and the child), it is possible to resolve `a.foo.example` on a cold-cache resolver. However, after the `ns.dnshost.example.` glue expires, the resolution would have failed with a "fetch loop detected" error. This is now fixed.

Closes #5588

Backport of MR !11535

Merge branch 'backport-5588-loopfetches-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11547
2026-02-20 19:17:12 +01:00
Colin Vidal
7d69ceb9e3 system test for the ADB fetch loop detection
Add a system test which implement the scenario described in the previous
commit "relaxes fetch loop detection".

(cherry picked from commit 4f8788310b)
2026-02-20 18:11:29 +01:00
Colin Vidal
60ae2c67e3 fetch loop detection improvements
The fetch loop detection occured in two places: when
`dns_resolver_createfetch()` is invoked (looking up through the parent
fetches chain and stops the fetch if a parent fetch is the same qname and
qtype) and right after calling `dns_adb_findname()` in the resolver
(stops the fetch if the current fetch is the same name from the ADB
lookup, and ADB lookup needs to fetch it).

Regarding fetch loop detection at the `dns_resulver_createfetch()`
entry, there are case where both qname and qtype are similar but the
zonecut is different. This will then query different name servers and
get different responses. For instance, the following delegation
parent-side (both for `foo.example.` and `dnshost.example.`):

	foo.example.		3600	NS	ns.dnshost.example.
	dnshost.example.	3600	NS	ns.dnshost.example.
	ns.dnshost.example.	3600	A	1.2.3.4

Then the child-side of `dnshost.example.`:

	dnshost.example.	300	NS	ns.dnshost.example.
	ns.dnshost.example.	300	A	1.2.3.4

Then the child-side of `foo.example.`:

	foo.example		3600	NS	ns.dnshost.example.
	a.foo.example		300	A	5.6.7.8

Obviously, there is a misconfiguration between the parent-side and the
child-side of `dnshost.example` (the mismatch of the TTL), but, this
happens...

Because the resolver is currently child-centric, the parent-side
delegation's glue of `dnshost.example.` will be overriden by the
child-side of the delegation. Once both A records will expires, the
resolver will attempt to find out the A RRs but will start from the
`foo.example.` zonecut, as the delegation itself is still valid.

Then the resolver will attempt to resolve `ns.dnshost.example.`, still
using the `foo.example.` zonecut, which will immediately trigger another
attempt to resolve `ns.foo.example.` (because the A RR is expired). This
is, however _not_ a loop, because the second attempt will have
`dnshost.example.` zonecut.  And this changes everything, because the
resolver detects the A name is in-domain, and pass a flag to ADB so
`dns_view_find()` won't use the cache. As a result, the zonecut will be
`.`, and the hints (root servers) will be queried instead.

From that point, they'll return the parent-side delegation, which
includes the glue for `ns.dnshost.example/A`, and the resolution can
continue. Previously, this wouldn't be possible because a loop would be
detected from the second attempt to looking `ns.foo.example/A` and would
result in a SERVFAIL.

Now, the loop detection is relaxed as the loop is detected if the qname,
qtype _and_ zonecut are equals.

This commit also changes the way the loop detection post
`dns_adb_createfind()` works. From the same example above, there would
be two ADB fetches with the same name, but with two different ADB flags
(the first one without DNS_ADB_STARTATZONE, the second one with that
flag). It means that there will be two fetches out of those two ADB
lookups, both legit, and not a loop (i.e. it won't be stuck). To
differenciate between a find which has a pending fetch (which could be
from another find the current find has been attached to), a new find
option `DNS_ADBFIND_STARTEDFETCH` is introduced, which tells that the
current has did started a fetch.

That way, if a find doesn't have `DNS_ADBFIND_STARTEDFETCH` option but
has pending fetches, we know this is a find attached to a similar find
so this is a loop. Otherwise, with `DNS_ADBFIND_STARTEDFETCH`, we know
that even if there is a pending fetch, this is not a loop as the fetch
has just been started

(cherry picked from commit f623ab1fb3)
2026-02-20 18:11:29 +01:00
Colin Vidal
ed184d8545 extends named -T so ADB settings can be tweaked
ADB entry window and ADB min cache time can be tweaked using `named -T
adbentrywindow=<unsigned int>` and `named -T adbmincache=<unsigned
int>`.

While those values doesn't needs to be exposed to the operator, this can
be needed to be able to system test ADB behaviors without having to wait
as long as those values are by default.

(cherry picked from commit e5f963262a)
2026-02-20 18:11:29 +01:00
Ondřej Surý
d4426f85b3 [9.20] chg: usr: Optimize the TCP source port selection on Linux
Enable a socket option on the outgoing TCP sockets to allow faster selection of the source <address,port> tuple for different destination <address,port> tuples when nearing over 70-80% of the source port utilization.

Backport of MR !11569

Merge branch 'backport-improve-selection-of-outgoing-TCP-port-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11573
2026-02-20 17:56:37 +01:00
Ondřej Surý
ae81ce723d
Rename isc_net_getudpportrange() to isc_net_getportrange()
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)
2026-02-20 17:02:45 +01:00
Ondřej Surý
bad1e4a665
Implement IP_LOCAL_PORT_RANGE socket option for Linux
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)
2026-02-20 17:02:45 +01:00
Ondřej Surý
a0e50c83de
Improve the source port selection on Linux
Since 2015, Linux has introduced a new socket option to overcome TCP
limitations: When an application needs to force a source IP on an active
TCP socket it has to use bind(IP, port=x).  As most applications do not
want to deal with already used ports, x is often set to 0, meaning the
kernel is in charge to find an available port.  But kernel does not know
yet if this socket is going to be a listener or be connected. This
IP_BIND_ADDRESS_NO_PORT socket option ask the kernel to ignore the 0
port provided by application in bind(IP, port=0) and only remember the
given IP address. The port will be automatically chosen at connect()
time, in a way that allows sharing a source port as long as the 4-tuples
are unique.

Enable IP_BIND_ADDRESS_NO_PORT on the outgoing TCP sockets to overcome
this TCP limitation.

(cherry picked from commit 2c48fcaeed)
2026-02-20 16:18:39 +01:00
Ondřej Surý
f93c565907
Remove return value from isc_net_getudpportrange()
The function was already marked as never failing, always returning
ISC_R_SUCCESS, so there was a lot of dead code around checking whether
the result would be ISC_R_SUCCESS.  This has been cleaned up.

(cherry picked from commit c3ec414d88)
2026-02-20 16:18:37 +01:00
Ondřej Surý
a123233319 [9.20] fix: usr: Fix errors when retrying over TCP in notify_send_toaddr
If the source address is not available do not attempt
to retry over TCP otherwise clear the TSIG key from the
message prior to retrying.

Closes #5457

Backport of MR !10805

Merge branch 'backport-5457-remove-tcp-retry-in-notify-send-toaddr-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11567
2026-02-20 12:43:16 +01:00
Mark Andrews
a6ca8407ee
Check notify with bad notify source address and tsig
named was asserting when the notify source address was not available
and TSIG was being used.  Check this scenario by adding a nameserver
to the zone which is configured to uses a non-existent source address
and a blackholed destination address and a TSIG using a server clause
for that destination address.

(cherry picked from commit f99d7f4217)
2026-02-20 10:50:19 +01:00
Ondřej Surý
9213c42bc0
Don't retry notify over TCP if it could not successed
Prevent retrying the notify over TCP in case the source address is not
available or the source vs the destination address family mismatch or
when the destination address has been blackholed.  Properly log the
hard notify failures.

(cherry picked from commit 5a5bc6de22)
2026-02-20 10:50:19 +01:00
Ondřej Surý
e68aa79e2a
Fix assertion failure when sending notify fails over UDP
When dns_request_create() fails in notify_send_toaddr() the TSIG key was
not cleared when retrying over TCP causing assertion failure.  Set the
TSIG key to NULL in the dns_message to prevent the assertion failure.

(cherry picked from commit ee3391a146)
2026-02-20 10:50:19 +01:00
Michał Kępień
5a5590da89 [9.20] fix: ci: Fix the update-stable-tag job
Fix the `update-stable-tag` job, necessary for updating Read the Docs.

Backport of MR !11559

Merge branch 'backport-andoni/fix-update-stable-branch-for-rtd-job-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11568
2026-02-20 09:55:02 +01:00
Andoni Duarte Pintado
61f81bffb0 Fix CI stable branch update job bug
The update script clones a fresh copy each time, if more than one
invocation is needed intermediate copies need to be removed.

(cherry picked from commit 81b71d5aa6)
2026-02-19 19:56:50 +00:00
Petr Špaček
d9eb13955c [9.20] chg: ci: cross-version-config-tests should hard fail again
Backport of MR !11560

Merge branch 'backport-reenable-cross-version-tests-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11561
2026-02-19 14:07:18 +00:00
Petr Špaček
f0b8cd47b6 Cross-version-config-tests should hard fail again
New tag was released so we can now re-enable check disabled in
093bef9211.

(cherry picked from commit ae657429f6)
2026-02-19 14:06:43 +00:00
Mark Andrews
8ac316bf0f [9.20] fix: dev: Return FORMERR for ECS family 0
RFC 7871 only defines family 1 (IPv4) and 2 (IPv6). Additionally
it requires FORMERR to be returned for all unknown families.

Backport of MR !11563

Merge branch 'backport-marka-formerr-family-0-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11565
2026-02-19 23:23:53 +11:00
Mark Andrews
32f802f4ed Return FORMERR for ECS family 0
RFC 7871 only defines family 1 (IPv4) and 2 (IPv6). Additionally
it requires FORMERR to be returned for all unknown families.

(cherry picked from commit 757e503536)
2026-02-19 22:42:26 +11:00
Matthijs Mekking
68ccf6ab4f [9.20] fix: doc: Minor documentation fixes for the 'rndc dnssec' command
List 'rndc dnssec' arguments in alphabetic order.
The `-step` argument was erroneously omitted from the usage output.

Closes #5731

Backport of MR !11529

Merge branch 'backport-5731-rndc-documentation-corrections-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11554
2026-02-18 14:20:58 +00:00
Matthijs Mekking
9101096e1e List 'rndc dnssec' arguments in alphabetic order
Same as rndc usage orderning,

(cherry picked from commit 4a22921936)
2026-02-18 14:20:53 +00:00
Matthijs Mekking
de04328ec7 Add rndc dnssec -step command to usage
The `-step` argument was erroneously omitted from the usage output.

(cherry picked from commit 0dd61d8773)
2026-02-18 14:20:53 +00:00
Petr Špaček
87a8d4fccc Merge tag 'v9.20.19' into bind-9.20 2026-02-18 10:33:06 +00:00
Mark Andrews
0a5922bcf7 [9.20] fix: usr: DNSTAP wasn't logging forwarded queries correctly
Closes #5724

Backport of MR !11509

Merge branch 'backport-5724-dnstap-forwarder-queries-logging-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11555
2026-02-17 15:09:24 +11:00
Mark Andrews
38ca02c7a0 Use shell function 'check_count' to check counts
(cherry picked from commit ea32141e48)
2026-02-17 03:32:47 +00:00
Mark Andrews
c59f66b6df Document UPDATE QUERY and UPDATE RESPONSE
(cherry picked from commit 24f85bc3f3)
2026-02-17 03:32:47 +00:00
Mark Andrews
b9ba70f9c1 Test forward query/response counts
(cherry picked from commit 591096f131)
2026-02-17 03:32:47 +00:00
Mark Andrews
99c189c772 Correctly identify forwarded queries with DNSTAP
Queries using forwarders where not being correctly identified
when using dnstap.

(cherry picked from commit 38b626d58d)
2026-02-17 03:32:47 +00:00
Mark Andrews
e8828fb2b1 Add missed ret!=0 checks
(cherry picked from commit 77278beaf3)
2026-02-17 03:32:47 +00:00
Michał Kępień
abc11cf63c [9.20] chg: test: Use isctest.asyncserver in the "pipelined" test
Replace the custom DNS server used in the "pipelined" system test with
new code based on the isctest.asyncserver module.

Backport of MR !11516

Merge branch 'backport-michal/pipelined-asyncserver-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11552
2026-02-13 15:40:29 +01:00
Michał Kępień
43eec494dd Use isctest.asyncserver in the "pipelined" test
Replace the custom DNS server used in the "pipelined" system test with
new code based on the isctest.asyncserver module.

(cherry picked from commit 3954025218)
2026-02-13 14:03:58 +00:00
Michał Kępień
5a0e1de2e5 Implement a response handler that forwards queries
Add a new response handler, ForwarderHandler, which enables forwarding
all queries to another DNS server.  To simplify implementation, always
forward queries to the target server via UDP, even if they are
originally received using a different transport protocol.

(cherry picked from commit 10a2fc7f1f)
2026-02-13 14:03:58 +00:00
Michał Kępień
f773a18f40 Log the server socket receiving each query
Extend AsyncDnsServer._log_query() and AsyncDnsServer._log_response() so
that they also log the <address, port> tuple for the socket on which a
given query was received on.  Minimize the signatures of those methods
by taking advantage of all the information contained in the QueryContext
instances passed to them.

(cherry picked from commit d3d9d166ed)
2026-02-13 14:03:58 +00:00
Michał Kępień
442285dce3 Store server socket information in QueryContext
Extend the QueryContext class with a field holding the <address, port>
tuple for the socket on which a given query was received.  This will
enable query handlers to act upon that information in arbitrary ways.

(cherry picked from commit 94a4793596)
2026-02-13 14:03:58 +00:00
Mark Andrews
66c58ce793 [9.20] fix: doc: Document that dig's query options are order sensitive
Closes #5730

Backport of MR !11526

Merge branch 'backport-5730-document-query-options-order-sensitive-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11542
2026-02-10 10:33:10 +11:00
Mark Andrews
5149e9abfa Document that query options are order sensitive
(cherry picked from commit 879d2ed480)
2026-02-09 22:47:15 +00:00
Michal Nowak
2cadea3ce1 [9.20] chg: test: Rewrite xfer system test to pytest
Backport of MR !11055

Merge branch 'backport-mnowak/pytest_rewrite_xfer-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11533
2026-02-06 21:04:11 +01:00
Michal Nowak
94a3861776 Rewrite xfer system test to pytest
(cherry picked from commit bf0df8b7f4)
2026-02-06 21:03:52 +01:00
Ondřej Surý
bfb55a587d [9.20] fix: nil: Release gnamebuf also on the error path
In dst_gssapi_acceptctx(), the gnamebuf could leak a little bit of
memory if dns_name_fromtext() would theoretically fail.  This would
require a Kerberos principal with invalid DNS name.

Closes #5737

Backport of MR !11536

Merge branch 'backport-5737-memory-leak-in-dst_gssapi_acceptctx-on-dns_name_fromtext-failure-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11537
2026-02-06 20:57:31 +01:00
Ondřej Surý
07877aa742
Release gnamebuf also on the error path
In dst_gssapi_acceptctx(), the gnamebuf could leak a little bit of
memory if dns_name_fromtext() would theoretically fail.  This would
require a Kerberos principal with invalid DNS name.

(cherry picked from commit 3ad87f1ad6)
2026-02-06 18:36:58 +01:00
Michał Kępień
f4fdcee03f [9.20] chg: usr: Record query time for all dnstap responses
Not all DNS responses had the query time set in their corresponding
dnstap messages. This has been fixed.

Closes #3695

Backport of MR !11527

Merge branch 'backport-3695-record-query-time-for-all-dnstap-responses-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11534
2026-02-06 16:57:06 +01:00
Mark Andrews
7931038fa8 Record query time for all dnstap responses
The description in the protobuf specification is not a list of request
types to process but rather a list of examples to qualify the
description of whether the time indicates when the message is received
or sent.

(cherry picked from commit 479c737517)
2026-02-06 14:40:59 +00:00
Nicki Křížek
2b00f34800 [9.20] fix: test: Allow re-run of kasp test case on all FreeBSDs
Closes #5720

Backport of MR !11507

Merge branch 'backport-5720-freebsd-kasp-test-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!11531
2026-02-06 15:37:30 +01:00
Nicki Křížek
aeb0518239 Allow re-run of kasp test case on all FreeBSDs
Previously, the issue when the kasp.test_kasp_case[secondary.kasp] fails
due to a timeout has been only ocassionally observed on FreeBSD 13
in our CI. It seems to have come back on FreeBSD 15.

(cherry picked from commit e4abb5bd07)
2026-02-06 13:20:03 +00:00