]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
add test cases for several FORMERR code paths:
authorMark Andrews <marka@isc.org>
Mon, 29 Jan 2024 18:21:37 +0000 (10:21 -0800)
committerMark Andrews <marka@isc.org>
Fri, 17 May 2024 03:39:22 +0000 (13:39 +1000)
  - duplicated question
  - duplicated answer
  - qtype as an answer
  - two question types
  - question names
  - nsec3 bad owner name
  - short record
  - short question
  - mismatching question class
  - bad record owner name
  - mismatched class in record
  - mismatched KEY class
  - OPT wrong owner name
  - invalid RRSIG "covers" type
  - UPDATE malformed delete type
  - TSIG wrong class
  - TSIG not the last record

21 files changed:
.reuse/dep5
bin/tests/system/formerr/badnsec3owner [new file with mode: 0644]
bin/tests/system/formerr/badrecordname [new file with mode: 0644]
bin/tests/system/formerr/clean.sh
bin/tests/system/formerr/dupans [new file with mode: 0644]
bin/tests/system/formerr/dupquestion [new file with mode: 0644]
bin/tests/system/formerr/keyclass [new file with mode: 0644]
bin/tests/system/formerr/malformeddeltype [new file with mode: 0644]
bin/tests/system/formerr/malformedrrsig [new file with mode: 0644]
bin/tests/system/formerr/optwrongname [new file with mode: 0644]
bin/tests/system/formerr/qtypeasanswer [new file with mode: 0644]
bin/tests/system/formerr/questionclass [new file with mode: 0644]
bin/tests/system/formerr/shortquestion [new file with mode: 0644]
bin/tests/system/formerr/shortrecord [new file with mode: 0644]
bin/tests/system/formerr/tests.sh
bin/tests/system/formerr/tsignotlast [new file with mode: 0644]
bin/tests/system/formerr/tsigwrongclass [new file with mode: 0644]
bin/tests/system/formerr/twoquestionnames [new file with mode: 0644]
bin/tests/system/formerr/twoquestiontypes [moved from bin/tests/system/formerr/twoquestions with 64% similarity]
bin/tests/system/formerr/wrongclass [new file with mode: 0644]
lib/dns/message.c

index ff17134e1b1efaf5414dea34130baca077b2f855..a58145d21436947b33c2e571963a7492d051f11a 100644 (file)
@@ -39,10 +39,25 @@ Files: **/*.after*
        bin/tests/system/doth/CA/index.txt
        bin/tests/system/doth/CA/index.txt.attr
        bin/tests/system/doth/CA/serial
-       bin/tests/system/notify/ns4/named.port.in
+       bin/tests/system/formerr/badnsec3owner
+       bin/tests/system/formerr/badrecordname
+       bin/tests/system/formerr/dupans
+       bin/tests/system/formerr/dupquestion
+       bin/tests/system/formerr/keyclass
+       bin/tests/system/formerr/malformeddeltype
+       bin/tests/system/formerr/malformedrrsig
        bin/tests/system/formerr/nametoolong
        bin/tests/system/formerr/noquestions
-       bin/tests/system/formerr/twoquestions
+       bin/tests/system/formerr/optwrongname
+       bin/tests/system/formerr/qtypeasanswer
+       bin/tests/system/formerr/questionclass
+       bin/tests/system/formerr/shortquestion
+       bin/tests/system/formerr/shortrecord
+       bin/tests/system/formerr/tsignotlast
+       bin/tests/system/formerr/tsigwrongclass
+       bin/tests/system/formerr/twoquestionnames
+       bin/tests/system/formerr/twoquestiontypes
+       bin/tests/system/formerr/wrongclass
        bin/tests/system/forward/CA/CA.cfg
        bin/tests/system/forward/CA/README
        bin/tests/system/forward/CA/index.txt
@@ -59,6 +74,7 @@ Files: **/*.after*
        bin/tests/system/masterfile/knowngood.include
        bin/tests/system/masterfile/knowngood.ttl1
        bin/tests/system/masterfile/knowngood.ttl2
+       bin/tests/system/notify/ns4/named.port.in
        bin/tests/system/nsupdate/CA/CA.cfg
        bin/tests/system/nsupdate/CA/README
        bin/tests/system/nsupdate/CA/index.txt
