mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-27 20:25:55 -04:00
Merge tag 'v9.20.21' into bind-9.20
This commit is contained in:
commit
b040b566fe
31 changed files with 1070 additions and 47 deletions
|
|
@ -24,6 +24,8 @@
|
|||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <dns/acl.h>
|
||||
|
||||
#ifdef HAVE_DNSTAP
|
||||
#include <fstrm.h>
|
||||
#endif
|
||||
|
|
@ -280,10 +282,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;
|
||||
|
|
@ -10358,6 +10360,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);
|
||||
}
|
||||
|
|
@ -10399,10 +10403,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))
|
||||
{
|
||||
|
|
@ -10474,9 +10478,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,
|
||||
|
|
|
|||
29
bin/tests/system/nsec/ns1/named.conf.j2
Normal file
29
bin/tests/system/nsec/ns1/named.conf.j2
Normal 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";
|
||||
};
|
||||
24
bin/tests/system/nsec/ns1/root.db
Normal file
24
bin/tests/system/nsec/ns1/root.db
Normal 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
|
||||
24
bin/tests/system/nsec/ns2/excessive-nsec-rrsigs.db.in
Normal file
24
bin/tests/system/nsec/ns2/excessive-nsec-rrsigs.db.in
Normal 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
|
||||
29
bin/tests/system/nsec/ns2/named.conf.j2
Normal file
29
bin/tests/system/nsec/ns2/named.conf.j2
Normal 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";
|
||||
};
|
||||
35
bin/tests/system/nsec/ns3/named.conf.j2
Normal file
35
bin/tests/system/nsec/ns3/named.conf.j2
Normal 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";
|
||||
1
bin/tests/system/nsec/ns3/trusted.conf.j2
Symbolic link
1
bin/tests/system/nsec/ns3/trusted.conf.j2
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../_common/trusted.conf.j2
|
||||
87
bin/tests/system/nsec/tests_excessive_rrsigs.py
Executable file
87
bin/tests/system/nsec/tests_excessive_rrsigs.py
Executable 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)
|
||||
35
bin/tests/system/nsec3-delegation/ns1/named.conf.j2
Normal file
35
bin/tests/system/nsec3-delegation/ns1/named.conf.j2
Normal 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";
|
||||
};
|
||||
25
bin/tests/system/nsec3-delegation/ns1/root.db
Normal file
25
bin/tests/system/nsec3-delegation/ns1/root.db
Normal 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
|
||||
|
|
@ -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 %}
|
||||
40
bin/tests/system/nsec3-delegation/ns2/named.conf.j2
Normal file
40
bin/tests/system/nsec3-delegation/ns2/named.conf.j2
Normal 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";
|
||||
};
|
||||
24
bin/tests/system/nsec3-delegation/ns2/sub.iter-too-many.db
Normal file
24
bin/tests/system/nsec3-delegation/ns2/sub.iter-too-many.db
Normal 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
|
||||
37
bin/tests/system/nsec3-delegation/ns3/named.conf.j2
Normal file
37
bin/tests/system/nsec3-delegation/ns3/named.conf.j2
Normal 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";
|
||||
1
bin/tests/system/nsec3-delegation/ns3/trusted.conf.j2
Symbolic link
1
bin/tests/system/nsec3-delegation/ns3/trusted.conf.j2
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
../../_common/trusted.conf.j2
|
||||
|
|
@ -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"
|
||||
)
|
||||
41
bin/tests/system/sig0/ns1/named.conf.j2
Normal file
41
bin/tests/system/sig0/ns1/named.conf.j2
Normal 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";
|
||||
};
|
||||
};
|
||||
17
bin/tests/system/sig0/setup.sh
Normal file
17
bin/tests/system/sig0/setup.sh
Normal 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.)
|
||||
119
bin/tests/system/sig0/tests_sig0.py
Normal file
119
bin/tests/system/sig0/tests_sig0.py
Normal 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)
|
||||
23
bin/tests/system/tkey/ns1/example.db
Normal file
23
bin/tests/system/tkey/ns1/example.db
Normal 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
|
||||
35
bin/tests/system/tkey/ns1/named.conf.j2
Normal file
35
bin/tests/system/tkey/ns1/named.conf.j2
Normal 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";
|
||||
};
|
||||
62
bin/tests/system/tkey/tests_cve_2026_3119.py
Normal file
62
bin/tests/system/tkey/tests_cve_2026_3119.py
Normal 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)
|
||||
|
|
@ -18,6 +18,7 @@ Changelog
|
|||
development. Regular users should refer to :ref:`Release Notes <relnotes>`
|
||||
for changes relevant to them.
|
||||
|
||||
.. include:: ../changelog/changelog-9.20.21.rst
|
||||
.. include:: ../changelog/changelog-9.20.20.rst
|
||||
.. include:: ../changelog/changelog-9.20.19.rst
|
||||
.. include:: ../changelog/changelog-9.20.18.rst
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ The list of known issues affecting the latest version in the 9.20 branch can be
|
|||
found at
|
||||
https://gitlab.isc.org/isc-projects/bind9/-/wikis/Known-Issues-in-BIND-9.20
|
||||
|
||||
.. include:: ../notes/notes-9.20.21.rst
|
||||
.. include:: ../notes/notes-9.20.20.rst
|
||||
.. include:: ../notes/notes-9.20.19.rst
|
||||
.. include:: ../notes/notes-9.20.18.rst
|
||||
|
|
|
|||
77
doc/changelog/changelog-9.20.21.rst
Normal file
77
doc/changelog/changelog-9.20.21.rst
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
.. 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.20.21
|
||||
------------
|
||||
|
||||
Security Fixes
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
- [CVE-2026-1519] Fix unbounded NSEC3 iterations when validating
|
||||
referrals to unsigned delegations. ``5af03a06066``
|
||||
|
||||
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. ``13215b9cbbf``
|
||||
|
||||
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. ``308baa89105``
|
||||
|
||||
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. ``aaaae0fd97e``
|
||||
|
||||
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`
|
||||
|
||||
Bug Fixes
|
||||
~~~~~~~~~
|
||||
|
||||
- Resolve "key defined in view is not found" ``819fe452745``
|
||||
|
||||
Commit `2956e4fc` hardened the `key` name check when used in
|
||||
`primaries` to reject the configuration if the key was not defined,
|
||||
rather than simply checking whether the key name was correctly formed.
|
||||
|
||||
However, the key name check didn't include the view configuration,
|
||||
causing keys not to be recognized if they were defined inside the view
|
||||
and not at the global level. This regression is now fixed.
|
||||
:gl:`#5761` :gl:`!11613`
|
||||
|
||||
|
||||
75
doc/notes/notes-9.20.21.rst
Normal file
75
doc/notes/notes-9.20.21.rst
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
.. 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.20.21
|
||||
----------------------
|
||||
|
||||
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`
|
||||
|
||||
Bug Fixes
|
||||
~~~~~~~~~
|
||||
|
||||
- Fix the handling of :namedconf:ref:`key` statements defined inside
|
||||
views.
|
||||
|
||||
A recent change introduced in BIND 9.20.17 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`
|
||||
|
|
@ -393,6 +393,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.
|
||||
|
|
|
|||
|
|
@ -3279,7 +3279,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);
|
||||
|
|
@ -3305,6 +3305,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);
|
||||
|
||||
|
|
@ -3318,7 +3326,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);
|
||||
|
|
@ -3344,6 +3352,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;
|
||||
|
|
|
|||
|
|
@ -3180,7 +3180,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);
|
||||
|
|
@ -3206,6 +3206,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);
|
||||
|
||||
|
|
@ -3219,7 +3227,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);
|
||||
|
|
@ -3245,6 +3253,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;
|
||||
|
|
|
|||
|
|
@ -420,7 +420,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:
|
||||
|
|
@ -463,6 +464,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -230,7 +230,8 @@ markanswer(dns_validator_t *val, const char *where, const char *mbstext) {
|
|||
* 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);
|
||||
|
|
@ -257,12 +258,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;
|
||||
|
|
@ -290,7 +304,7 @@ isdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
|
|||
goto trynsec3;
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return false;
|
||||
return ISC_R_NOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -304,7 +318,7 @@ isdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
|
|||
dns_rdata_reset(&rdata);
|
||||
}
|
||||
dns_rdataset_disassociate(&set);
|
||||
return found;
|
||||
return found ? ISC_R_SUCCESS : ISC_R_NOTFOUND;
|
||||
|
||||
trynsec3:
|
||||
/*
|
||||
|
|
@ -343,6 +357,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);
|
||||
|
|
@ -354,7 +380,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;
|
||||
|
|
@ -370,12 +396,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
|
||||
|
|
@ -589,9 +615,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
|
||||
|
|
@ -707,10 +734,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",
|
||||
"no DS and this is a delegation");
|
||||
|
|
@ -1487,11 +1517,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->maxbits, val->view->mctx, rdata,
|
||||
|
|
@ -1846,9 +1884,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;
|
||||
}
|
||||
|
|
@ -2057,8 +2093,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 ||
|
||||
|
|
@ -2769,7 +2804,19 @@ 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;
|
||||
|
||||
result = create_validator(val, name, rdataset->type, rdataset,
|
||||
sigrdataset, validator_callback_nsec,
|
||||
"validate_neg_rrset");
|
||||
|
|
@ -2879,11 +2926,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;
|
||||
|
|
@ -2932,7 +2977,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)", NULL);
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
|
|
@ -2940,9 +2986,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(
|
||||
|
|
@ -2968,7 +3012,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)", NULL);
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
|
|
@ -2996,7 +3040,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;
|
||||
}
|
||||
|
|
@ -3181,7 +3226,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)",
|
||||
"this is a delegation");
|
||||
return ISC_R_COMPLETE;
|
||||
|
|
|
|||
Loading…
Reference in a new issue