diff --git a/CHANGES b/CHANGES index c4f89d400a..21ef323a23 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +4615. [bug] AD could be set on truncated answer with no records + present in the answer and authority sections. + [RT #45140] + 4614. [test] Fixed an error in the sockaddr unit test. [RT #45146] 4613. [func] By default, the maximum size of a zone journal file diff --git a/bin/tests/system/resolver/ns6/keygen.sh b/bin/tests/system/resolver/ns6/keygen.sh index bfdee21f07..1c126236e6 100644 --- a/bin/tests/system/resolver/ns6/keygen.sh +++ b/bin/tests/system/resolver/ns6/keygen.sh @@ -16,7 +16,7 @@ zonefile="${zone}.db" infile="${zonefile}.in" cp $infile $zonefile ksk=`$KEYGEN -q -3 -r $RANDFILE -fk $zone` -zsk=`$KEYGEN -q -3 -r $RANDFILE $zone` +zsk=`$KEYGEN -q -3 -r $RANDFILE -b 2048 $zone` cat $ksk.key $zsk.key >> $zonefile $SIGNER -P -r $RANDFILE -o $zone $zonefile > /dev/null 2>&1 diff --git a/bin/tests/system/resolver/tests.sh b/bin/tests/system/resolver/tests.sh index 3cd8c03435..64432c70ec 100755 --- a/bin/tests/system/resolver/tests.sh +++ b/bin/tests/system/resolver/tests.sh @@ -734,5 +734,21 @@ test ${ttl:-1} -eq 0 || ret=1 if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +n=`expr $n + 1` +echo "I:check that 'ad' in not returned in truncated answer with empty answer and authority sections to request with +ad (${n})" +ret=0 +$DIG @10.53.0.6 -p 5300 dnskey ds.example.net +bufsize=512 +ad +nodnssec +ignore +norec > dig.out.$n +grep "flags: qr aa tc; QUERY: 1, ANSWER: 0, AUTHORITY: 0" dig.out.$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I:check that 'ad' in not returned in truncated answer with empty answer and authority sections to request with +dnssec (${n})" +ret=0 +$DIG @10.53.0.6 -p 5300 dnskey ds.example.net +bufsize=512 +noad +dnssec +ignore +norec > dig.out.$n +grep "flags: qr aa tc; QUERY: 1, ANSWER: 0, AUTHORITY: 0" dig.out.$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/lib/dns/message.c b/lib/dns/message.c index f2bc44197c..ca8d77d71a 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -1960,6 +1960,15 @@ renderset(dns_rdataset_t *rdataset, const dns_name_t *owner_name, return (result); } +static void +maybe_clear_ad(dns_message_t *msg, dns_section_t sectionid) { + if (msg->counts[sectionid] == 0 && + (sectionid == DNS_SECTION_ANSWER || + (sectionid == DNS_SECTION_AUTHORITY && + msg->counts[DNS_SECTION_ANSWER] == 0))) + msg->flags &= ~DNS_MESSAGEFLAG_AD; +} + isc_result_t dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid, unsigned int options) @@ -2157,6 +2166,7 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid, *(msg->buffer) = st; /* rollback */ msg->buffer->length += msg->reserved; msg->counts[sectionid] += total; + maybe_clear_ad(msg, sectionid); return (result); }