From: Mark Andrews Date: Tue, 2 May 2017 21:51:41 +0000 (+1000) Subject: 4615. [bug] AD could be set on truncated answer with no records X-Git-Tag: v9.12.0a1~315 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=33e94f501f32955e1c44bcd4015459dc9c95ccb0;p=thirdparty%2Fbind9.git 4615. [bug] AD could be set on truncated answer with no records present in the answer and authority sections. [RT #45140] --- diff --git a/CHANGES b/CHANGES index c4f89d400a3..21ef323a236 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 bfdee21f07e..1c126236e66 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 3cd8c034353..64432c70ecc 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 f2bc44197c5..ca8d77d71ac 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); }