diff --git a/bin/tests/system/formerr/badnsec3owner b/bin/tests/system/formerr/badnsec3owner
new file mode 100644 (file)
index 0000000..de6e692
--- /dev/null
@@ -0,0 +1,7 @@
+# bad NSEC3 owner (:) not in base32hex valid characters
+# header: id=0008 opcode=query questions=1 authority=1
+00 08 00 00 00 01 00 00 00 01 00 00
+# question: ./A/IN
+00 00 01 00 01
+# :./NSEC3/IN/1 length=7 hashtype=240 flags=0 interations=0 salt=- hashlen=1 hash=ff
+01 58 00 00 32 00 01 00 00 00 01 00 07 f0 00 00 00 00 01 ff
diff --git a/bin/tests/system/formerr/badrecordname b/bin/tests/system/formerr/badrecordname
new file mode 100644 (file)
index 0000000..f79df49
--- /dev/null
@@ -0,0 +1,21 @@
+# oversized owner name
+# header: additional=1
+00 00 00 00 00 00 00 00 00 00 00 01
+# owner name too big (256 octets) A/IN/1 0.0.0.0
+0f 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
+0f 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
+0f 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
+0f 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
+0f 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
+0f 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
+0f 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
+0f 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
+0f 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
+0f 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
+0f 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
+0f 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
+0f 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
+0f 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
+0f 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41
+0e 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00
+00 01 00 01 00 00 00 01 00 04 00 00 00 00
index c22ae71c84c457bed6b6c5de704ce68ff91b7295..886771b26fd38bdfa0028b2ab7a82b3ba1ffb2c4 100644 (file)
 # See the COPYRIGHT file distributed with this work for additional
 # information regarding copyright ownership.
 
+rm -f badnsec3owner.out
+rm -f badrecordname.out
+rm -f dupans.out
+rm -f dupquestion.out
+rm -f keyclass.out
+rm -f malformeddeltype.out
+rm -f malformedrrsig.out
 rm -f nametoolong.out
-rm -f twoquestions.out
 rm -f noquestions.out
+rm -f optwrongname.out
+rm -f ns*/managed-keys.bind*
 rm -f ns*/named.conf
-rm -f ns*/named.run
 rm -f ns*/named.memstats
-rm -f ns*/managed-keys.bind*
+rm -f ns*/named.run
+rm -f qtypeasanswer.out
+rm -f questionclass.out
+rm -f shortquestion.out
+rm -f shortrecord.out
+rm -f tsignotlast.out
+rm -f tsigwrongclass.out
+rm -f twoquestionnames.out
+rm -f twoquestiontypes.out
+rm -f wrongclass.out
diff --git a/bin/tests/system/formerr/dupans b/bin/tests/system/formerr/dupans
new file mode 100644 (file)
index 0000000..142022a
--- /dev/null
@@ -0,0 +1,8 @@
+# multiple singletons (SOA)
+# header questions=1 answers=2
+00 00 00 00 00 01 00 02 00 00 00 00
+# question SOA/IN
+00 00 06 00 01
+# 2 SOA records that differ in expire
+00 00 06 00 01 00 00 00 01 00 16 00 00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05
+00 00 06 00 01 00 00 00 01 00 16 00 00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 06
diff --git a/bin/tests/system/formerr/dupquestion b/bin/tests/system/formerr/dupquestion
new file mode 100644 (file)
index 0000000..327b8ca
--- /dev/null
@@ -0,0 +1,10 @@
+# header: 2 questions
+00 00 00 00 00 02 00 00 00 00 00 00
+# question: AAAAAAAAAAAAAA./A/IN
+0e 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00
+00 01
+00 01
+# question: AAAAAAAAAAAAAA./A/IN
+0e 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00
+00 01
+00 01
diff --git a/bin/tests/system/formerr/keyclass b/bin/tests/system/formerr/keyclass
new file mode 100644 (file)
index 0000000..c84568a
--- /dev/null
@@ -0,0 +1,7 @@
+# mismatched key class
+# header: questions=1 additional=1
+00 00 00 00 00 01 00 00 00 00 00 01
+# question: ./A/IN
+00 00 01 00 01
+# additional: ./KEY/CLASS2 flags=0 protocol=0 algorithm=248 keydata=00
+00 00 19 00 02 00 00 00 01 00 05 00 00 00 f8 00
diff --git a/bin/tests/system/formerr/malformeddeltype b/bin/tests/system/formerr/malformeddeltype
new file mode 100644 (file)
index 0000000..2d14ae4
--- /dev/null
@@ -0,0 +1,5 @@
+# UPDATE malformed 'delete type' update change (non empty data)
+# header: UPDATE authority=1
+00 00 28 00 00 00 00 00 00 01 00 00
+# ./A/ANY TTL=0 length=1 data=00
+00 00 01 00 ff 00 00 00 00 00 01 00
diff --git a/bin/tests/system/formerr/malformedrrsig b/bin/tests/system/formerr/malformedrrsig
new file mode 100644 (file)
index 0000000..07d2af0
--- /dev/null
@@ -0,0 +1,5 @@
+# malformed RRRSIG
+# header: QUERY, additional=1
+00 00 00 00 00 00 00 00 00 00 00 01
+# ./RRSIG/IN TTL=1 covers=0 algorithm=240 labels=0 ttl=1 expire=2 signed=3 id=0
+00 00 2e 00 01 00 00 00 01 00 14 00 00 f0 00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 00
diff --git a/bin/tests/system/formerr/optwrongname b/bin/tests/system/formerr/optwrongname
new file mode 100644 (file)
index 0000000..7b486d9
--- /dev/null
@@ -0,0 +1,5 @@
+# OPT record with wrong name (not .)
+# header: QUERY, additional=1
+00 00 00 00 00 00 00 00 00 00 00 01
+# OPT record (owner A.)
+01 41 00 00 29 00 01 00 00 00 00 00 00
diff --git a/bin/tests/system/formerr/qtypeasanswer b/bin/tests/system/formerr/qtypeasanswer
new file mode 100644 (file)
index 0000000..d254d1d
--- /dev/null
@@ -0,0 +1,5 @@
+# QTYPE-only type as answer
+# header, answers=1
+00 00 00 00 00 00 00 01 00 00 00 00
+# ./MAILB/IN
+00 00 fd 00 01 00 00 00 01 00 00
diff --git a/bin/tests/system/formerr/questionclass b/bin/tests/system/formerr/questionclass
new file mode 100644 (file)
index 0000000..b34d1e3
--- /dev/null
@@ -0,0 +1,7 @@
+# two questions of different classes
+# header: QUERY, questions=2
+00 00 00 00 00 02 00 00 00 00 00 00
+# ./A/IN
+00 00 01 00 01
+# ./A/CLASS2
+00 00 01 00 02
diff --git a/bin/tests/system/formerr/shortquestion b/bin/tests/system/formerr/shortquestion
new file mode 100644 (file)
index 0000000..168ed90
--- /dev/null
@@ -0,0 +1,5 @@
+# truncated question section
+# header: QUERY, questions=1
+00 00 00 00 00 01 00 00 00 00 00 00
+# truncated question (no class)
+00 00 01
diff --git a/bin/tests/system/formerr/shortrecord b/bin/tests/system/formerr/shortrecord
new file mode 100644 (file)
index 0000000..d9a2ab7
--- /dev/null
@@ -0,0 +1,5 @@
+# truncated record
+# header: QUERY, additional=1
+00 09 00 00 00 00 00 00 00 00 00 01
+# truncated A record (no ttl, length or data)
+00 00 01 00 01
index 1d1aeafd677d33e925c6ae217b3d21f0a92265ac..2ec7448fe38012ac1252cfbf8166f78b46ec475f 100644 (file)
@@ -25,14 +25,46 @@ if [ "${ans}" != "got: 000080010000000000000000" ]; then
   status=$((status + 1))
 fi
 
-echo_i "two questions"
-$PERL formerr.pl -a 10.53.0.1 -p ${PORT} twoquestions >twoquestions.out
-ans=$(grep got: twoquestions.out)
+echo_i "two question names"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} twoquestionnames >twoquestionnames.out
+ans=$(grep got: twoquestionnames.out)
 if [ "${ans}" != "got: 000080010000000000000000" ]; then
   echo_i "failed"
   status=$((status + 1))
 fi
 
