bind/bind-9.16-CVE-2024-1737-types-test.patch
Petr Menšík 4b8cbe77ba Fix patches after rebase
zone.c was left broken. Fix it.

Resolves: RHEL-6454
2026-07-07 14:37:42 +02:00

991 lines
35 KiB
Diff

From d6b010f2c7c002295235ca3553376ce1a4b7cf96 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@isc.org>
Date: Tue, 28 May 2024 15:23:24 +0200
Subject: [PATCH] Add a test for not caching large number of RRsets
Send a recursive query for a large number of RRsets, which should
fail when using the default max-types-per-name setting of 100, but
succeed when the cap is disabled.
(cherry picked from commit 7e4530f847c8dc541c5e5bf9f790deed520aaa16)
(cherry picked from commit a36ab2eb3615e59809e0d875233d92f9c0d1a729)
Add test for not-loading many RRsets per name on a secondary
This tests makes sure the zone with many RRsets per name is not loaded
via XFR on the secondary server.
(cherry picked from commit 4cfeed912a5e7440f04cb088a461ff47305da2e7)
(cherry picked from commit b6f6e12bbfbc35901f4c0ee693dace9199efb237)
Test variable rename a->rrcount
(cherry picked from commit 338b45ae713cded921fd3e5494ca38bd59ff9ee8)
(cherry picked from commit 747da63896f9daf4dae866150d68fc275ae6f660)
Test variable rename i->_attempt
(cherry picked from commit 13417eb277cc8a30ee4ddbb6fc02442b0d8e6d3c)
(cherry picked from commit 6516c92c070e944910fd19ce87a3028b9bf8480a)
Test owner name rename: a b c d e -> <number>-txt
(cherry picked from commit 6ce03f75d1935c2e1991e9c0a01c49b0099a58cb)
(cherry picked from commit eb4355c9f393e3f4ce6203da2590108f52df55f4)
masterformat: rename zone names to reflect intended meaning
(cherry picked from commit d34bfb1eeaa2f8faab80b1620b992b5495e6f88c)
(cherry picked from commit da5bac8104b56fd2782cffc97fb06577dd62eec1)
Remove duplicated empty zone files
(cherry picked from commit 1456b4fc7778b851256107dbc79fb67d45f752f5)
(cherry picked from commit e08f2683878850d4b02eab3e4dd47b44925c78a0)
Add more tests for adding many RR types to the database
More reclimit tests that test various scenarios adding combinations of
priority and non-priority RR types into the database.
(cherry picked from commit d3ca4be21c90283b801886e6f798def801d259a9)
---
bin/tests/system/masterformat/clean.sh | 5 +
bin/tests/system/masterformat/ns1/compile.sh | 7 +-
bin/tests/system/masterformat/ns1/large.db.in | 22 --
.../system/masterformat/ns1/named.conf.in | 21 +-
.../system/masterformat/ns2/named.conf.in | 16 +-
bin/tests/system/masterformat/setup.sh | 45 ++-
bin/tests/system/masterformat/tests.sh | 83 +++--
bin/tests/system/reclimit/clean.sh | 22 +-
bin/tests/system/reclimit/ns1/named.conf.in | 6 +
bin/tests/system/reclimit/ns1/root.db | 5 +-
bin/tests/system/reclimit/ns3/named6.conf.in | 43 +++
bin/tests/system/reclimit/setup.sh | 5 +
bin/tests/system/reclimit/tests.sh | 325 +++++++++++++++---
13 files changed, 469 insertions(+), 136 deletions(-)
delete mode 100644 bin/tests/system/masterformat/ns1/large.db.in
create mode 100644 bin/tests/system/reclimit/ns3/named6.conf.in
diff --git a/bin/tests/system/masterformat/clean.sh b/bin/tests/system/masterformat/clean.sh
index c606c61..2b93c2b 100755
--- a/bin/tests/system/masterformat/clean.sh
+++ b/bin/tests/system/masterformat/clean.sh
@@ -18,6 +18,11 @@ rm -f ./ns1/large.db ./ns1/large.db.raw
rm -f ./ns1/example.db.map ./ns1/signed.db.map
rm -f ./ns1/huge.db ./ns1/huge.db.raw
rm -f ./ns1/uber.db ./ns1/uber.db.raw
+rm -f ./ns1/255types.db ./ns1/255types.db.raw
+rm -f ./ns1/on-limit.db ./ns1/on-limit.db.raw
+rm -f ./ns1/over-limit.db ./ns1/over-limit.db.raw
+rm -f ./ns1/under-limit.db ./ns1/under-limit.db.raw
+rm -f ./ns2/under-limit.bk
rm -f ./ns1/session.key
rm -f ./dig.out.*
rm -f ./dig.out
diff --git a/bin/tests/system/masterformat/ns1/compile.sh b/bin/tests/system/masterformat/ns1/compile.sh
index 3427954..7eee7cc 100755
--- a/bin/tests/system/masterformat/ns1/compile.sh
+++ b/bin/tests/system/masterformat/ns1/compile.sh
@@ -26,11 +26,12 @@ $CHECKZONE -D -F raw=0 -o example.db.compat example-compat \
example.db >/dev/null 2>&1
$CHECKZONE -D -F raw -L 3333 -o example.db.serial.raw example \
example.db >/dev/null 2>&1
-$CHECKZONE -D -F raw -o large.db.raw large large.db >/dev/null 2>&1
+$CHECKZONE -D -F raw -o under-limit.db.raw under-limit under-limit.db >/dev/null 2>&1
$CHECKZONE -D -F map -o example.db.map example-map \
example.db >/dev/null 2>&1
-$CHECKZONE -D -F raw -o huge.db.raw huge huge.db >/dev/null 2>&1
-$CHECKZONE -D -F raw -o uber.db.raw uber uber.db >/dev/null 2>&1
+$CHECKZONE -D -F raw -o on-limit.db.raw on-limit on-limit.db >/dev/null 2>&1
+$CHECKZONE -D -F raw -o over-limit.db.raw over-limit over-limit.db >/dev/null 2>&1
+$CHECKZONE -D -F raw -o 255types.db.raw 255types 255types.db >/dev/null 2>&1
$KEYGEN -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -f KSK signed >/dev/null 2>&1
$KEYGEN -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" signed >/dev/null 2>&1
diff --git a/bin/tests/system/masterformat/ns1/large.db.in b/bin/tests/system/masterformat/ns1/large.db.in
deleted file mode 100644
index 5a81863..0000000
--- a/bin/tests/system/masterformat/ns1/large.db.in
+++ /dev/null
@@ -1,22 +0,0 @@
-; 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 1D
-
-@ IN SOA ns hostmaster (
- 1
- 3600
- 1800
- 1814400
- 3
- )
- NS ns
-ns A 10.53.0.1
diff --git a/bin/tests/system/masterformat/ns1/named.conf.in b/bin/tests/system/masterformat/ns1/named.conf.in
index 1434ec3..85642a9 100644
--- a/bin/tests/system/masterformat/ns1/named.conf.in
+++ b/bin/tests/system/masterformat/ns1/named.conf.in
@@ -23,6 +23,7 @@ options {
session-keyfile "session.key";
servfail-ttl 0;
max-records-per-type 2050;
+ max-types-per-name 500;
};
key rndc_key {
@@ -71,23 +72,31 @@ zone "transfer4" {
};
-zone "large" {
+zone "under-limit" {
type primary;
- file "large.db.raw";
+ file "under-limit.db.raw";
masterfile-format raw;
allow-transfer { any; };
};
-zone "huge" {
+zone "on-limit" {
type primary;
- file "huge.db.raw";
+ file "on-limit.db.raw";
masterfile-format raw;
allow-transfer { any; };
};
-zone "uber" {
+
+zone "over-limit" {
+ type primary;
+ file "over-limit.db.raw";
+ masterfile-format raw;
+ allow-transfer { any; };
+};
+
+zone "255types" {
type primary;
- file "uber.db.raw";
+ file "255types.db.raw";
masterfile-format raw;
allow-transfer { any; };
};
diff --git a/bin/tests/system/masterformat/ns2/named.conf.in b/bin/tests/system/masterformat/ns2/named.conf.in
index df778bc..d4b2bb7 100644
--- a/bin/tests/system/masterformat/ns2/named.conf.in
+++ b/bin/tests/system/masterformat/ns2/named.conf.in
@@ -22,6 +22,7 @@ options {
notify no;
servfail-ttl 0;
max-records-per-type 2000;
+ max-types-per-name 200;
};
zone "example" {
@@ -56,16 +57,23 @@ zone "transfer4" {
file "transfer.db.full";
};
-zone "large" {
+zone "under-limit" {
type secondary;
primaries { 10.53.0.1; };
masterfile-format raw;
- file "large.bk";
+ file "under-limit.bk";
};
-zone "huge" {
+zone "on-limit" {
type secondary;
primaries { 10.53.0.1; };
masterfile-format raw;
- file "huge.bk";
+ file "on-limit.bk";
+};
+
+zone "255types" {
+ type secondary;
+ primaries { 10.53.0.1; };
+ masterfile-format raw;
+ file "255types.bk";
};
diff --git a/bin/tests/system/masterformat/setup.sh b/bin/tests/system/masterformat/setup.sh
index 57b8a24..223ca0b 100755
--- a/bin/tests/system/masterformat/setup.sh
+++ b/bin/tests/system/masterformat/setup.sh
@@ -22,25 +22,34 @@ copy_setports ns3/named.conf.in ns3/named.conf
cp ns1/example.db ns2/
cp ns2/formerly-text.db.in ns2/formerly-text.db
-cp ns1/large.db.in ns1/large.db
+cp ns1/empty.db.in ns1/under-limit.db
+
+# counts are set with respect to these limits in named.conf:
+# max-records-per-type 2050;
+# max-types-per-name 500;
awk 'END {
- for (i = 0; i < 500; i++ ) { print "a TXT", i; }
- for (i = 0; i < 1000; i++ ) { print "b TXT", i; }
- for (i = 0; i < 2000; i++ ) { print "c TXT", i; }
-}' </dev/null >>ns1/large.db
-cp ns1/huge.db.in ns1/huge.db
+ for (i = 0; i < 500; i++ ) { print "500-txt TXT", i; }
+ for (i = 0; i < 1000; i++ ) { print "1000-txt TXT", i; }
+ for (i = 0; i < 2000; i++ ) { print "2000-txt TXT", i; }
+}' </dev/null >>ns1/under-limit.db
+cp ns1/empty.db.in ns1/on-limit.db
awk 'END {
- for (i = 0; i < 500; i++ ) { print "a TXT", i; }
- for (i = 0; i < 1000; i++ ) { print "b TXT", i; }
- for (i = 0; i < 2000; i++ ) { print "c TXT", i; }
- for (i = 0; i < 2050; i++ ) { print "d TXT", i; }
-}' </dev/null >>ns1/huge.db
-cp ns1/uber.db.in ns1/uber.db
+ for (i = 0; i < 500; i++ ) { print "500-txt TXT", i; }
+ for (i = 0; i < 1000; i++ ) { print "1000-txt TXT", i; }
+ for (i = 0; i < 2000; i++ ) { print "2000-txt TXT", i; }
+ for (i = 0; i < 2050; i++ ) { print "2050-txt TXT", i; }
+}' </dev/null >>ns1/on-limit.db
+cp ns1/empty.db.in ns1/over-limit.db
awk 'END {
- for (i = 0; i < 500; i++ ) { print "a TXT", i; }
- for (i = 0; i < 1000; i++ ) { print "b TXT", i; }
- for (i = 0; i < 2000; i++ ) { print "c TXT", i; }
- for (i = 0; i < 2050; i++ ) { print "d TXT", i; }
- for (i = 0; i < 2100; i++ ) { print "e TXT", i; }
-}' </dev/null >>ns1/uber.db
+ for (i = 0; i < 500; i++ ) { print "500-txt TXT", i; }
+ for (i = 0; i < 1000; i++ ) { print "1000-txt TXT", i; }
+ for (i = 0; i < 2000; i++ ) { print "2000-txt TXT", i; }
+ for (i = 0; i < 2050; i++ ) { print "2050-txt TXT", i; }
+ for (i = 0; i < 2100; i++ ) { print "2100-txt TXT", i; }
+}' </dev/null >>ns1/over-limit.db
+cp ns1/empty.db.in ns1/255types.db
+for ntype in $(seq 65280 65534); do
+ echo "m TYPE${ntype} \# 0"
+done >>ns1/255types.db
+echo "m TXT bunny" >>ns1/255types.db
cd ns1 && $SHELL compile.sh
diff --git a/bin/tests/system/masterformat/tests.sh b/bin/tests/system/masterformat/tests.sh
index c3be164..029bf62 100755
--- a/bin/tests/system/masterformat/tests.sh
+++ b/bin/tests/system/masterformat/tests.sh
@@ -145,7 +145,7 @@ n=$((n + 1))
status=$((status + ret))
echo_i "waiting for transfers to complete"
-for i in 0 1 2 3 4 5 6 7 8 9; do
+for _attempt in 0 1 2 3 4 5 6 7 8 9; do
test -f ns2/transfer.db.raw -a -f ns2/transfer.db.txt && break
sleep 1
done
@@ -173,7 +173,7 @@ n=$((n + 1))
status=$((status + ret))
echo_i "checking that secondary formerly in text format is now raw ($n)"
-for i in 0 1 2 3 4 5 6 7 8 9; do
+for _attempt in 0 1 2 3 4 5 6 7 8 9; do
ret=0
israw ns2/formerly-text.db >/dev/null 2>&1 || ret=1
[ "$(rawversion ns2/formerly-text.db)" -eq 1 ] || ret=1
@@ -184,16 +184,12 @@ n=$((n + 1))
[ $ret -eq 0 ] || echo_i "failed"
status=$((status + ret))
-echo_i "checking that large rdatasets loaded ($n)"
-for i in 0 1 2 3 4 5 6 7 8 9; do
+echo_i "checking that under-limit rdatasets loaded ($n)"
+for _attempt in 0 1 2 3 4 5 6 7 8 9; do
ret=0
- for a in a b c; do
- $DIG +tcp txt "${a}.large" @10.53.0.2 -p "${PORT}" >"dig.out.ns2.test$n"
- grep "status: NOERROR" "dig.out.ns2.test$n" >/dev/null || ret=1
- for a in a b c
- do
- $DIG +tcp txt "${a}.large" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$a.test$n"
- grep "status: NOERROR" "dig.out.ns1.$a.test$n" >/dev/null || ret=1
+ for rrcount in 500-txt 1000-txt 2000-txt; do
+ $DIG +tcp txt "${rrcount}.under-limit" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$rrcount.test$n"
+ grep "status: NOERROR" "dig.out.ns1.$rrcount.test$n" >/dev/null || ret=1
done
[ $ret -eq 0 ] && break
sleep 1
@@ -202,12 +198,12 @@ n=$((n + 1))
[ $ret -eq 0 ] || echo_i "failed"
status=$((status + ret))
-echo_i "checking that large rdatasets transfered ($n)"
-for i in 0 1 2 3 4 5 6 7 8 9; do
+echo_i "checking that under-limit rdatasets transfered ($n)"
+for _attempt in 0 1 2 3 4 5 6 7 8 9; do
ret=0
- for a in a b c; do
- $DIG +tcp txt "${a}.large" @10.53.0.2 -p "${PORT}" >"dig.out.ns2.$a.test$n"
- grep "status: NOERROR" "dig.out.ns2.$a.test$n" >/dev/null || ret=1
+ for rrcount in 500-txt 1000-txt 2000-txt; do
+ $DIG +tcp txt "${rrcount}.under-limit" @10.53.0.2 -p "${PORT}" >"dig.out.ns2.$rrcount.test$n"
+ grep "status: NOERROR" "dig.out.ns2.$rrcount.test$n" >/dev/null || ret=1
done
[ $ret -eq 0 ] && break
sleep 1
@@ -216,12 +212,12 @@ n=$((n + 1))
[ $ret -eq 0 ] || echo_i "failed"
status=$((status + ret))
-echo_i "checking that huge rdatasets loaded ($n)"
-for i in 0 1 2 3 4 5 6 7 8 9; do
+echo_i "checking that on-limit rdatasets loaded ($n)"
+for _attempt in 0 1 2 3 4 5 6 7 8 9; do
ret=0
- for a in a b c d; do
- $DIG +tcp txt "${a}.huge" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$a.test$n"
- grep "status: NOERROR" "dig.out.ns1.$a.test$n" >/dev/null || ret=1
+ for rrcount in 500-txt 1000-txt 2000-txt 2050-txt; do
+ $DIG +tcp txt "${rrcount}.on-limit" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$rrcount.test$n"
+ grep "status: NOERROR" "dig.out.ns1.$rrcount.test$n" >/dev/null || ret=1
done
[ $ret -eq 0 ] && break
sleep 1
@@ -230,12 +226,12 @@ n=$((n + 1))
[ $ret -eq 0 ] || echo_i "failed"
status=$((status + ret))
-echo_i "checking that huge rdatasets not transfered ($n)"
-for i in 0 1 2 3 4 5 6 7 8 9; do
+echo_i "checking that on-limit rdatasets not transfered ($n)"
+for _attempt in 0 1 2 3 4 5 6 7 8 9; do
ret=0
- for a in a b c d; do
- $DIG +tcp txt "${a}.huge" @10.53.0.2 -p "${PORT}" >"dig.out.ns2.$a.test$n"
- grep "status: SERVFAIL" "dig.out.ns2.$a.test$n" >/dev/null || ret=1
+ for rrcount in 500-txt 1000-txt 2000-txt 2050-txt; do
+ $DIG +tcp txt "${rrcount}.on-limit" @10.53.0.2 -p "${PORT}" >"dig.out.ns2.$rrcount.test$n"
+ grep "status: SERVFAIL" "dig.out.ns2.$rrcount.test$n" >/dev/null || ret=1
done
[ $ret -eq 0 ] && break
sleep 1
@@ -244,12 +240,12 @@ n=$((n + 1))
[ $ret -eq 0 ] || echo_i "failed"
status=$((status + ret))
-echo_i "checking that uber rdatasets not loaded ($n)"
-for i in 0 1 2 3 4 5 6 7 8 9; do
+echo_i "checking that over-limit rdatasets not loaded ($n)"
+for _attempt in 0 1 2 3 4 5 6 7 8 9; do
ret=0
- for a in a b c d e; do
- $DIG +tcp txt "${a}.uber" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$a.test$n"
- grep "status: SERVFAIL" "dig.out.ns1.$a.test$n" >/dev/null || ret=1
+ for rrcount in 500-txt 1000-txt 2000-txt 2050-txt 2100-txt; do
+ $DIG +tcp txt "${rrcount}.over-limit" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$rrcount.test$n"
+ grep "status: SERVFAIL" "dig.out.ns1.$rrcount.test$n" >/dev/null || ret=1
done
[ $ret -eq 0 ] && break
sleep 1
@@ -258,6 +254,29 @@ n=$((n + 1))
[ $ret -eq 0 ] || echo_i "failed"
status=$((status + ret))
+echo_i "checking that 255 types are loaded ($n)"
+for _attempt in 0 1 2 3 4 5 6 7 8 9; do
+ ret=0
+ $DIG +tcp TXT "m.255types" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.test$n"
+ grep "status: NOERROR" "dig.out.ns1.test$n" >/dev/null || ret=1
+ [ $ret -eq 0 ] && break
+ sleep 1
+done
+n=$((n + 1))
+[ $ret -eq 0 ] || echo_i "failed"
+status=$((status + ret))
+
+echo_i "checking that 255 types types are not transfered ($n)"
+for _attempt in 0 1 2 3 4 5 6 7 8 9; do
+ $DIG +tcp TXT "m.255types" @10.53.0.2 -p "${PORT}" >"dig.out.ns2.test$n"
+ grep "status: SERVFAIL" "dig.out.ns2.test$n" >/dev/null || ret=1
+ [ $ret -eq 0 ] && break
+ sleep 1
+done
+n=$((n + 1))
+[ $ret -eq 0 ] || echo_i "failed"
+status=$((status + ret))
+
echo_i "checking format transitions: text->raw->map->text ($n)"
ret=0
$CHECKZONE -D -f text -F text -o baseline.txt example.nil ns1/example.db >/dev/null
@@ -322,7 +341,7 @@ stop_server --use-rndc --port ${CONTROLPORT} ns3
rm ns3/*.jnl
restart
#shellcheck disable=SC2034
-for i in 0 1 2 3 4 5 6 7 8 9; do
+for _attempt in 0 1 2 3 4 5 6 7 8 9; do
lret=0
dig_with_opts +comm @10.53.0.3 moretext.dynamic txt >"dig.out.dynamic2.ns3.test$n"
grep "more text" "dig.out.dynamic2.ns3.test$n" >/dev/null 2>&1 || lret=1
diff --git a/bin/tests/system/reclimit/clean.sh b/bin/tests/system/reclimit/clean.sh
index 0a92f90..b63dc61 100644
--- a/bin/tests/system/reclimit/clean.sh
+++ b/bin/tests/system/reclimit/clean.sh
@@ -11,12 +11,16 @@
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
-rm -f dig.out*
-rm -f ans?/ans.run
-rm -f ans2/ans.limit
-rm -f ans4/ans.limit
-rm -f ns?/named.memstats
-rm -f ns?/named.run
-rm -f ns*/named.conf
-rm -f ns*/named.lock
-rm -f ns*/managed-keys.bind*
+rm -f ./dig.out*
+rm -f ./dsset-signed.
+rm -f ./ans?/ans.run
+rm -f ./ans2/ans.limit
+rm -f ./ans4/ans.limit
+rm -f ./ns?/named.memstats
+rm -f ./ns?/named.run
+rm -f ./ns*/named.conf
+rm -f ./ns*/named.lock
+rm -f ./ns*/managed-keys.bind*
+rm -f ./ns*/signed.db*
+rm -f ./ns*/*.db.signed
+rm -f ./ns*/Ksigned.*.key ./ns*/Ksigned.*.private
diff --git a/bin/tests/system/reclimit/ns1/named.conf.in b/bin/tests/system/reclimit/ns1/named.conf.in
index c56c0db..c345c28 100644
--- a/bin/tests/system/reclimit/ns1/named.conf.in
+++ b/bin/tests/system/reclimit/ns1/named.conf.in
@@ -23,6 +23,7 @@ options {
recursion no;
dnssec-validation no;
max-records-per-type 0;
+ max-types-per-name 0;
};
zone "." { type primary; file "root.db"; };
@@ -31,3 +32,8 @@ zone "big." {
type primary;
file "big.db";
};
+
+zone "signed." {
+ type primary;
+ file "signed.db.signed";
+};
diff --git a/bin/tests/system/reclimit/ns1/root.db b/bin/tests/system/reclimit/ns1/root.db
index 30e175b..7b7c119 100644
--- a/bin/tests/system/reclimit/ns1/root.db
+++ b/bin/tests/system/reclimit/ns1/root.db
@@ -20,5 +20,8 @@ direct.example.net. 60 IN A 10.53.0.2
example.com. 60 IN NS direct.example.com.
direct.example.com. 60 IN A 10.53.0.4
-big. in NS ns.big.
+big. IN NS ns.big.
ns.big. 60 IN A 10.53.0.1
+
+signed. IN NS ns.signed.
+ns.signed. 60 IN A 10.53.0.1
diff --git a/bin/tests/system/reclimit/ns3/named6.conf.in b/bin/tests/system/reclimit/ns3/named6.conf.in
new file mode 100644
index 0000000..e1607e2
--- /dev/null
+++ b/bin/tests/system/reclimit/ns3/named6.conf.in
@@ -0,0 +1,43 @@
+/*
+ * 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 {
+ directory ".";
+ 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; };
+ servfail-ttl 0;
+ qname-minimization disabled;
+ max-recursion-depth 12;
+ recursion yes;
+ dnssec-validation yes;
+ max-records-per-type 0;
+ max-types-per-name 0;
+};
+
+trust-anchors { };
+
+key rndc_key {
+ secret "1234abcd8765";
+ algorithm @DEFAULT_HMAC@;
+};
+
+controls {
+ inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+zone "." { type hint; file "hints.db"; };
diff --git a/bin/tests/system/reclimit/setup.sh b/bin/tests/system/reclimit/setup.sh
index 5b39cdf..8ad0586 100644
--- a/bin/tests/system/reclimit/setup.sh
+++ b/bin/tests/system/reclimit/setup.sh
@@ -16,3 +16,8 @@ SYSTEMTESTTOP=..
copy_setports ns1/named.conf.in ns1/named.conf
copy_setports ns3/named1.conf.in ns3/named.conf
+
+sed -e s/big[.]/signed./g <ns1/big.db >ns1/signed.db
+$KEYGEN -K ns1 -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -f KSK signed >/dev/null 2>&1
+$KEYGEN -K ns1 -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" signed >/dev/null 2>&1
+$SIGNER -K ns1 -S -f ns1/signed.db.signed -o signed ns1/signed.db >/dev/null
diff --git a/bin/tests/system/reclimit/tests.sh b/bin/tests/system/reclimit/tests.sh
index b332e38..9bbe2e0 100644
--- a/bin/tests/system/reclimit/tests.sh
+++ b/bin/tests/system/reclimit/tests.sh
@@ -14,7 +14,9 @@
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
-DIGOPTS="-p ${PORT}"
+dig_with_opts() {
+ $DIG -p "${PORT}" +retries=0 "$@"
+}
status=0
n=0
@@ -65,12 +67,12 @@ echo_i "attempt excessive-depth lookup ($n)"
ret=0
echo "1000" >ans2/ans.limit
echo "1000" >ans4/ans.limit
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.4 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect1.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.4 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect1.example.org >dig.out.1.test$n || ret=1
grep "status: SERVFAIL" dig.out.1.test$n >/dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
check_query_count dig.out.2.test$n dig.out.4.test$n 27 14
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$(expr $status + $ret)
@@ -81,12 +83,12 @@ ret=0
echo "12" >ans2/ans.limit
echo "12" >ans4/ans.limit
ns3_reset ns3/named1.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.4 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect2.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.4 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect2.example.org >dig.out.1.test$n || ret=1
grep "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
check_query_count dig.out.2.test$n dig.out.4.test$n 50 26
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$(expr $status + $ret)
@@ -98,12 +100,12 @@ echo_i "attempt excessive-depth lookup ($n)"
ret=0
echo "12" >ans2/ans.limit
ns3_reset ns3/named2.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.4 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect3.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.4 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect3.example.org >dig.out.1.test$n || ret=1
grep "status: SERVFAIL" dig.out.1.test$n >/dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
check_query_count dig.out.2.test$n dig.out.4.test$n 13 7
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$(expr $status + $ret)
@@ -114,12 +116,12 @@ ret=0
echo "5" >ans2/ans.limit
echo "5" >ans4/ans.limit
ns3_reset ns3/named2.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.4 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect4.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.4 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect4.example.org >dig.out.1.test$n || ret=1
grep "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
check_query_count dig.out.2.test$n dig.out.4.test$n 22 12
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$(expr $status + $ret)
@@ -132,14 +134,14 @@ ret=0
echo "13" >ans2/ans.limit
echo "13" >ans4/ans.limit
ns3_reset ns3/named3.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.4 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect5.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.4 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect5.example.org >dig.out.1.test$n || ret=1
if ns3_sends_aaaa_queries; then
grep "status: SERVFAIL" dig.out.1.test$n >/dev/null || ret=1
fi
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1
eval count=$(cat dig.out.2.test$n)
[ $count -le 50 ] || {
ret=1
@@ -153,10 +155,10 @@ echo_i "attempt permissible lookup ($n)"
ret=0
echo "12" >ans2/ans.limit
ns3_reset ns3/named3.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect6.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect6.example.org >dig.out.1.test$n || ret=1
grep "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
eval count=$(cat dig.out.2.test$n)
[ $count -le 50 ] || {
ret=1
@@ -172,12 +174,12 @@ echo_i "attempt excessive-queries lookup ($n)"
ret=0
echo "11" >ans2/ans.limit
ns3_reset ns3/named4.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect7.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect7.example.org >dig.out.1.test$n || ret=1
if ns3_sends_aaaa_queries; then
grep "status: SERVFAIL" dig.out.1.test$n >/dev/null || ret=1
fi
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
eval count=$(cat dig.out.2.test$n)
[ $count -le 40 ] || {
ret=1
@@ -191,10 +193,10 @@ echo_i "attempt permissible lookup ($n)"
ret=0
echo "9" >ans2/ans.limit
ns3_reset ns3/named4.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS @10.53.0.3 indirect8.example.org >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts @10.53.0.3 indirect8.example.org >dig.out.1.test$n || ret=1
grep "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
eval count=$(cat dig.out.2.test$n)
[ $count -le 40 ] || {
ret=1
@@ -207,12 +209,12 @@ n=$(expr $n + 1)
echo_i "attempting NS explosion ($n)"
ret=0
ns3_reset ns3/named4.conf.in
-$DIG $DIGOPTS @10.53.0.2 reset >/dev/null || ret=1
-$DIG $DIGOPTS +short @10.53.0.3 ns1.1.example.net >dig.out.1.test$n || ret=1
-$DIG $DIGOPTS +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
+dig_with_opts @10.53.0.2 reset >/dev/null || ret=1
+dig_with_opts +short @10.53.0.3 ns1.1.example.net >dig.out.1.test$n || ret=1
+dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1
eval count=$(cat dig.out.2.test$n)
[ $count -lt 50 ] || ret=1
-$DIG $DIGOPTS +short @10.53.0.7 count txt >dig.out.3.test$n || ret=1
+dig_with_opts +short @10.53.0.7 count txt >dig.out.3.test$n || ret=1
eval count=$(cat dig.out.3.test$n)
[ $count -lt 50 ] || {
ret=1
@@ -224,13 +226,254 @@ status=$(expr $status + $ret)
n=$((n + 1))
echo_i "checking RRset that exceeds max-records-per-type ($n)"
ret=0
-$DIG $DIGOPTS @10.53.0.3 biganswer.big >dig.out.1.test$n || ret=1
+dig_with_opts @10.53.0.3 biganswer.big >dig.out.1.test$n || ret=1
grep 'status: SERVFAIL' dig.out.1.test$n >/dev/null || ret=1
ns3_reset ns3/named5.conf.in
-$DIG $DIGOPTS @10.53.0.3 biganswer.big >dig.out.2.test$n || ret=1
+dig_with_opts @10.53.0.3 biganswer.big >dig.out.2.test$n || ret=1
grep 'status: NOERROR' dig.out.2.test$n >/dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
+check_manytypes() (
+ i=$1
+ name=$2
+ type=$3
+ expected=$4
+ exname=$5
+ extype=$6
+ ttl=$7
+ neq_ttl=$8
+
+ if ! dig_with_opts @10.53.0.3 IN "$type" "$name" >"dig.out.$i.$type.test$n"; then
+ exit 1
+ fi
+
+ if ! grep 'status: '"${expected}"'' "dig.out.$i.$type.test$n" >/dev/null; then
+ exit 1
+ fi
+
+ if [ -n "$ttl" ] && ! grep -q "^$exname.[[:space:]]*${ttl}[[:space:]]*IN[[:space:]]*$extype" "dig.out.$i.$type.test$n"; then
+ exit 1
+ fi
+
+ if [ -n "${neq_ttl}" ] && grep -q "^$exname.[[:space:]]*${neq_ttl}[[:space:]]*IN[[:space:]]*$type" "dig.out.$i.$type.test$n"; then
+ exit 1
+ fi
+
+ exit 0
+)
+
+n=$((n + 1))
+ret=0
+echo_i "checking that priority names under the max-types-per-name limit get cached ($n)"
+
+# Query for NXDOMAIN for items on our priority list - these should get cached
+for rrtype in AAAA MX NS; do
+ check_manytypes 1 manytypes.big "${rrtype}" NOERROR big SOA 60 || ret=1
+done
+# Wait at least 1 second
+for rrtype in AAAA MX NS; do
+ check_manytypes 2 manytypes.big "${rrtype}" NOERROR big SOA "" 60 || ret=1
+done
+
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+if [ $status -ne 0 ]; then exit 1; fi
+
+ns3_flush
+
+n=$((n + 1))
+ret=0
+echo_i "checking that NXDOMAIN names under the max-types-per-name limit get cached ($n)"
+
+# Query for 10 NXDOMAIN types
+for ntype in $(seq 65270 65279); do
+ check_manytypes 1 manytypes.big "TYPE${ntype}" NOERROR big SOA 60 || ret=1
+done
+# Wait at least 1 second
+sleep 1
+# Query for 10 NXDOMAIN types again - these should be cached
+for ntype in $(seq 65270 65279); do
+ check_manytypes 2 manytypes.big "TYPE${ntype}" NOERROR big SOA "" 60 || ret=1
+done
+
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+if [ $status -ne 0 ]; then exit 1; fi
+
+n=$((n + 1))
+ret=0
+echo_i "checking that existing names under the max-types-per-name limit get cached ($n)"
+
+# Limited to 10 types - these should be cached and the previous record should be evicted
+for ntype in $(seq 65280 65289); do
+ check_manytypes 1 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" 60 || ret=1
+done
+# Wait at least one second
+sleep 1
+# Limited to 10 types - these should be cached
+for ntype in $(seq 65280 65289); do
+ check_manytypes 2 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" "" 60 || ret=1
+done
+
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+if [ $status -ne 0 ]; then exit 1; fi
+
+n=$((n + 1))
+ret=0
+echo_i "checking that NXDOMAIN names over the max-types-per-name limit don't get cached ($n)"
+
+# Query for 10 NXDOMAIN types
+for ntype in $(seq 65270 65279); do
+ check_manytypes 1 manytypes.big "TYPE${ntype}" NOERROR big SOA 0 || ret=1
+done
+# Wait at least 1 second
+sleep 1
+# Query for 10 NXDOMAIN types again - these should not be cached
+for ntype in $(seq 65270 65279); do
+ check_manytypes 2 manytypes.big "TYPE${ntype}" NOERROR big SOA 0 || ret=1
+done
+
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+if [ $status -ne 0 ]; then exit 1; fi
+
+n=$((n + 1))
+ret=0
+echo_i "checking that priority NXDOMAIN names over the max-types-per-name limit get cached ($n)"
+
+# Query for NXDOMAIN for items on our priority list - these should get cached
+for rrtype in AAAA MX NS; do
+ check_manytypes 1 manytypes.big "${rrtype}" NOERROR big SOA 60 || ret=1
+done
+# Wait at least 1 second
+for rrtype in AAAA MX NS; do
+ check_manytypes 2 manytypes.big "${rrtype}" NOERROR big SOA "" 60 || ret=1
+done
+
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+if [ $status -ne 0 ]; then exit 1; fi
+
+n=$((n + 1))
+ret=0
+echo_i "checking that priority name over the max-types-per-name get cached ($n)"
+
+# Query for an item on our priority list - it should get cached
+check_manytypes 1 manytypes.big "A" NOERROR manytypes.big A 60 || ret=1
+# Wait at least 1 second
+sleep 1
+# Query the same name again - it should be in the cache
+check_manytypes 2 manytypes.big "A" NOERROR big manytypes.A "" 60 || ret=1
+
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+if [ $status -ne 0 ]; then exit 1; fi
+
+ns3_flush
+
+n=$((n + 1))
+ret=0
+echo_i "checking that priority name over the max-types-per-name don't get evicted ($n)"
+
+# Query for an item on our priority list - it should get cached
+check_manytypes 1 manytypes.big "A" NOERROR manytypes.big A 60 || ret=1
+# Query for 10 more types - this should not evict A record
+for ntype in $(seq 65280 65289); do
+ check_manytypes 1 manytypes.big "TYPE${ntype}" NOERROR manytypes.big || ret=1
+done
+# Wait at least 1 second
+sleep 1
+# Query the same name again - it should be in the cache
+check_manytypes 2 manytypes.big "A" NOERROR manytypes.big A "" 60 || ret=1
+# This one was first in the list and should have been evicted
+check_manytypes 2 manytypes.big "TYPE65280" NOERROR manytypes.big TYPE65280 60 || ret=1
+
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+if [ $status -ne 0 ]; then exit 1; fi
+
+ns3_flush
+
+n=$((n + 1))
+ret=0
+echo_i "checking that non-priority types cause eviction ($n)"
+
+# Everything on top of that will cause the cache eviction
+for ntype in $(seq 65280 65299); do
+ check_manytypes 1 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" 60 || ret=1
+done
+# Wait at least one second
+sleep 1
+# These should have TTL != 60 now
+for ntype in $(seq 65290 65299); do
+ check_manytypes 2 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" "" 60 || ret=1
+done
+# These should have been evicted
+for ntype in $(seq 65280 65289); do
+ check_manytypes 3 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" 60 || ret=1
+done
+# These should have been evicted by the previous block
+for ntype in $(seq 65290 65299); do
+ check_manytypes 4 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" 60 || ret=1
+done
+
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+if [ $status -ne 0 ]; then exit 1; fi
+
+ns3_flush
+
+n=$((n + 1))
+ret=0
+echo_i "checking that signed names under the max-types-per-name limit get cached ($n)"
+
+# Go through the 10 items, this should result in 20 items (type + rrsig(type))
+for ntype in $(seq 65280 65289); do
+ check_manytypes 1 manytypes.signed "TYPE${ntype}" NOERROR manytypes.signed "TYPE${ntype}" 60 || ret=1
+done
+
+# Wait at least one second
+sleep 1
+
+# These should have TTL != 60 now
+for ntype in $(seq 65285 65289); do
+ check_manytypes 2 manytypes.signed "TYPE${ntype}" NOERROR manytypes.signed "TYPE${ntype}" "" 60 || ret=1
+done
+
+# These should have been evicted
+for ntype in $(seq 65280 65284); do
+ check_manytypes 3 manytypes.signed "TYPE${ntype}" NOERROR manytypes.signed "TYPE${ntype}" 60 || ret=1
+done
+
+# These should have been evicted by the previous block
+for ntype in $(seq 65285 65289); do
+ check_manytypes 4 manytypes.signed "TYPE${ntype}" NOERROR manytypes.signed "TYPE${ntype}" 60 || ret=1
+done
+
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+if [ $status -ne 0 ]; then exit 1; fi
+
+n=$((n + 1))
+ret=0
+echo_i "checking that lifting the limit will allow everything to get cached ($n)"
+
+# Lift the limit
+ns3_reset ns3/named6.conf.in
+
+for ntype in $(seq 65280 65534); do
+ check_manytypes 1 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" 60 || ret=1
+done
+# Wait at least one second
+sleep 1
+for ntype in $(seq 65280 65534); do
+ check_manytypes 2 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" "" 60 || ret=1
+done
+
+if [ $ret -ne 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
--
2.51.1