Merge tag 'v9.21.20'

This commit is contained in:
Michał Kępień 2026-03-25 14:23:41 +00:00
commit b0fc0e31c5
30 changed files with 1151 additions and 50 deletions

View file

@ -24,6 +24,8 @@
#include <sys/types.h>
#include <unistd.h>
#include <dns/acl.h>
#ifdef HAVE_DNSTAP
#include <fstrm.h>
#endif
@ -272,10 +274,10 @@ struct zonelistentry {
* asynchronously.
*/
typedef struct matching_view_ctx {
isc_netaddr_t *srcaddr;
isc_netaddr_t *destaddr;
isc_netaddr_t srcaddr;
isc_netaddr_t destaddr;
dns_message_t *message;
dns_aclenv_t *env;
dns_aclenv_t *aclenv;
ns_server_t *sctx;
isc_loop_t *loop;
isc_job_cb cb;
@ -9208,6 +9210,8 @@ get_matching_view_done(void *cbarg) {
mvctx->cb(mvctx->cbarg);
dns_aclenv_detach(&mvctx->aclenv);
if (mvctx->quota_result == ISC_R_SUCCESS) {
isc_quota_release(&mvctx->sctx->sig0checksquota);
}
@ -9249,10 +9253,10 @@ get_matching_view_continue(void *cbarg, isc_result_t result) {
tsig = dns_tsigkey_identity(mvctx->message->tsigkey);
}
if (dns_acl_allowed(mvctx->srcaddr, tsig, mvctx->view->matchclients,
mvctx->env) &&
dns_acl_allowed(mvctx->destaddr, tsig,
mvctx->view->matchdestinations, mvctx->env) &&
if (dns_acl_allowed(&mvctx->srcaddr, tsig, mvctx->view->matchclients,
mvctx->aclenv) &&
dns_acl_allowed(&mvctx->destaddr, tsig,
mvctx->view->matchdestinations, mvctx->aclenv) &&
!(mvctx->view->matchrecursiveonly &&
(mvctx->message->flags & DNS_MESSAGEFLAG_RD) == 0))
{
@ -9324,9 +9328,9 @@ get_matching_view(isc_netaddr_t *srcaddr, isc_netaddr_t *destaddr,
matching_view_ctx_t *mvctx = isc_mem_get(message->mctx, sizeof(*mvctx));
*mvctx = (matching_view_ctx_t){
.srcaddr = srcaddr,
.destaddr = destaddr,
.env = env,
.srcaddr = *srcaddr,
.destaddr = *destaddr,
.aclenv = dns_aclenv_ref(env),
.cb = cb,
.cbarg = cbarg,
.sigresult = sigresult,

View file

@ -0,0 +1,29 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
port @PORT@;
pid-file "named.pid";
listen-on { 10.53.0.1; };
listen-on-v6 { none; };
recursion no;
notify yes;
};
zone "." {
type primary;
file "root.db";
};

View file

@ -0,0 +1,24 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$TTL 300
. IN SOA . a.root.servers.nil. (
2000042100 ; serial
600 ; refresh
600 ; retry
1200 ; expire
600 ; minimum
)
. NS a.root-servers.nil.
a.root-servers.nil. A 10.53.0.1
excessive-nsec-rrsigs. NS ns2.excessive-nsec-rrsigs.
ns2.excessive-nsec-rrsigs. A 10.53.0.2

View file

@ -0,0 +1,24 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$TTL 300
@ IN SOA mname1. . (
1 ; serial
600 ; refresh
600 ; retry
1200 ; expire
600 ; minimum
)
@ NS ns2
ns2 A 10.53.0.2
* A 127.0.0.1

View file

@ -0,0 +1,29 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port @PORT@;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
notify yes;
};
zone "excessive-nsec-rrsigs" {
type primary;
file "excessive-nsec-rrsigs.db.signed";
};

View file

@ -0,0 +1,35 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
// validating resolver
options {
query-source address 10.53.0.3;
notify-source 10.53.0.3;
transfer-source 10.53.0.3;
port @PORT@;
pid-file "named.pid";
listen-on { 10.53.0.3; };
listen-on-v6 { none; };
recursion yes;
dnssec-validation yes;
max-records-per-type 2;
};
zone "." {
type hint;
file "../../_common/root.hint";
};
include "trusted.conf";

View file

@ -0,0 +1 @@
../../_common/trusted.conf.j2

View file

@ -0,0 +1,87 @@
#!/usr/bin/python3
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
import dns.rdataclass
import dns.rdatatype
import dns.rdtypes.ANY.RRSIG
import dns.zone
from isctest.run import EnvCmd
import isctest
def duplicate_rrsig(rdata, i):
return dns.rdtypes.ANY.RRSIG.RRSIG(
rdclass=rdata.rdclass,
rdtype=rdata.rdtype,
type_covered=rdata.type_covered,
algorithm=rdata.algorithm,
labels=rdata.labels,
# increment orig TTL so the rdataset isn't treated as identical record by dnspython
original_ttl=rdata.original_ttl + i,
expiration=rdata.expiration,
inception=rdata.inception,
key_tag=rdata.key_tag,
signer=rdata.signer,
signature=rdata.signature,
)
def bootstrap():
keygen = EnvCmd("KEYGEN", "-a ECDSA256 -Kns2 -q")
signer = EnvCmd("SIGNER", "-S -g")
zone = "excessive-nsec-rrsigs"
infile = f"{zone}.db.in"
signedfile = f"{zone}.db.signed"
isctest.log.info(f"{zone}: generate ksk and zsk")
ksk_name = keygen(f"-f KSK {zone}").out.strip()
keygen(f"{zone}").out.strip()
ksk = isctest.kasp.Key(ksk_name, keydir="ns2")
isctest.log.info(f"{zone}: sign zone")
signer(f"-P -x -O full -o {zone} -f {signedfile} {infile}", cwd="ns2")
isctest.log.info(
f"{zone}: duplicate the RRSIG(NSEC) to exceed max-records-per-type"
)
zone = dns.zone.from_file(f"ns2/{signedfile}", origin=zone)
for node in zone.values():
rrsig_rdataset = node.find_rdataset(
dns.rdataclass.IN, dns.rdatatype.RRSIG, dns.rdatatype.NSEC
)
orig = rrsig_rdataset[0]
rrsig_rdataset.add(duplicate_rrsig(orig, 1))
rrsig_rdataset.add(duplicate_rrsig(orig, 2))
zone.to_file(f"ns2/{signedfile}", sorted=True)
return {
"trust_anchors": [
ksk.into_ta("static-key"),
],
}
# reproducer for CVE-2026-3104 [GL#5742]
def test_excessive_rrsigs(ns3):
# the real test is that there is no crash on shutdown - checked by the test
# framework when the test finishes
# multiple queries seem more reliable to reproduce the memory leak, using a
# single query sometimes didn't cause a crash on shutdown
for i in range(10):
msg = isctest.query.create(f"x{i}.excessive-nsec-rrsigs", "A")
res = isctest.query.udp(msg, ns3.ip, attempts=1)
isctest.check.servfail(res)

View file

@ -0,0 +1,35 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
port @PORT@;
pid-file "named.pid";
listen-on { 10.53.0.1; };
listen-on-v6 { none; };
recursion no;
dnssec-validation no;
};
controls {
inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
include "../../_common/rndc.key";
zone "." {
type primary;
file "root.db";
};

View file

@ -0,0 +1,25 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$TTL 300
. IN SOA . . (
2025063000 ; serial
600 ; refresh
600 ; retry
1200 ; expire
600 ; minimum
)
. NS a.root-servers.nil.
a.root-servers.nil A 10.53.0.1
iter-too-many. NS ns2.iter-too-many.
ns2.iter-too-many. A 10.53.0.2

View file

@ -0,0 +1,31 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
{% raw %}
$TTL 300
@ IN SOA ns2.iter-too-many. hostmaster.iter-too-many. (
2026020300 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
@ IN NS ns2.iter-too-many.
ns2 IN A 10.53.0.2
sub IN NS ns2.sub.iter-too-many.
ns2.sub IN A 10.53.0.2
{% endraw %}
{% for dnskey in dnskeys %}
@dnskey@
{% endfor %}

View file

@ -0,0 +1,40 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
options {
query-source address 10.53.0.2;
notify-source 10.53.0.2;
transfer-source 10.53.0.2;
port @PORT@;
pid-file "named.pid";
listen-on { 10.53.0.2; };
listen-on-v6 { none; };
recursion no;
dnssec-validation no;
};
controls {
inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
include "../../_common/rndc.key";
zone "iter-too-many" {
type primary;
file "iter-too-many.signed.db";
};
zone "sub.iter-too-many" {
type primary;
file "sub.iter-too-many.db";
};

View file

@ -0,0 +1,24 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$TTL 300
@ IN SOA ns2.sub.iter-too-many. hostmaster.sub.iter-too-many. (
2026020300 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
@ IN NS ns2.sub.iter-too-many.
ns2 IN A 10.53.0.2
example IN A 127.0.0.1

View file

@ -0,0 +1,37 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
options {
query-source address 10.53.0.3;
notify-source 10.53.0.3;
transfer-source 10.53.0.3;
port @PORT@;
pid-file "named.pid";
listen-on { 10.53.0.3; };
listen-on-v6 { none; };
recursion yes;
dnssec-validation yes;
};
controls {
inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
include "../../_common/rndc.key";
zone "." {
type hint;
file "../../_common/root.hint";
};
include "trusted.conf";

View file

@ -0,0 +1 @@
../../_common/trusted.conf.j2

View file

@ -0,0 +1,61 @@
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
from isctest.run import EnvCmd
import isctest
def bootstrap():
templates = isctest.template.TemplateEngine(".")
keygen = EnvCmd("KEYGEN", "-a ECDSA256")
signer = EnvCmd("SIGNER")
isctest.log.info("setup iter-too-many.")
zonename = "iter-too-many."
ksk_name = keygen(f"-f KSK {zonename}", cwd="ns2").out.strip()
zsk_name = keygen(f"{zonename}", cwd="ns2").out.strip()
ksk = isctest.kasp.Key(ksk_name, keydir="ns2")
zsk = isctest.kasp.Key(zsk_name, keydir="ns2")
dnskeys = [ksk.dnskey, zsk.dnskey]
tdata = {
"dnskeys": dnskeys,
}
templates.render(f"ns2/{zonename}db", tdata, template=f"ns2/{zonename}db.j2.manual")
signer(
f"-P -o {zonename} -f {zonename}signed.db -3 A1B2C3D4 -H too-many -H 51 -S {zonename}db",
cwd="ns2",
)
return {
"trust_anchors": [
ksk.into_ta("static-key"),
],
}
def test_excessive_nsec3_iterations_delegation(ns3):
# reproducer for CVE-2026-1519 [GL#5708]
zone = "example.sub.iter-too-many"
msg = isctest.query.create(zone, "A")
res = isctest.query.tcp(msg, ns3.ip)
# an insecure response is expected regardless of the NSEC3 iteration limit,
# because the sub.iter-too-many. zone is unsigned. the real difference is
# in the CPU usage required for generating such response, but that can't be
# easily and reliably tested in an automated fashion
isctest.check.noerror(res)
with ns3.watch_log_from_start() as watcher:
watcher.wait_for_line(
f"validating {zone}/A: validator_callback_ds: too many iterations"
)

View file

@ -0,0 +1,41 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
port @PORT@;
pid-file "named.pid";
listen-on { 10.53.0.1; };
listen-on-v6 { none; };
recursion no;
notify no;
};
key rndc_key {
secret "1234abcd8765";
algorithm @DEFAULT_HMAC@;
};
controls {
inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
view "v1" {
match-clients { any; };
zone "." {
type hint;
file "/dev/null";
};
};

View file

@ -0,0 +1,17 @@
#!/bin/sh -e
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
# shellcheck source=conf.sh
. ../conf.sh
key=$($KEYGEN -q -a RSASHA256 -b 2048 sig0.)

View file

@ -0,0 +1,119 @@
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
import base64
import glob
import os
import struct
import time
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding, rsa
import dns.flags
import dns.message
import dns.name
import dns.rdata
import dns.rdataclass
import dns.rdatatype
import dns.renderer
import dns.rrset
import isctest
def load_bind_private_key(filename):
"""Parses a BIND 9 .private key file."""
with open(filename, "r", encoding="utf-8") as f:
lines = f.readlines()
data = {}
for line in lines:
if ":" in line:
key, value = line.split(":", 1)
data[key.strip()] = value.strip()
def b64int(k):
return int.from_bytes(base64.b64decode(data[k]), byteorder="big")
rsa_key = rsa.RSAPrivateNumbers(
p=b64int("Prime1"),
q=b64int("Prime2"),
d=b64int("PrivateExponent"),
dmp1=b64int("Exponent1"),
dmq1=b64int("Exponent2"),
iqmp=b64int("Coefficient"),
public_numbers=rsa.RSAPublicNumbers(
e=b64int("PublicExponent"), n=b64int("Modulus")
),
).private_key(default_backend())
return rsa_key
def make_sig0_query(key_file, key_name_str):
private_key = load_bind_private_key(key_file)
qname = dns.name.from_text(".")
query = dns.message.make_query(qname, dns.rdatatype.SOA)
query.flags |= dns.flags.RD
# Render message to bytes (needed for signing)
renderer = dns.renderer.Renderer()
query.to_wire(renderer)
msg_bytes = renderer.get_wire()
# SIG(0) Constants
basename = os.path.basename(key_file)
key_tag = int(basename.split("+")[2].split(".")[0])
now = int(time.time())
expiration = now + 3600
inception = now - 3600
signer_name = dns.name.from_text(key_name_str)
# Construct SIG RDATA header (0=SIG(0), 8=RSASHA256, 0=Labels)
sig_rdata_header = struct.pack(
"!HBBIIIH", 0, 8, 0, 0, expiration, inception, key_tag
)
sig_rdata_pre_sig = sig_rdata_header + signer_name.to_wire()
# Sign: ( SIG RDATA sans signature ) + ( Message )
signature = private_key.sign(
sig_rdata_pre_sig + msg_bytes, padding.PKCS1v15(), hashes.SHA256()
)
# Create the SIG RR
full_sig_rdata = sig_rdata_pre_sig + signature
sig_rr = dns.rdata.from_wire(
dns.rdataclass.ANY,
dns.rdatatype.SIG,
full_sig_rdata,
0,
len(full_sig_rdata),
)
sig_rrset = dns.rrset.from_rdata(qname, 0, sig_rr)
query.additional.append(sig_rrset)
return query
def test_sig0_acl_bypass():
key_files = glob.glob("Ksig0.+*.private")
assert len(key_files) == 1
query = make_sig0_query(key_files[0], "sig0.")
# Send the query
res = isctest.query.tcp(query, "10.53.0.1")
isctest.check.servfail(res)

View file

@ -0,0 +1,23 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$ORIGIN .
$TTL 300 ; 5 minutes
example.nil IN SOA ns1.example.nil. hostmaster.example.nil. (
1 ; serial
2000 ; refresh (2000 seconds)
2000 ; retry (2000 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
example.nil. NS ns1.example.nil.
ns1.example.nil. A 10.53.0.1
a.example.nil. A 10.53.0.1

View file

@ -0,0 +1,35 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
options {
query-source address 10.53.0.1;
notify-source 10.53.0.1;
transfer-source 10.53.0.1;
port @PORT@;
pid-file "named.pid";
listen-on { 10.53.0.1; };
listen-on-v6 { none; };
recursion no;
dnssec-validation no;
notify no;
};
key "test-key" {
algorithm "hmac-sha256";
secret "R16NojROxtxH/xbDl//ehDsHm5DjWTQ2YXV+hGC2iBY=";
};
zone "example.nil" {
type primary;
file "example.db";
};

View file

@ -0,0 +1,62 @@
#!/usr/bin/python3
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
# pylint: disable=unused-variable
import time
import dns.message
import dns.rdataclass
import dns.rdatatype
import dns.rdtypes.ANY.TKEY
import dns.rrset
import dns.tsigkeyring
import pytest
import isctest
pytestmark = pytest.mark.extra_artifacts([])
def create_tkey_msg(qname, mode, alg="hmac-sha256"):
msg = dns.message.make_query(qname, "TKEY")
now = int(time.time())
rdata = dns.rdtypes.ANY.TKEY.TKEY(
rdclass=dns.rdataclass.ANY,
rdtype=dns.rdatatype.TKEY,
algorithm=alg,
inception=now - 3600,
expiration=now + 86400,
mode=mode,
error=0,
key=b"",
)
rrset = dns.rrset.from_rdata(qname, dns.rdatatype.TKEY, rdata)
msg.additional.append(rrset)
return msg
def test_tkey_cve_2026_3119(ns1):
keyring = dns.tsigkeyring.from_text(
{
"test-key": "R16NojROxtxH/xbDl//ehDsHm5DjWTQ2YXV+hGC2iBY=",
}
)
msg_delete = create_tkey_msg("a.example.nil.", 5)
msg_delete.use_tsig(keyring, keyname="test-key")
isctest.query.tcp(msg_delete, ns1.ip, attempts=1)
msg_unsupported = create_tkey_msg("a.example.nil.", 99)
msg_unsupported.use_tsig(keyring, keyname="test-key")
isctest.query.tcp(msg_unsupported, ns1.ip, attempts=1)

View file

@ -18,6 +18,7 @@ Changelog
development. Regular users should refer to :ref:`Release Notes <relnotes>`
for changes relevant to them.
.. include:: ../changelog/changelog-9.21.20.rst
.. include:: ../changelog/changelog-9.21.19.rst
.. include:: ../changelog/changelog-9.21.18.rst
.. include:: ../changelog/changelog-9.21.17.rst

View file

@ -47,6 +47,7 @@ The list of known issues affecting the latest version in the 9.21 branch can be
found at
https://gitlab.isc.org/isc-projects/bind9/-/wikis/Known-Issues-in-BIND-9.21
.. include:: ../notes/notes-9.21.20.rst
.. include:: ../notes/notes-9.21.19.rst
.. include:: ../notes/notes-9.21.18.rst
.. include:: ../notes/notes-9.21.17.rst

View file

@ -0,0 +1,137 @@
.. Copyright (C) Internet Systems Consortium, Inc. ("ISC")
..
.. SPDX-License-Identifier: MPL-2.0
..
.. This Source Code Form is subject to the terms of the Mozilla Public
.. License, v. 2.0. If a copy of the MPL was not distributed with this
.. file, you can obtain one at https://mozilla.org/MPL/2.0/.
..
.. See the COPYRIGHT file distributed with this work for additional
.. information regarding copyright ownership.
BIND 9.21.20
------------
Security Fixes
~~~~~~~~~~~~~~
- [CVE-2026-1519] Fix unbounded NSEC3 iterations when validating
referrals to unsigned delegations. ``779463a703e``
DNSSEC-signed zones may contain high iteration-count NSEC3 records,
which prove that certain delegations are insecure. Previously, a
validating resolver encountering such a delegation processed these
iterations up to the number given, which could be a maximum of 65,535.
This has been addressed by introducing a processing limit, set at 50.
Now, if such an NSEC3 record is encountered, the delegation will be
treated as insecure.
ISC would like to thank Samy Medjahed/Ap4sh for bringing this
vulnerability to our attention. :gl:`#5708`
- [CVE-2026-3104] Fix memory leaks in code preparing DNSSEC proofs of
non-existence. ``5e29b24dcd0``
An attacker controlling a DNSSEC-signed zone could trigger a memory
leak in the logic preparing DNSSEC proofs of non-existence, by
creating more than :any:`max-records-per-type` RRSIGs for NSEC
records. These memory leaks have been fixed.
ISC would like to thank Vitaly Simonovich for bringing this
vulnerability to our attention. :gl:`#5742`
- [CVE-2026-3119] Prevent a crash in code processing queries containing
a TKEY record. ``adbe0358089``
The :iscman:`named` process could terminate unexpectedly when
processing a correctly signed query containing a TKEY record. This has
been fixed.
ISC would like to thank Vitaly Simonovich for bringing this
vulnerability to our attention. :gl:`#5748`
- [CVE-2026-3591] Fix a stack use-after-return flaw in SIG(0) handling
code. ``c64392c731b``
A stack use-after-return flaw in SIG(0) handling code could enable ACL
bypass and/or assertion failures in certain circumstances. This flaw
has been fixed.
ISC would like to thank Mcsky23 for bringing this vulnerability to our
attention. :gl:`#5754`
New Features
~~~~~~~~~~~~
- Provide response round-trip time (RTT) counters via statistics
channel. ``e7b1a44b8c5``
Previously, :iscman:`named` provided RTT counters for outgoing queries
performed by itself during name resolutions. Now this has been
improved to provide more granular counters (histogram), and to also
provide RTT counters for the incoming queries. :gl:`#5279`
:gl:`!11508`
Feature Changes
~~~~~~~~~~~~~~~
- Introduce max-delegation-servers configuration option. ``d2cb28d43ee``
Make the maximum number of processed delegation nameservers
configurable via the new 'max-delegation-servers' option (default:
13), replacing the hardcoded NS_PROCESSING_LIMIT (20).
The default is reduced to 13 to precisely match the maximum number of
root servers that can fit into a classic 512-byte UDP payload. This
provides a natural, historically sound cap that mitigates resource
exhaustion and amplification attacks from artificially inflated or
misconfigured delegations.
The configuration option is strictly bounded between 1 and 100 to
ensure resolver stability. :gl:`!11607`
- Replace lock keyfile hashmap with lock pool. ``4fd84193c73``
Kasp used a lock per zone origin in order to prevent concurrent access
to keyfiles. This lead to substantial memory consumption in the case
of authoritative servers with many small zones, as lots of locks need
to be allocated.
Since the number of keyfile locks taken cannot exceed the number of
helper threads, it makes more sense to use a lock pool of fixed size
keyed by the hash of the origin name, leading to memory savings.
:gl:`!11633`
Bug Fixes
~~~~~~~~~
- Fix setting retire in dns_keymgr_key_init. ``a6701c37b98``
A wrong-variable bug in `dns_keymgr_key_init()` causes the DNSSEC key
inactive time to never be read. This means the key state is retracting
zone signatures where it should have, delaying the key rollover.
ISC would like to thank Naresh Kandula Parmar (Nottiboy) for reporting
this. :gl:`#5774` :gl:`!11624`
- Fix resquery reference imbalance on TCP connect failure.
``7c82cb0f14e``
In fctx_query(), resquery_ref(query) is called before
dns_dispatch_connect() in anticipation of the resquery_connected()
callback consuming the reference. When dns_dispatch_connect() fails
synchronously on TCP (e.g. from dns_transport_get_tlsctx() failing in
tcp_dispatch_connect()), the connect callback is never scheduled, so
the extra reference is never consumed. This has been fixed.
:gl:`!11640`
- Resolve "key defined in view is not found" ``0d5f47e3ec2``
A recent change in `2956e4fc45b3c2142a3351682d4200647448f193` hardened
the `key` name check when used in `primaries` to immediately reject
the configuration if the key was not defined (rather than only
checking whether the key name was correctly formed). However, the
change introduced a regression that prevented the use of a `key`
defined in a view. This is now fixed. :gl:`!11588`

108
doc/notes/notes-9.21.20.rst Normal file
View file

@ -0,0 +1,108 @@
.. Copyright (C) Internet Systems Consortium, Inc. ("ISC")
..
.. SPDX-License-Identifier: MPL-2.0
..
.. This Source Code Form is subject to the terms of the Mozilla Public
.. License, v. 2.0. If a copy of the MPL was not distributed with this
.. file, you can obtain one at https://mozilla.org/MPL/2.0/.
..
.. See the COPYRIGHT file distributed with this work for additional
.. information regarding copyright ownership.
Notes for BIND 9.21.20
----------------------
Security Fixes
~~~~~~~~~~~~~~
- Fix unbounded NSEC3 iterations when validating referrals to unsigned
delegations. :cve:`2026-1519`
DNSSEC-signed zones may contain high iteration-count NSEC3 records,
which prove that certain delegations are insecure. Previously, a
validating resolver encountering such a delegation processed these
iterations up to the number given, which could be a maximum of 65,535.
This has been addressed by introducing a processing limit, set at 50.
Now, if such an NSEC3 record is encountered, the delegation will be
treated as insecure.
ISC would like to thank Samy Medjahed/Ap4sh for bringing this
vulnerability to our attention. :gl:`#5708`
- Fix memory leaks in code preparing DNSSEC proofs of non-existence.
:cve:`2026-3104`
An attacker controlling a DNSSEC-signed zone could trigger a memory
leak in the logic preparing DNSSEC proofs of non-existence, by
creating more than :any:`max-records-per-type` RRSIGs for NSEC
records. These memory leaks have been fixed.
ISC would like to thank Vitaly Simonovich for bringing this
vulnerability to our attention. :gl:`#5742`
- Prevent a crash in code processing queries containing a TKEY record.
:cve:`2026-3119`
The :iscman:`named` process could terminate unexpectedly when
processing a correctly signed query containing a TKEY record. This has
been fixed.
ISC would like to thank Vitaly Simonovich for bringing this
vulnerability to our attention. :gl:`#5748`
- Fix a stack use-after-return flaw in SIG(0) handling code.
:cve:`2026-3591`
A stack use-after-return flaw in SIG(0) handling code could enable ACL
bypass and/or assertion failures in certain circumstances. This flaw
has been fixed.
ISC would like to thank Mcsky23 for bringing this vulnerability to our
attention. :gl:`#5754`
New Features
~~~~~~~~~~~~
- Provide response round-trip time (RTT) counters via statistics
channel.
Previously, :iscman:`named` provided RTT counters for outgoing queries
that it performed during name resolutions. This has now been improved
to provide more granular counters (histogram), and to also provide RTT
counters for the incoming queries. :gl:`#5279`
- Introduce :any:`max-delegation-servers` configuration option.
Make the maximum number of processed delegation nameservers
configurable via the new :any:`max-delegation-servers` option
(default: 13), replacing the hardcoded ``NS_PROCESSING_LIMIT`` (20).
The default is reduced to 13 to precisely match the maximum number of
root servers that can fit into a classic 512-byte UDP payload. This
provides a natural, historically sound cap that mitigates resource
exhaustion and amplification attacks from artificially inflated or
misconfigured delegations.
The configuration option is strictly bounded between 1 and 100 to
ensure resolver stability. :gl:`!11607`
Bug Fixes
~~~~~~~~~
- Fix parsing key inactivation time in KASP code.
A wrong-variable bug in KASP code caused the DNSSEC key inactivation
time to never be read. As a result, zone signatures were being
retracted later than they should be, which caused unnecessary key
rollover delays. This has now been fixed. :gl:`#5774`
- Fix the handling of :namedconf:ref:`key` statements defined inside
views.
A recent change introduced in BIND 9.21.16 hardened the
:namedconf:ref:`key` name check when used in :any:`primaries`, to
immediately reject the configuration if the key was not defined
(rather than only checking whether the key name was correctly formed).
However, that change introduced a regression that prevented the use of
a :namedconf:ref:`key` defined in a view. This has now been fixed.
:gl:`#5761`

View file

@ -384,6 +384,7 @@ enum {
((x) == dns_trust_additional || (x) == dns_trust_pending_additional)
#define DNS_TRUST_GLUE(x) ((x) == dns_trust_glue)
#define DNS_TRUST_ANSWER(x) ((x) == dns_trust_answer)
#define DNS_TRUST_SECURE(x) ((x) >= dns_trust_secure)
/*%
* Name checking severities.

View file

@ -2981,7 +2981,7 @@ addnoqname(isc_mem_t *mctx, dns_slabheader_t *newheader, uint32_t maxrrperset,
dns_slabheader_proof_t *noqname = NULL;
dns_name_t name = DNS_NAME_INITEMPTY;
dns_rdataset_t neg = DNS_RDATASET_INIT, negsig = DNS_RDATASET_INIT;
isc_region_t r1, r2;
isc_region_t r1 = { .base = NULL }, r2 = { .base = NULL };
result = dns_rdataset_getnoqname(rdataset, &name, &neg, &negsig);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
@ -3001,6 +3001,14 @@ addnoqname(isc_mem_t *mctx, dns_slabheader_t *newheader, uint32_t maxrrperset,
newheader->noqname = noqname;
cleanup:
if (result != ISC_R_SUCCESS) {
if (r1.base != NULL) {
isc_mem_put(mctx, r1.base, r1.length);
}
if (r2.base != NULL) {
isc_mem_put(mctx, r2.base, r2.length);
}
}
dns_rdataset_disassociate(&neg);
dns_rdataset_disassociate(&negsig);
@ -3014,7 +3022,7 @@ addclosest(isc_mem_t *mctx, dns_slabheader_t *newheader, uint32_t maxrrperset,
dns_slabheader_proof_t *closest = NULL;
dns_name_t name = DNS_NAME_INITEMPTY;
dns_rdataset_t neg = DNS_RDATASET_INIT, negsig = DNS_RDATASET_INIT;
isc_region_t r1, r2;
isc_region_t r1 = { .base = NULL }, r2 = { .base = NULL };
result = dns_rdataset_getclosest(rdataset, &name, &neg, &negsig);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
@ -3034,6 +3042,14 @@ addclosest(isc_mem_t *mctx, dns_slabheader_t *newheader, uint32_t maxrrperset,
newheader->closest = closest;
cleanup:
if (result != ISC_R_SUCCESS) {
if (r1.base != NULL) {
isc_mem_put(mctx, r1.base, r1.length);
}
if (r2.base != NULL) {
isc_mem_put(mctx, r2.base, r2.length);
}
}
dns_rdataset_disassociate(&neg);
dns_rdataset_disassociate(&negsig);
return result;
@ -3106,12 +3122,12 @@ qpcache_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
DNS_SLABHEADER_SETATTR(newheader, DNS_SLABHEADERATTR_OPTOUT);
}
if (rdataset->attributes.noqname) {
RETERR(addnoqname(qpnode->mctx, newheader, qpdb->maxrrperset,
rdataset));
CHECK(addnoqname(qpnode->mctx, newheader, qpdb->maxrrperset,
rdataset));
}
if (rdataset->attributes.closest) {
RETERR(addclosest(qpnode->mctx, newheader, qpdb->maxrrperset,
rdataset));
CHECK(addclosest(qpnode->mctx, newheader, qpdb->maxrrperset,
rdataset));
}
nlock = &qpdb->buckets[qpnode->locknum].lock;
@ -3179,6 +3195,9 @@ qpcache_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
INSIST(tlocktype == isc_rwlocktype_none);
return result;
cleanup:
dns_slabheader_destroy(&newheader);
return result;
}

View file

@ -401,7 +401,8 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
/*
* A delete operation uses the fully specified qname.
*/
CHECK(process_deletetkey(signer, qname, &tkeyin, &tkeyout,
keyname = qname;
CHECK(process_deletetkey(signer, keyname, &tkeyin, &tkeyout,
ring));
break;
case DNS_TKEYMODE_GSSAPI:
@ -443,6 +444,10 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
result = DNS_R_NOTIMP;
goto cleanup;
default:
/*
* For unrecognized modes also use the fully specified qname.
*/
keyname = qname;
tkeyout.error = dns_tsigerror_badmode;
}

View file

@ -217,7 +217,8 @@ markanswer(dns_validator_t *val, const char *where) {
* Mark the RRsets in val->vstat with trust level secure.
*/
static void
marksecure(dns_validator_t *val) {
marksecure(dns_validator_t *val, const char *where) {
validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (%s)", where);
dns_rdataset_settrust(val->rdataset, dns_trust_secure);
if (val->sigrdataset != NULL) {
dns_rdataset_settrust(val->sigrdataset, dns_trust_secure);
@ -244,12 +245,25 @@ validator_done(dns_validator_t *val, isc_result_t result) {
}
/*%
* Look in the NSEC record returned from a DS query to see if there is
* a NS RRset at this name. If it is found we are at a delegation point.
* The isdelegation() function is called as part of seeking the DS record.
* Look in the NSEC or NSEC3 record returned from a DS query to see if the
* record has the NS bitmap set. If so, we are at a delegation point.
*
* If the response contains NSEC3 records with too high iterations, we cannot
* (or rather we are not going to) validate the insecurity proof. Instead we
* are going to treat the message as insecure and just assume the DS was at
* the delegation.
*
* Returns:
*\li #ISC_R_SUCCESS the NS bitmap was set in the NSEC or NSEC3 record, or
* the NSEC3 covers the name (in case of opt-out), or
* we cannot validate the insecurity proof and are going
* to treat the message as isnecure.
*\li #ISC_R_NOTFOUND the NS bitmap was not set,
*/
static bool
isdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
isc_result_t dbresult) {
static isc_result_t
isdelegation(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset,
isc_result_t dbresult, const char *caller) {
dns_fixedname_t fixed;
dns_label_t hashlabel;
dns_name_t nsec3name;
@ -276,7 +290,7 @@ isdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
goto trynsec3;
}
if (result != ISC_R_SUCCESS) {
return false;
return ISC_R_NOTFOUND;
}
}
@ -290,7 +304,7 @@ isdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
found = dns_nsec_typepresent(&rdata, dns_rdatatype_ns);
}
dns_rdataset_disassociate(&set);
return found;
return found ? ISC_R_SUCCESS : ISC_R_NOTFOUND;
trynsec3:
/*
@ -325,6 +339,18 @@ trynsec3:
if (nsec3.next_length > NSEC3_MAX_HASH_LENGTH) {
continue;
}
/*
* If there are too many iterations assume bad things
* are happening and bail out early. Treat as if the
* DS was at the delegation.
*/
if (nsec3.iterations > DNS_NSEC3_MAXITERATIONS) {
validator_log(val, ISC_LOG_DEBUG(3),
"%s: too many iterations",
caller);
dns_rdataset_disassociate(&set);
return ISC_R_SUCCESS;
}
length = isc_iterated_hash(
hash, nsec3.hash, nsec3.iterations, nsec3.salt,
nsec3.salt_length, name->ndata, name->length);
@ -336,7 +362,7 @@ trynsec3:
found = dns_nsec3_typepresent(&rdata,
dns_rdatatype_ns);
dns_rdataset_disassociate(&set);
return found;
return found ? ISC_R_SUCCESS : ISC_R_NOTFOUND;
}
if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) == 0) {
continue;
@ -352,12 +378,12 @@ trynsec3:
memcmp(hash, nsec3.next, length) < 0)))
{
dns_rdataset_disassociate(&set);
return true;
return ISC_R_SUCCESS;
}
}
dns_rdataset_disassociate(&set);
}
return found;
return found ? ISC_R_SUCCESS : ISC_R_NOTFOUND;
}
static void
@ -593,9 +619,10 @@ fetch_callback_ds(void *arg) {
break;
case DNS_R_NXRRSET:
case DNS_R_NCACHENXRRSET:
if (isdelegation(resp->foundname, &val->frdataset,
eresult))
{
result = isdelegation(val, resp->foundname,
&val->frdataset, eresult,
"fetch_callback_ds");
if (result == ISC_R_SUCCESS) {
/*
* Failed to find a DS while trying to prove
* insecurity. If this is a zone cut, that
@ -708,10 +735,13 @@ validator_callback_ds(void *arg) {
dns_trust_totext(val->frdataset.trust));
have_dsset = (val->frdataset.type == dns_rdatatype_ds);
name = dns_fixedname_name(&val->fname);
if ((val->attributes & VALATTR_INSECURITY) != 0 &&
val->frdataset.covers == dns_rdatatype_ds &&
NEGATIVE(&val->frdataset) &&
isdelegation(name, &val->frdataset, DNS_R_NCACHENXRRSET))
isdelegation(val, name, &val->frdataset,
DNS_R_NCACHENXRRSET,
"validator_callback_ds") == ISC_R_SUCCESS)
{
result = markanswer(val, "validator_callback_ds");
} else if ((val->attributes & VALATTR_INSECURITY) != 0) {
@ -1441,11 +1471,19 @@ verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata,
bool ignore = false;
dns_name_t *wild;
if (DNS_TRUST_SECURE(val->rdataset->trust)) {
/*
* This RRset was already verified before.
*/
return ISC_R_SUCCESS;
}
val->attributes |= VALATTR_TRIEDVERIFY;
wild = dns_fixedname_initname(&fixed);
if (over_max_validations(val)) {
return ISC_R_QUOTA;
}
wild = dns_fixedname_initname(&fixed);
again:
result = dns_dnssec_verify(val->name, val->rdataset, key, ignore,
val->view->mctx, rdata, wild);
@ -1797,9 +1835,7 @@ validate_answer_finish(void *arg) {
}
if (val->result == ISC_R_SUCCESS) {
marksecure(val);
validator_log(val, ISC_LOG_DEBUG(3),
"marking as secure, noqname proof not needed");
marksecure(val, "noqname proof not needed");
validate_async_done(val, val->result);
return;
}
@ -2002,8 +2038,7 @@ validate_dnskey_dsset_done(dns_validator_t *val, isc_result_t result) {
/* Abort, abort, abort! */
break;
case ISC_R_SUCCESS:
marksecure(val);
validator_log(val, ISC_LOG_DEBUG(3), "marking as secure (DS)");
marksecure(val, "validate_dnskey (DS)");
break;
case ISC_R_NOMORE:
if (val->unsupported_algorithm != 0 ||
@ -2742,11 +2777,21 @@ validate_neg_rrset(dns_validator_t *val, dns_name_t *name,
}
}
if (rdataset->type != dns_rdatatype_nsec &&
DNS_TRUST_SECURE(rdataset->trust))
{
/*
* The negative response data is already verified.
* We skip NSEC records, because they require special
* processing in validator_callback_nsec().
*/
return DNS_R_CONTINUE;
}
val->nxset = rdataset;
RETERR(create_validator(val, name, rdataset->type, rdataset,
sigrdataset, validator_callback_nsec,
"validate_neg_rrset"));
val->authcount++;
return DNS_R_WAIT;
}
@ -2849,11 +2894,9 @@ validate_ncache(dns_validator_t *val, bool resume) {
}
result = validate_neg_rrset(val, name, rdataset, sigrdataset);
if (result == DNS_R_CONTINUE) {
continue;
if (result != DNS_R_CONTINUE) {
return result;
}
return result;
}
if (result == ISC_R_NOMORE) {
result = ISC_R_SUCCESS;
@ -2902,7 +2945,8 @@ validate_nx(dns_validator_t *val, bool resume) {
result = findnsec3proofs(val);
if (result == DNS_R_NSEC3ITERRANGE) {
validator_log(val, ISC_LOG_DEBUG(3),
"too many iterations");
"%s: too many iterations",
__func__);
markanswer(val, "validate_nx (3)");
return ISC_R_SUCCESS;
}
@ -2910,9 +2954,7 @@ validate_nx(dns_validator_t *val, bool resume) {
if (FOUNDNOQNAME(val) && FOUNDCLOSEST(val) && !FOUNDOPTOUT(val))
{
validator_log(val, ISC_LOG_DEBUG(3),
"marking as secure, noqname proof found");
marksecure(val);
marksecure(val, "validate_nx (noqname proof found)");
return ISC_R_SUCCESS;
} else if (FOUNDOPTOUT(val) &&
dns_name_countlabels(
@ -2938,7 +2980,7 @@ validate_nx(dns_validator_t *val, bool resume) {
result = findnsec3proofs(val);
if (result == DNS_R_NSEC3ITERRANGE) {
validator_log(val, ISC_LOG_DEBUG(3),
"too many iterations");
"%s: too many iterations", __func__);
markanswer(val, "validate_nx (4)");
return ISC_R_SUCCESS;
}
@ -2963,7 +3005,8 @@ validate_nx(dns_validator_t *val, bool resume) {
validator_log(val, ISC_LOG_DEBUG(3),
"nonexistence proof(s) found");
if (val->message == NULL) {
marksecure(val);
marksecure(val,
"validate_nx (nonexistence proofs found)");
} else {
val->secure = true;
}
@ -3272,7 +3315,9 @@ seek_ds(dns_validator_t *val, isc_result_t *resp) {
return ISC_R_COMPLETE;
}
if (isdelegation(tname, &val->frdataset, result)) {
result = isdelegation(val, tname, &val->frdataset, result,
"seek_ds");
if (result == ISC_R_SUCCESS) {
*resp = markanswer(val, "seek_ds (3)");
return ISC_R_COMPLETE;
}