[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#889285: bind9: CVE-2017-3139 affects debian too: assertion failure in validator.c:1858



On Sat, Feb 03, 2018 at 05:17:01PM +0100, Salvatore Bonaccorso wrote:
> 
> The bug was about CVE-2017-3137, it's never a good idea to mix up
> things ;-).

This is true.  However, it appears that Ondrej Zary's comment to #860225
on 2017-09-02 is in fact related to CVE-2017-3139.  Since one of the
bind9 maintainers was the one to raise the issue of CVE-2017-3139 in
that same bug, I don't see a related follow-up report from a user to be
problematic.

> Anyway thanks that you took action and filled a new bug
> for this issue you are experiencing.
> 
> JTR, since Red Hat does not provide much details on the CVE-2017-3139
> we cannot say Debian is affected as well by this very same CVE. Since
> it's not clear, what CVE-2017-3139 is in detail, I have removed the
> CVE in the subject of this bug.
> 
It is true that there is information provided by RedHat regarding the
details of the vulnerability.  The RHSA mentioned in #860225 is also
linked from this RedHat BZ:

https://bugzilla.redhat.com/show_bug.cgi?id=1447743

However, there are no useful details there either.  I did some digging
and located the bind9 source RPM references in RHSA-2017:1202 and its
immediate predecessor.  By comparing the packages, I was able to
identify the specific patch that was associated with that RHSA.  I have
attached the patch to this email.  The name of the patch refers to
another RedHat BZ entry:

https://bugzilla.redhat.com/show_bug.cgi?id=1447407

That one is not accessible to the public, so we have no way of knowing
the details there.  Additionally, the related upstream RT tickets are
also not public.

Note that the attached patch appears to be based on commit
07dbb507d2913fc35c7edbe3692a976e3248a911 from upstream's git repository:

https://source.isc.org/git/bind9.git

The upstream changes appear to include a hunk in resolver.c which does
not appear in the RedHat patch.  That chunk would also not apply to the
wheezy version of bind9.