+echo_i "two question types"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} twoquestiontypes >twoquestiontypes.out
+ans=$(grep got: twoquestiontypes.out)
+if [ "${ans}" != "got: 0000800100020000000000000e41414141414141414141414141410000010001c00c00020001" ]; then
+  echo_i "failed"
+  status=$((status + 1))
+fi
+
+echo_i "duplicate questions"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} dupquestion >dupquestion.out
+ans=$(grep got: dupquestion.out)
+if [ "${ans}" != "got: 000080010000000000000000" ]; then
+  echo_i "failed"
+  status=$(expr $status + 1)
+fi
+
+echo_i "duplicate answer"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} dupans >dupans.out
+ans=$(grep got: dupans.out)
+if [ "${ans}" != "got: 0000800100010000000000000000060001" ]; then
+  echo_i "failed"
+  status=$(expr $status + 1)
+fi
+
+echo_i "question only type in answer"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} qtypeasanswer >qtypeasanswer.out
+ans=$(grep got: qtypeasanswer.out)
+if [ "${ans}" != "got: 000080010000000000000000" ]; then
+  echo_i "failed"
+  status=$(expr $status + 1)
+fi
+
 # this would be NOERROR if it included a COOKIE option,
 # but is a FORMERR without one.
 echo_i "empty question section (and no COOKIE option)"
@@ -43,6 +75,103 @@ if [ "${ans}" != "got: 000080010000000000000000" ]; then
   status=$((status + 1))
 fi
 
+echo_i "bad nsec3 owner"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} badnsec3owner >badnsec3owner.out
+ans=$(grep got: badnsec3owner.out)
+# SERVFAIL (2) rather than FORMERR (1)
+if [ "${ans}" != "got: 0008800200010000000000000000010001" ]; then
+  echo_i "failed"
+  status=$(expr $status + 1)
+fi
+
+echo_i "short record before rdata "
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} shortrecord >shortrecord.out
+ans=$(grep got: shortrecord.out)
+if [ "${ans}" != "got: 000980010000000000000000" ]; then
+  echo_i "failed"
+  status=$(expr $status + 1)
+fi
+
+echo_i "short question"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} shortquestion >shortquestion.out
+ans=$(grep got: shortquestion.out)
+if [ "${ans}" != "got: 000080010000000000000000" ]; then
+  echo_i "failed"
+  status=$(expr $status + 1)
+fi
+
+echo_i "mismatch classes in question section"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} questionclass >questionclass.out
+ans=$(grep got: questionclass.out)
+if [ "${ans}" != "got: 000080010000000000000000" ]; then
+  echo_i "failed"
+  status=$(expr $status + 1)
+fi
+
+echo_i "bad record owner name"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} badrecordname >badrecordname.out
+ans=$(grep got: badrecordname.out)
+if [ "${ans}" != "got: 000080010000000000000000" ]; then
+  echo_i "failed"
+  status=$(expr $status + 1)
+fi
+
+echo_i "mismatched class in record"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} wrongclass >wrongclass.out
+ans=$(grep got: wrongclass.out)
+if [ "${ans}" != "got: 000080010000000000000000" ]; then
+  echo_i "failed"
+  status=$(expr $status + 1)
+fi
+
+echo_i "mismatched KEY class"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} keyclass >keyclass.out
+ans=$(grep got: keyclass.out)
+if [ "${ans}" != "got: 0000800100010000000000000000010001" ]; then
+  echo_i "failed"
+  status=$(expr $status + 1)
+fi
+
+echo_i "OPT wrong owner name"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} optwrongname >optwrongname.out
+ans=$(grep got: optwrongname.out)
+if [ "${ans}" != "got: 000080010000000000000000" ]; then
+  echo_i "failed"
+  status=$(expr $status + 1)
+fi
+
+echo_i "RRSIG invalid covers"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} malformedrrsig >malformedrrsig.out
+ans=$(grep got: malformedrrsig.out)
+if [ "${ans}" != "got: 000080010000000000000000" ]; then
+  echo_i "failed"
+  status=$(expr $status + 1)
+fi
+
+echo_i "UPDATE malformed delete type"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} malformeddeltype >malformeddeltype.out
+ans=$(grep got: malformeddeltype.out)
+if [ "${ans}" != "got: 0000a8010000000000000000" ]; then
+  echo_i "failed"
+  status=$(expr $status + 1)
+fi
+
+echo_i "TSIG wrong class"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} tsigwrongclass >tsigwrongclass.out
+ans=$(grep got: tsigwrongclass.out)
+if [ "${ans}" != "got: 000080010000000000000000" ]; then
+  echo_i "failed"
+  status=$(expr $status + 1)
+fi
+
+echo_i "TSIG not last"
+$PERL formerr.pl -a 10.53.0.1 -p ${PORT} tsignotlast >tsignotlast.out
+ans=$(grep got: tsignotlast.out)
+if [ "${ans}" != "got: 000080010000000000000000" ]; then
+  echo_i "failed"
+  status=$(expr $status + 1)
+fi
+
 echo_i "exit status: $status"
 
 [ $status -eq 0 ] || exit 1
diff --git a/bin/tests/system/formerr/tsignotlast b/bin/tests/system/formerr/tsignotlast
new file mode 100644 (file)
index 0000000..108936c
--- /dev/null
@@ -0,0 +1,8 @@
+# SIG not last in additional
+# header: QUERY additional=2
+00 00 00 00 00 00 00 00 00 00 00 02
+# Additional records:
+# SIG record (class ANY)
+00 00 fa 00 ff 00 00 00 01 00 12 00 01 02 03 04 05 06 01 02 00 01 00 00 00 00 00 00 00
+# A record
+00 00 01 00 01 00 00 00 01 00 04 00 00 00 00
diff --git a/bin/tests/system/formerr/tsigwrongclass b/bin/tests/system/formerr/tsigwrongclass
new file mode 100644 (file)
index 0000000..29aea08
--- /dev/null
@@ -0,0 +1,5 @@
+# TSIG wrong class
+# header: QUERY, additional=1
+00 00 00 00 00 00 00 00 00 00 00 01
+# class should be ANY (00 ff) not IN (00 01)
+00 00 fa 00 01 00 00 00 01 00 12 00 01 02 03 04 05 06 01 02 00 01 00 00 00 00 00 00 00
diff --git a/bin/tests/system/formerr/twoquestionnames b/bin/tests/system/formerr/twoquestionnames
new file mode 100644 (file)
index 0000000..f363a23
--- /dev/null
@@ -0,0 +1,11 @@
+# two questions with different names
+00 00 00 00 00 02 00 00 00 00 00 00
+# AAAAAAAAAAAAAA./A/IN
+0e 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00
+00 01
+00 01
+# AAAAAAAAAAAAAB./A/IN
+0e 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00
+0e 41 41 41 41 41 41 41 41 41 41 41 41 41 42 00
+00 01
+00 01
similarity index 64%
rename from bin/tests/system/formerr/twoquestions
rename to bin/tests/system/formerr/twoquestiontypes
index 2192e3d208dfc27e62be69e81e94725cbddbb461..451f8f6ee4e42521dd3e606b61bb825922570bad 100644 (file)
@@ -1,7 +1,10 @@
+# two questions that differ by type
 00 00 00 00 00 02 00 00 00 00 00 00
+# AAAAAAAAAAAAAAA./A/IN
 0e 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00
 00 01
-00 02
-0e 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00
 00 01
+# AAAAAAAAAAAAAAA./NS/IN
+0e 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00
+00 02
 00 01
diff --git a/bin/tests/system/formerr/wrongclass b/bin/tests/system/formerr/wrongclass
new file mode 100644 (file)
index 0000000..96211e0
--- /dev/null
@@ -0,0 +1,7 @@
+# class mismatch
+# header: QUERY, additional=2
+00 00 00 00 00 00 00 00 00 00 00 02
+# ./A/IN
+00 00 01 00 01 00 00 00 01 00 04 00 00 00 00
+# ./TYPE65280/CLASS256
+00 ff 00 01 00 02 00 00 01 00 04 00 00 00 00
index 161db7a5e5f903d81d1a205156a60845e3c2ef51..4f0d7740faa1dc7718ec7bdd62b3c6be93abd420 100644 (file)
@@ -1125,6 +1125,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx,
        }
 
        if (seen_problem) {
+               /* XXX test coverage */
                result = DNS_R_RECOVERABLE;
        }
 
@@ -1453,6 +1454,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx,
                                if (msg->rdclass != dns_rdataclass_any &&
                                    msg->rdclass != rdclass)
                                {
+                                       /* XXX test coverage */
                                        DO_ERROR(DNS_R_FORMERR);
                                }
                        }
@@ -1676,6 +1678,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx,
 
                if (seen_problem) {
                        if (free_name) {
+                               /* XXX test coverage */
                                dns_message_puttempname(msg, &name);
                        }
                        free_name = false;
@@ -1694,6 +1697,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t dctx,
            ((msg->flags & DNS_MESSAGEFLAG_TC) == 0) && !preserve_order &&
            !auth_signed(section))
        {
+               /* XXX test coverage */
                DO_ERROR(DNS_R_FORMERR);
        }