Merge branch '3394-cve-2022-2795-test-v9_18' into 'v9_18'

[v9_18] Add tests for CVE-2022-2795

See merge request isc-projects/bind9!6948
This commit is contained in:
Michal Nowak 2022-10-19 13:05:22 +00:00
commit 6a3d92a98c
11 changed files with 223 additions and 10 deletions

View file

@ -73,6 +73,15 @@ for (;;) {
# Data for the "cname + other data / 2" test: same RRs in opposite order
$packet->push("answer", new Net::DNS::RR("cname2.example.com 300 A 1.2.3.4"));
$packet->push("answer", new Net::DNS::RR("cname2.example.com 300 CNAME cname2.example.com"));
} elsif ($qname =~ /redirect\.com/) {
$packet->push("authority", new Net::DNS::RR("redirect.com 300 NS ns.redirect.com"));
$packet->push("additional", new Net::DNS::RR("ns.redirect.com 300 A 10.53.0.6"));
} elsif ($qname =~ /\.tld1/) {
$packet->push("authority", new Net::DNS::RR("tld1 300 NS ns.tld1"));
$packet->push("additional", new Net::DNS::RR("ns.tld1 300 A 10.53.0.6"));
} elsif ($qname =~ /\.tld2/) {
$packet->push("authority", new Net::DNS::RR("tld2 300 NS ns.tld2"));
$packet->push("additional", new Net::DNS::RR("ns.tld2 300 A 10.53.0.7"));
} elsif ($qname eq "org" && $qtype eq "NS") {
$packet->header->aa(1);
$packet->push("answer", new Net::DNS::RR("org 300 NS a.root-servers.nil."));

View file

@ -20,11 +20,21 @@ use IO::Socket;
use Net::DNS;
use Net::DNS::Packet;
# Ignore SIGPIPE so we won't fail if peer closes a TCP socket early
local $SIG{PIPE} = 'IGNORE';
# Flush logged output after every line
local $| = 1;
my $localport = int($ENV{'PORT'});
if (!$localport) { $localport = 5300; }
my $sock = IO::Socket::INET->new(LocalAddr => "10.53.0.3",
LocalPort => $localport, Proto => "udp") or die "$!";
my $server_addr = "10.53.0.3";
my $udpsock = IO::Socket::INET->new(LocalAddr => "$server_addr",
LocalPort => $localport, Proto => "udp", Reuse => 1) or die "$!";
my $tcpsock = IO::Socket::INET->new(LocalAddr => "$server_addr",
LocalPort => $localport, Proto => "tcp", Listen => 5, Reuse => 1) or die "$!";
my $pidf = new IO::File "ans.pid", "w" or die "cannot open pid file: $!";
print $pidf "$$\n" or die "cannot write pid file: $!";
@ -34,11 +44,8 @@ sub rmpid { unlink "ans.pid"; exit 1; };
$SIG{INT} = \&rmpid;
$SIG{TERM} = \&rmpid;
for (;;) {
$sock->recv($buf, 512);
print "**** request from " , $sock->peerhost, " port ", $sock->peerport, "\n";
sub handleQuery {
my $buf = shift;
my $packet;
if ($Net::DNS::VERSION > 0.68) {
@ -105,6 +112,13 @@ for (;;) {
$packet->header->aa(0);
$packet->push("authority", new Net::DNS::RR("lame.example.org 300 NS ns.lame.example.org"));
$packet->push("additional", new Net::DNS::RR("ns.lame.example.org 300 A 10.53.0.3"));
} elsif ($qname eq "large-referral.example.net") {
for (my $i = 1; $i < 1000; $i++) {
$packet->push("authority", new Net::DNS::RR("large-referral.example.net 300 NS ns" . $i . ".fake.redirect.com"));
}
# No glue records
} elsif ($qname eq "foo.bar.sub.tld1") {
$packet->push("answer", new Net::DNS::RR("$qname 300 TXT baz"));
} elsif ($qname eq "cname.sub.example.org") {
$packet->push("answer",
new Net::DNS::RR($qname .
@ -132,9 +146,46 @@ for (;;) {
$packet->push("answer", new Net::DNS::RR("www.example.com 300 A 1.2.3.4"));
}
$sock->send($packet->data);
print "RESPONSE:\n";
$packet->print;
print "\n";
return $packet->data;
}
# Main
my $rin;
my $rout;
for (;;) {
$rin = '';
vec($rin, fileno($tcpsock), 1) = 1;
vec($rin, fileno($udpsock), 1) = 1;
select($rout = $rin, undef, undef, undef);
if (vec($rout, fileno($udpsock), 1)) {
printf "UDP request\n";
my $buf;
$udpsock->recv($buf, 512);
my $result = handleQuery($buf);
my $num_chars = $udpsock->send($result);
print " Sent $num_chars bytes via UDP\n";
} elsif (vec($rout, fileno($tcpsock), 1)) {
my $conn = $tcpsock->accept;
my $buf;
for (;;) {
my $lenbuf;
my $n = $conn->sysread($lenbuf, 2);
last unless $n == 2;
my $len = unpack("n", $lenbuf);
$n = $conn->sysread($buf, $len);
last unless $n == $len;
print "TCP request\n";
my $result = handleQuery($buf);
$len = length($result);
$conn->syswrite(pack("n", $len), 2);
$n = $conn->syswrite($result, $len);
print " Sent: $n chars via TCP\n";
}
$conn->close;
}
}

View file

@ -31,6 +31,10 @@ options {
attach-cache "globalcache";
};
server 10.53.0.3 {
tcp-only yes;
};
server 10.42.23.3/32 {
notify-source 10.42.22.1;
query-source address 10.42.22.1 port 0;
@ -64,3 +68,12 @@ view "default" {
file "root.hint";
};
};
key rndc_key {
secret "1234abcd8765";
algorithm @DEFAULT_HMAC@;
};
controls {
inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};

View file

@ -62,6 +62,16 @@ zone "broken" {
allow-update { any; };
};
zone "redirect.com" {
type primary;
file "redirect.com.db";
};
zone "tld1" {
type primary;
file "tld1.db";
};
zone "no-edns-version.tld" {
type primary;
file "no-edns-version.tld.db";

View file

@ -0,0 +1,27 @@
; 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 600
@ IN SOA ns hostmaster 1 1800 900 604800 600
@ IN NS ns
ns IN A 10.53.0.6
; 10.53.1.* are non-responsive IP addresses
$GENERATE 1-100 ns$.fake IN A 10.53.1.$
$GENERATE 101-200 ns$.fake IN A 10.53.1.${-100}
$GENERATE 201-300 ns$.fake IN A 10.53.1.${-200}
$GENERATE 301-400 ns$.fake IN A 10.53.1.${-300}
$GENERATE 401-500 ns$.fake IN A 10.53.1.${-400}
$GENERATE 501-600 ns$.fake IN A 10.53.1.${-500}
$GENERATE 601-700 ns$.fake IN A 10.53.1.${-600}
$GENERATE 701-800 ns$.fake IN A 10.53.1.${-700}
$GENERATE 801-900 ns$.fake IN A 10.53.1.${-800}
$GENERATE 901-1000 ns$.fake IN A 10.53.1.${-900}

View file

@ -0,0 +1,17 @@
; 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 600
@ IN SOA ns hostmaster 1 1800 900 604800 600
@ IN NS ns
ns IN A 10.53.0.6
$GENERATE 1-21 sub IN NS sub-ns$.tld2.

View file

@ -63,3 +63,13 @@ zone "all-cnames" {
type primary;
file "all-cnames.db";
};
zone "tld2" {
type primary;
file "tld2.db";
};
zone "sub.tld1" {
type primary;
file "sub.tld1.db";
};

View file

@ -63,3 +63,13 @@ zone "all-cnames" {
type primary;
file "all-cnames.db";
};
zone "tld2" {
type primary;
file "tld2.db";
};
zone "sub.tld1" {
type primary;
file "sub.tld1.db";
};

View file

@ -0,0 +1,17 @@
; 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 600
@ IN SOA ns hostmaster 1 1800 900 604800 600
$GENERATE 1-21 @ IN NS sub-ns$.tld2.
$GENERATE 1-21 bar IN NS bar-sub-ns$.tld2.

View file

@ -0,0 +1,18 @@
; 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 600
@ IN SOA ns hostmaster 1 1800 900 604800 600
@ IN NS ns
ns IN A 10.53.0.7
$GENERATE 1-21 sub-ns$ IN A 10.53.0.7
$GENERATE 1-21 bar-sub-ns$ IN A 10.53.0.3

View file

@ -937,5 +937,36 @@ grep "status: SERVFAIL" dig.out.ns1.${n} > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n+1))
echo_i "check handling of large referrals to unresponsive name servers ($n)"
ret=0
dig_with_opts +timeout=15 large-referral.example.net @10.53.0.1 a > dig.out.ns1.test${n} || ret=1
grep "status: SERVFAIL" dig.out.ns1.test${n} > /dev/null || ret=1
# Check the total number of findname() calls triggered by a single query
# for large-referral.example.net/A.
findname_call_count="$(grep -c "large-referral\.example\.net.*FINDNAME" ns1/named.run)"
if [ "${findname_call_count}" -gt 1000 ]; then
echo_i "failed: ${findname_call_count} (> 1000) findname() calls detected for large-referral.example.net"
ret=1
fi
# Check whether the limit of NS RRs processed for any delegation
# encountered was not exceeded.
if grep -Eq "dns_adb_createfind: started (A|AAAA) fetch for name ns21.fake.redirect.com" ns1/named.run; then
echo_i "failed: unexpected address fetch(es) were triggered for ns21.fake.redirect.com"
ret=1
fi
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
n=$((n+1))
echo_i "checking query resolution for a domain with a valid glueless delegation chain ($n)"
ret=0
rndccmd 10.53.0.1 flush || ret=1
dig_with_opts foo.bar.sub.tld1 @10.53.0.1 TXT > dig.out.ns1.test${n} || ret=1
grep "status: NOERROR" dig.out.ns1.test${n} > /dev/null || ret=1
grep "IN.*TXT.*baz" dig.out.ns1.test${n} > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1