> What seem clear is that apparently a fix in Debian wheezy's bind9
> version causes the regression you notices. Thus I suggest the LTS team
> to try to find the defective patch introducing the issue and then
> issue just a regression update (without referencing CVE-2017-3139. If
> its on the other hand clear that Debian wheezy used the very same
> patch for a previous issue, and CVE-2017-3139 applies as well for
> Debian wheezy, then obviously it's fine to use the CVE).
> 
I examined the changes made from 9.8.4.dfsg.P1-6+nmu2+deb7u15 to
9.8.4.dfsg.P1-6+nmu2+deb7u16, which included fixes for CVE-2017-3136,
CVE-2017-3137, and CVE-2017-3138.  After examining the changes and
comparing them to the related upstream commits, I am convinced that the
fix for CVE-2017-3137 in 9.8.4.dfsg.P1-6+nmu2+deb7u16 is correct and
complete.  I would consider my examination thorough, but not exhaustive
owing to the large volume of change and some departures that are clearly
a result of the upsteam changes being backported to the bind9 in wheezy.
I am further convinced that the problem reported by Ondrej Zary in
#860225 and by Vladislav Kurz are both identical occurrences of
CVE-2017-3139.

In order to confirm the latter hypothesis, I built the current wheezy
version of bind9 and ran the dnssec test.  The test passed.  I then
stripped the changes to validator.c from the attached patch and applied
the remainder to the current wheezy version of bind9, built, and ran the
dnssec test again.  This time the test failed.  This seems to indicate
that the version of bind9 in wheezy is vulnerable to CVE-2017-3139.  I
then applied the remaining validator.c changes, rebuilt, and ran the
dnssec test again.  This time the test passed.

Based on these findings, I conclude that wheezy bind9 is vulnerable to
CVE-2017-3139.  I propose to do the following:

- Mark CVE-2017-3139 as affecting wheezy in the security tracker
- Prepare and upload a version 9.8.4.dfsg.P1-6+nmu2+deb7u20 upload that
  incorporates the CVE-2017-3139 patch from RedHat (and which closes
  this bug, #889285)
- Release a DLA per the normal procedure

I am now in the process of preparing the package for upload, but I will
wait a couple of days to allow for any objections and/or suggestions.

Regards,

-Roberto

-- 
Roberto C. Sánchez
>From 1d31a0cf1712d3eb001a686c06fe1225ba48fd04 Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Sat, 6 Oct 2012 14:56:33 +1000
Subject: [PATCH] 3391. [bug] DNSKEY that encountered a CNAME failed. [RT
 #31262]

(original commit 07dbb507d2913fc35c7edbe3692a976e3248a911)
---
 bin/tests/system/dnssec/clean.sh                 |  1 +
 bin/tests/system/dnssec/ns3/secure.example.db.in |  4 ++
 bin/tests/system/dnssec/ns3/sign.sh              |  4 +-
 bin/tests/system/dnssec/tests.sh                 | 66 ++++++++++++++++++++++++
 lib/dns/validator.c                              |  4 ++
 5 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/bin/tests/system/dnssec/clean.sh b/bin/tests/system/dnssec/clean.sh
index a1c5752..a6b1212 100644
--- a/bin/tests/system/dnssec/clean.sh
+++ b/bin/tests/system/dnssec/clean.sh
@@ -35,6 +35,7 @@ rm -f ns3/optout-unknown.example.db ns3/optout.example.db
 rm -f ns3/expired.example.db ns3/update-nsec3.example.db
 rm -f ns7/multiple.example.bk ns7/nsec3.example.bk ns7/optout.example.bk
 rm -f */named.memstats
+rm -f */named.run
 rm -f ns3/nsec3.nsec3.example.db
 rm -f ns3/nsec3.optout.example.db
 rm -f ns3/optout.nsec3.example.db
diff --git a/bin/tests/system/dnssec/ns3/secure.example.db.in b/bin/tests/system/dnssec/ns3/secure.example.db.in
index 80b7dd3..1abb69d 100644
--- a/bin/tests/system/dnssec/ns3/secure.example.db.in
+++ b/bin/tests/system/dnssec/ns3/secure.example.db.in
@@ -44,3 +44,7 @@ ns.nosoa		A	10.53.0.7
 
 normalthenrrsig		A	10.0.0.28
 rrsigonly		A	10.0.0.29
+
+cnameandkey		CNAME	@
+cnamenokey		CNAME	@
+dnameandkey		DNAME	@
diff --git a/bin/tests/system/dnssec/ns3/sign.sh b/bin/tests/system/dnssec/ns3/sign.sh
index db5da68..6394ea0 100644
--- a/bin/tests/system/dnssec/ns3/sign.sh
+++ b/bin/tests/system/dnssec/ns3/sign.sh
@@ -26,9 +26,11 @@ zone=secure.example.
 infile=secure.example.db.in
 zonefile=secure.example.db
 
+cnameandkey=`$KEYGEN -T KEY -q -r $RANDFILE -a RSASHA1 -b 768 -n host cnameandkey.$zone`
+dnameandkey=`$KEYGEN -T KEY -q -r $RANDFILE -a RSASHA1 -b 768 -n host dnameandkey.$zone`
 keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone`
 
-cat $infile $keyname.key >$zonefile
+cat $infile $cnameandkey.key $dnameandkey.key $keyname.key >$zonefile
 
 $SIGNER -P -r $RANDFILE -o $zone $zonefile > /dev/null 2>&1
 
diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh
index ad176e0..35ecc3b 100644
--- a/bin/tests/system/dnssec/tests.sh
+++ b/bin/tests/system/dnssec/tests.sh
@@ -1350,5 +1350,71 @@ $DIG +noall +answer +dnssec +nottl -p 5300 expiring.example ns @10.53.0.3 | grep
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+echo "I:testing DNSKEY lookup via CNAME ($n)"
+ret=0
+$DIG $DIGOPTS +noauth cnameandkey.secure.example. \
+	@10.53.0.3 dnskey > dig.out.ns3.test$n || ret=1
+$DIG $DIGOPTS +noauth cnameandkey.secure.example. \
+	@10.53.0.4 dnskey > dig.out.ns4.test$n || ret=1
+$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
+grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
+grep "CNAME" dig.out.ns4.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:testing KEY lookup at CNAME (present) ($n)"
+ret=0
+$DIG $DIGOPTS +noauth cnameandkey.secure.example. \
+	@10.53.0.3 key > dig.out.ns3.test$n || ret=1
+$DIG $DIGOPTS +noauth cnameandkey.secure.example. \
+	@10.53.0.4 key > dig.out.ns4.test$n || ret=1
+$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
+grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
+grep "CNAME" dig.out.ns4.test$n > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:testing KEY lookup at CNAME (not present) ($n)"
+ret=0
+$DIG $DIGOPTS +noauth cnamenokey.secure.example. \
+	@10.53.0.3 key > dig.out.ns3.test$n || ret=1
+$DIG $DIGOPTS +noauth cnamenokey.secure.example. \
+	@10.53.0.4 key > dig.out.ns4.test$n || ret=1
+$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
+grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
+grep "CNAME" dig.out.ns4.test$n > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:testing DNSKEY lookup via DNAME ($n)"
+ret=0
+$DIG $DIGOPTS a.dnameandkey.secure.example. \
+	@10.53.0.3 dnskey > dig.out.ns3.test$n || ret=1
+$DIG $DIGOPTS a.dnameandkey.secure.example. \
+	@10.53.0.4 dnskey > dig.out.ns4.test$n || ret=1
+$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
+grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
+grep "CNAME" dig.out.ns4.test$n > /dev/null || ret=1
+grep "DNAME" dig.out.ns4.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:testing KEY lookup via DNAME ($n)"
+ret=0
+$DIG $DIGOPTS b.dnameandkey.secure.example. \
+	@10.53.0.3 key > dig.out.ns3.test$n || ret=1
+$DIG $DIGOPTS b.dnameandkey.secure.example. \
+	@10.53.0.4 key > dig.out.ns4.test$n || ret=1
+$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
+grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
+grep "DNAME" dig.out.ns4.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 echo "I:exit status: $status"
 exit $status
diff --git a/lib/dns/validator.c b/lib/dns/validator.c
index 8f9a566..864301b 100644
--- a/lib/dns/validator.c
+++ b/lib/dns/validator.c
@@ -1858,6 +1858,10 @@ isselfsigned(dns_validator_t *val) {
 	name = val->event->name;
 	mctx = val->view->mctx;
 
+	if (rdataset->type == dns_rdatatype_cname ||
+	    rdataset->type == dns_rdatatype_dname)
+		return (answer);
+
 	INSIST(rdataset->type == dns_rdatatype_dnskey);
 
 	for (result = dns_rdataset_first(rdataset);
-- 
2.9.3


Reply to: