Commit graph

46164 commits

Author SHA1 Message Date
Alessio Podda
ace05a3cb8 Reproducer for #5977 cache poison NSEC piggyback
Create a new "nsec_piggyback" system test.

Co-Authored-By: Matthijs Mekking <matthijs@isc.org>
2026-07-08 11:50:09 +02:00
Evan Hunt
adb5c63e70 Don't synthesize negative responses with pending NSEC
If a cached record has not yet been validated and has trust
level pending, don't use it to synthesize negative responses.

Fixes: isc-projects/bind9#5872
Fixes: isc-projects/bind9#5887
Fixes: isc-projects/bind9#5977
2026-07-08 11:50:09 +02:00
Colin Vidal
dfefde8481 fix: dev: Detect UTF-16 surrogates in isc_utf8_valid()
UTF-8 standard forbid usage of unicode character between the range of
0xD800..0xDFFF (reserved, and used as UTF-16 surrogates, see RFC 3629).

However, `usc_utf8_valid()` was not checking if the encoded unicode
character was in this range, which then would accept invalid UTF-8
strings. This is now fixed.

Closes #6151

Merge branch '6151-utf16-surrogates-detection' into 'main'

See merge request isc-projects/bind9!12345
2026-07-08 11:03:52 +02:00
Colin Vidal
0249e64664 Add UTF-8 unit test
Add a unit test suite for `isc_utf8_valid()` function. It test the
varioutes encoding lower/upper ranges as well as UTF-16 surrogate
exclusion.

Also add unit tests for `usc_utf8_bom()` function.
2026-07-08 10:31:10 +02:00
Colin Vidal
ad5e8fee8d Detect UTF-16 surrogates in isc_utf8_valid()
UTF-8 standard forbid usage of unicode character between the range of
0xD800..0xDFFF (reserved, and used as UTF-16 surrogates, see RFC 3629).

However, `usc_utf8_valid()` was not checking if the encoded unicode
character was in this range, which then would accept invalid UTF-8
strings. This is now fixed.
2026-07-08 10:31:10 +02:00
Colin Vidal
094efe68e3 fix: dev: Remove ACL detach deadcode from dyndb
Since `188aa43e`, `dns_acl_any()` can't
fail (and thus would always set memory to its target). Removing deadcode
that would detach the ACL if `dns_acl_any()` would return some error
while the ACL would be created and attached.

Merge branch 'colin/remove-acl-detach-deadcode' into 'main'

See merge request isc-projects/bind9!12333
2026-07-08 08:02:53 +02:00
Colin Vidal
94aaf3cd6a Remove ACL detach deadcode from dyndb
Since `188aa43e48379572ffa758e45333c67214917d39`, `dns_acl_any()` can't
fail (and thus would always set memory to its target). Removing deadcode
that would detach the ACL if `dns_acl_any()` would return some error
while the ACL would be created and attached.
2026-07-08 08:02:44 +02:00
Ondřej Surý
1a2d276d3f chg: dev: Mark the related slabheader as visited on cache hit
A cache hit only marked the looked-up header as SIEVE-visited, leaving
its related header (the flattened counterpart) a candidate for eviction.
Mark both so related slabheaders age together.

Merge branch 'ondrej/mark-related-header-visited-on-cache-hit' into 'main'

See merge request isc-projects/bind9!12306
2026-07-07 16:28:42 +02:00
Ondřej Surý
6e646e664a
Mark the related slabheader as visited on cache hit
A cache hit only marked the looked-up header as SIEVE-visited, leaving
its related header (the flattened counterpart) a candidate for eviction.
Mark both so related slabheaders age together.
2026-07-07 16:28:14 +02:00
Arаm Sаrgsyаn
06413e5767 fix: dev: Include the IPv6 address's brackets in the parsed URL/URI host
The brackets are not included in the host component of the parsed
URL/URI. Change the parser to include the brackets.

Closes #6147

Merge branch '6147-isc_url_parse-ipv6-brackets-fix' into 'main'

See merge request isc-projects/bind9!12266
2026-07-07 12:19:26 +00:00
Aram Sargsyan
f85d9f5ef3 Include the brackets when parsing a URI with a IPv6 address
The brackets are not included in the host component of the parsed
URL/URI. Change the parser to include the brackets.
2026-07-07 11:23:16 +00:00
Arаm Sаrgsyаn
d960de55be fix: dev: Improve the input validation of the isc_url_parse() function
The isc_url_parse() function failed to check the input buffer's
length and assumed that it can't be bigger than UINT16_MAX, because
both the 'off' and 'len' fields of the 'isc_url_parser_t' structure
are uint16_t.

Add a check to not accept a buffer longer than 8192 octets.

Closes #6150

Merge branch '6150-isc_url_parse-buffer-size-check-fix' into 'main'

See merge request isc-projects/bind9!12252
2026-07-07 11:22:59 +00:00
Aram Sargsyan
efa8ca2267 Limit allowed URL/URI size to 8192 bytes in the parser
RFC 9110 Section 4.1 recommends at least 8000 octets, and 65535
is too excessive. Limit the maximum length to 8192 octets.
2026-07-07 10:08:04 +00:00
Ondřej Surý
874f34545f Add IPv6 and authority cases to the isc_url_t unit test
Cover IPv6 literal hosts (the brackets are stripped from the host, zone
identifiers are kept verbatim), userinfo, explicit ports and case
preservation, plus inputs that isc_url_parse() rejects although a generic
RFC 3986 parser would accept them: a '+' in the scheme, an IPvFuture
literal, and a percent-encoded port. The cases are drawn from the
Addressable URI test suite. The shared table runner is factored out so
both table-driven tests reuse it.

Assisted-by: Claude:claude-opus-4-8
2026-07-07 10:08:04 +00:00
Ondřej Surý
220a270930 Extend the isc_url_t unit test with RFC 3986 cases
Parse the absolute URIs from RFC 3986 section 5.4 and verify the
component split, and assert the input-length boundary (UINT16_MAX is
accepted, UINT16_MAX + 1 is rejected). isc_url_parse() splits request
targets but does not resolve relative references, so the dot-segments
in path/query/fragment are expected to survive verbatim.

Assisted-by: Claude:claude-opus-4-8
2026-07-07 10:08:04 +00:00
Aram Sargsyan
3bd33a817a Add a unit test for isc_url_t
The test has some basic checks for the URL/URI parser.
2026-07-07 10:08:04 +00:00
Aram Sargsyan
b878f82409 Add a maximum length for isc_url_parse() input buffer
The isc_url_parse() function failed to check the input buffer's
length and assumed that it can't be bigger than UINT16_MAX, because
both the 'off' and 'len' fields of the 'isc_url_parser_t' structure
are uint16_t.

Add a check to not accept a buffer longer than UINT16_MAX.
2026-07-07 10:08:04 +00:00
Arаm Sаrgsyаn
ee5763880a fix: dev: Fix PROXYv2 header size truncation bug
The 'isc_proxy2_handler_t' structure stores some size values in a
'uint16_t' type, while the maximum size can be bigger, which results
in truncation. Change the affected types to 'size_t'.

Closes #6142

Merge branch '6142-proxyv2-header-length-fix' into 'main'

See merge request isc-projects/bind9!12294
2026-07-07 10:07:45 +00:00
Aram Sargsyan
30e052bf47 Add new proxyheader unit tests
Check the maximum size and bigger than the maximum size headers.
2026-07-07 10:07:39 +00:00
Aram Sargsyan
0c6186870f Fix PROXYv2 header size truncation bug
The 'isc_proxy2_handler_t' structure stores some size values in a
'uint16_t' type, while the maximum size can be bigger, which results
in truncation. Change the affected types to 'size_t'.
2026-07-07 10:07:39 +00:00
Matthijs Mekking
de49e6cca1 new: test: Test multi-master dnssec-policy setup
Update the manual rollover system test with a multi-master setup.

Merge branch 'matthijs-test-dnssec-policy-multimaster' into 'main'

See merge request isc-projects/bind9!11268
2026-07-07 08:55:23 +00:00
Matthijs Mekking
affe84e55b Test multi-master dnssec-policy setup
Update the manual rollover test case with a multi-master setup.  In this
scenario, key files are generated, as well as rollovers are started
on one server (ns3) and key files are copied to the other server (ns4).

Add checks that the begin and end key states are the same.
2026-07-07 09:01:41 +02:00
Evan Hunt
d2350fc546 fix: usr: Unvalidated opt-out NSEC3 could be accepted in insecurity proof
When determining whether an insecure delegation is legitimate, NSEC3 opt-out records which had not yet passed validation could be used. This has been fixed.

Closes #5970

Merge branch '5970-pending-nsec3' into 'main'

See merge request isc-projects/bind9!12283
2026-07-03 07:01:30 +00:00
Evan Hunt
abd274c1fd Merge "nsec3_wrong_zone" into "dnssec_nsec3"
These tests are similar in structure and topic, and can be merged.
2026-07-02 23:07:26 -07:00
Alessio Podda
fdecacf07a Reproducer for #5970 acceptance of unvalidated NSEC3
Add "dnssec_nsec3" system test.

Co-Authored-By: Evan Hunt <each@isc.org>
2026-07-02 23:07:26 -07:00
Evan Hunt
1bd458d3ba Unvalidated opt-out NSEC3 could be accepted in insecurity proof
Ignore NSEC3 records that failed in the sub-validator when determining
whether an insecure delegation is legitimate.

Fixes: isc-projects/bind9#5970
2026-07-02 23:07:24 -07:00
Ondřej Surý
aefb8570a2 fix: usr: Fix DNSSEC validation failures for names under an apex DNAME
DNSSEC validation could fail with SERVFAIL for names covered by a DNAME
at the apex of a signed zone, unless the zone's keys were already validated
in the cache. This regression was introduced by the recent fix for resolver
stalls on CNAME responses to DS queries.

Closes #6176

Merge branch '6176-validator-apex-dname' into 'main'

See merge request isc-projects/bind9!12353
2026-07-02 16:47:22 +02:00
Ondřej Surý
38992e02bb Add a system test resolving through a signed apex DNAME
The dnssec system test signs a DNAME-at-apex zone but only ever
queried the apex directly; nothing resolved a name under the DNAME
through the validating resolver, so a validator regression on that
path went unnoticed.

Assisted-by: Claude:claude-fable-5
2026-07-02 16:47:14 +02:00
Ondřej Surý
057ae0adb8 Restrict the alias-chain deadlock check to chaining CNAMEs
check_deadlock() aborted any fetch whose name equals the owner of a
chaining rdataset, assuming nothing the validator needs can live at an
alias.  That is true for a CNAME, but a DNAME aliases only the names
below its owner: with a DNAME at a zone apex, the DNSKEY signing the
DNAME lives at the owner name itself, so every answer synthesized from
a signed apex DNAME failed validation whenever that key was not
already validated in the cache.

Chaining CNAMEs, including those synthesized from a DNAME, still cover
the self-join case the check was added for.
2026-07-02 16:47:14 +02:00
Nicki Křížek
c468f9abe1 fix: test: Support serving signed child zone from its parent's nameserver
When a signed zone is served by the same nameserver instance as
its parent, the child's dnssec-signzone has already written
dsset-<child>. into that directory. Don't attempt to copy the dsset if
the destination and source files are the same.

Assisted-by: Claude:claude-opus-4-8

Merge branch 'nicki/serve-signed-child-same-ns' into 'main'

See merge request isc-projects/bind9!12354
2026-07-02 16:42:15 +02:00
Nicki Křížek
246cca357b Support serving signed child zone from its parent's nameserver
When a signed zone is served by the same nameserver instance as
its parent, the child's dnssec-signzone has already written
dsset-<child>. into that directory. Don't attempt to copy the dsset if
the destination and source files are the same.

Assisted-by: Claude:claude-opus-4-8
2026-07-02 16:00:55 +02:00
Michał Kępień
8728b2a999 chg: test: Update AsyncDnsServer-related test cookbook parts
Add practical tips about specific handler classes.  Mention some good
practices and point developers at existing code written in the desired
manner.  Document common pitfalls.  Suggest preferred approaches for
splitting up complex response handling code.

Merge branch 'michal/update-asyncdnsserver-related-test-cookbook-parts' into 'main'

See merge request isc-projects/bind9!12260
2026-07-02 15:09:50 +02:00
Michał Kępień
edd765a092
Move ans.py-related information to README.md
COOKBOOK.md is supposed to be minimal and heavy on examples, so move the
lengthy section about implementing custom ans.py servers from
COOKBOOK.md to README.md.
2026-07-02 15:07:40 +02:00
Michał Kępień
a48e5cd98d
Update AsyncDnsServer-related test cookbook parts
Add practical tips about specific handler classes.  Mention some good
practices and point developers at existing code written in the desired
manner.  Document common pitfalls.  Suggest preferred approaches for
splitting up complex response handling code.
2026-07-02 15:07:40 +02:00
Nicki Křížek
cbc41caafa chg: test: Unify system test key and algorithm handling
This is a followup from https://gitlab.isc.org/isc-projects/bind9/-/merge_requests/11807.

De-duplicates the key material handling and moves algorithm-related things into a dedicated shared module.

Merge branch 'nicki/pytest-key-reconcile' into 'main'

See merge request isc-projects/bind9!12255
2026-07-02 14:51:52 +02:00
Nicki Křížek
4d76b7bd9e Move algorithm definitions into a top-level isctest.algorithms module
The Algorithm type, the per-algorithm constants, and the ALL_ALGORITHMS*
lookup tables are general DNSSEC key definitions used across isctest
package and the tests. Move them into a dedicated module to separate
these from the environment-specific setup that remains in
isctest.vars.algorithms.

Assisted-by: Claude:claude-opus-4-8
2026-07-02 14:51:41 +02:00
Nicki Křížek
ee73ba3bba Add private_key support to all ZoneKey implementations
Extend the ZoneKeyFile to read the file-backed private key and return it
in a format suitable for use with dnspython. Add ZoneKey.private_key
property to unify the interface.
2026-07-02 14:51:41 +02:00
Nicki Křížek
7f69a57021 Replace get_dnsalg() with kasp.Key.algorithm
The get_dnsalg() was just a compatibility layer for 9.18 which lacked
the Algorithm support - remove it in favor of using the .algorithm
property.

In order to properly support private OID algorithms, use the DST value
which is unique across all algorithms.

Also fix private_type_record(): the choice between the 5- and 7-byte
signing record depends on the DST value (256/257 for the private-OID
algorithms), not the on-wire number, which never reaches 256.

Assisted-by: Claude:claude-opus-4-8
2026-07-02 14:51:41 +02:00
Nicki Křížek
596e41553c Add NSEC3RSASHA1 to list of algorithms
This algorithm is deprecated and not currently used in our system tests,
but it should be in the list of all algorithms.
2026-07-02 14:51:41 +02:00
Nicki Křížek
55cd4a1e11 Move dnskey method from kasp.Key to zone.FileZoneKey
Code move with one change - switch dnskey TTL from 300s (DEFAULT_TTL) to
3600s (DNSKEY_TTL).

Assisted-by: Claude:claude-opus-4-8
2026-07-02 14:51:41 +02:00
Nicki Křížek
35fc5ce8b4 Merge kasp.Key functionality into zone.FileZoneKey
Make zone.FileZoneKey the single representation of a file-backed key
(typically generated by dnssec-keygen). Move the common key-related
functionality into zone.FileZoneKey, and extend that functionality in
kasp.Key to also add state and timing related operations on top. Remove
duplicate into_ta() function.

Note that is_ksk() is implemented differently for kasp.Key: with the
metadata file available, the KSK status is loaded from that file, as it
indicates the authoritative policy decision which makes the key a KSK.
In zone.FileZoneKey which doesn't work with the metadata file, the KSK
status if inferred from the DNSKEY SEP flag - the best information
available for that class.

Assisted-by: Claude:claude-opus-4-8
2026-07-02 14:51:41 +02:00
Nicki Křížek
9dc039f735 Read DNSKEY TTL from kasp.Key.dnskey
Remove the redundant ttl() method. The DNSKEY RR already provides the
TTL.
2026-07-02 14:51:41 +02:00
Ondřej Surý
2762fe12a0 chg: dev: Replace query and inner client attribute bitfields with named bools
Replace the unsigned int attributes field in struct ns_query and the unsigned int attributes field in struct ns_client_inner with individual bool bitfields.

Merge branch 'ondrej/query-attributes-to-bitfields' into 'main'

See merge request isc-projects/bind9!11732
2026-07-02 13:27:27 +02:00
Ondřej Surý
430ce335ad Replace query and client attribute bitfield with named bools
Replace the unsigned int attributes field in struct ns_query with
individual bool bitfields.  This removes the NS_QUERYATTR_* constants
and the 12 accessor macros (USECACHE, RECURSIONOK, RECURSING, etc.)
from query.c, replacing all bit manipulation with direct bool access.

And replace the unsigned int attributes field in struct ns_client_inner
with individual bool bitfields.  This removes the NS_CLIENTATTR_*
constants and the accessor macros (TCP, WANTDNSSEC, etc.), replacing
all bit manipulation with direct bool access.
2026-07-02 13:27:11 +02:00
Ondřej Surý
03c495def6 fix: usr: Resolver could terminate unexpectedly when processing a malformed RRSIG
A recursive resolver could terminate unexpectedly when an authoritative
server returned a crafted RRSIG(RRSIG) record for an insecure zone. Such
records are now rejected.

Closes #6184

Merge branch '6184-reject-rrsig-covering-signature' into 'main'

See merge request isc-projects/bind9!12347
2026-07-02 13:27:00 +02:00
Ondřej Surý
6c968be47d Add a regression test for an RRSIG that covers a signature
The qpcache_rrsig_any test enumerated only meta-types as the covered
type, so an RRSIG covering RRSIG -- a non-meta signature type -- slipped
through the earlier meta-type hardening. Probe that case too.

Assisted-by: Claude:claude-opus-4-8
2026-07-02 13:26:48 +02:00
Ondřej Surý
9596a03d21 Reject an RRSIG that covers a signature type
An RRSIG whose Type-Covered field is RRSIG is not a meta-type, so it
passed the message parser, and for an insecure domain the resolver
cached it as a standalone signature. The QP cache pairs every RRSIG
header with the non-signature header it covers and never expects the
covered type to itself be a signature, so a signature covering a
signature broke that invariant and aborted named on a crafted response.
Reject the record in the parser, and tighten the cache precondition so
a positive signature header must cover a non-signature type.
2026-07-02 13:26:48 +02:00
Ondřej Surý
f5e5097fad fix: dev: Correct locator decoding for NID, L64, and L32 records
NID, L64, and L32 records were decoded incorrectly when converted into their
parsed structures, because the preference field was not skipped before the
locator.

Closes #6097

Merge branch '6097-nid-l64-l32-tostruct-consume' into 'main'

See merge request isc-projects/bind9!12348
2026-07-02 12:54:52 +02:00
Ondřej Surý
f28bea94e3
Add NID/L64/L32 round-trip coverage to the rdata unit test
These types had no entries in the rdata test table, so the
tostruct/fromstruct round-trip in check_struct_conversions() never ran
against them -- which is why the missing preference consume in their
tostruct routines went unnoticed for years. Add text and wire vectors
for all three.

Assisted-by: Claude:claude-fable-5
2026-07-02 12:16:27 +02:00
Ondřej Surý
5aa279bbea
Consume the preference before reading the locator in NID/L64/L32 tostruct
tostruct_nid() and tostruct_l64() read the 16-bit preference with the
non-consuming uint16_fromregion() and then memmove()'d the whole
remaining region -- still ten octets, still anchored at the preference
-- into the eight-octet nid[]/l64[] arrays. That folded the preference
into the first two locator octets and stored two octets past the end of
the array. tostruct_l32() shares the root cause: it read the 32-bit
locator from the same unconsumed offset, so the value was built from the
preference plus the first two locator octets.

Consume the two preference octets first, matching the sibling
tostruct_lp(), and assert the expected framing on the fixed-size types.
2026-07-02 12:16:27 +02:00