diff -Nru bind9-9.10.3.dfsg.P4/debian/changelog bind9-9.10.3.dfsg.P4/debian/changelog --- bind9-9.10.3.dfsg.P4/debian/changelog 2016-11-15 16:24:58.000000000 +0000 +++ bind9-9.10.3.dfsg.P4/debian/changelog 2017-01-25 14:28:10.000000000 +0000 @@ -1,3 +1,26 @@ +bind9 (1:9.10.3.dfsg.P4-10.1ubuntu3) zesty; urgency=medium + + * SECURITY UPDATE: assertion failure via class mismatch + - debian/patches/CVE-2016-9131.patch: properly handle certain TKEY + records in lib/dns/resolver.c. + - CVE-2016-9131 + * SECURITY UPDATE: assertion failure via inconsistent DNSSEC information + - debian/patches/CVE-2016-9147.patch: fix logic when records are + returned without the requested data in lib/dns/resolver.c. + - CVE-2016-9147 + * SECURITY UPDATE: assertion failure via unusually-formed DS record + - debian/patches/CVE-2016-9444.patch: handle missing RRSIGs in + lib/dns/message.c, lib/dns/resolver.c. + - CVE-2016-9444 + * SECURITY UPDATE: regression in CVE-2016-8864 + - debian/patches/rt43779.patch: properly handle CNAME -> DNAME in + responses in lib/dns/resolver.c, added tests to + bin/tests/system/dname/ns2/example.db, + bin/tests/system/dname/tests.sh. + - No CVE number + + -- Marc Deslauriers Wed, 25 Jan 2017 09:28:10 -0500 + bind9 (1:9.10.3.dfsg.P4-10.1ubuntu2) zesty; urgency=medium * Add RemainAfterExit to bind9-resolvconf unit configuration file diff -Nru bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-8864.patch bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-8864.patch --- bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-8864.patch 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-8864.patch 2016-10-31 12:53:39.000000000 +0000 @@ -0,0 +1,189 @@ +Description: fix denial of service via responses containing a DNAME answer +Origin: backported from 9.10.4-P4 + +Index: bind9-9.10.3.dfsg.P4/lib/dns/resolver.c +=================================================================== +--- bind9-9.10.3.dfsg.P4.orig/lib/dns/resolver.c 2016-10-31 08:53:33.663609748 -0400 ++++ bind9-9.10.3.dfsg.P4/lib/dns/resolver.c 2016-10-31 08:53:33.659609703 -0400 +@@ -614,7 +614,9 @@ + valarg->addrinfo = addrinfo; + + if (!ISC_LIST_EMPTY(fctx->validators)) +- INSIST((valoptions & DNS_VALIDATOR_DEFER) != 0); ++ valoptions |= DNS_VALIDATOR_DEFER; ++ else ++ valoptions &= ~DNS_VALIDATOR_DEFER; + + result = dns_validator_create(fctx->res->view, name, type, rdataset, + sigrdataset, fctx->rmessage, +@@ -5534,13 +5536,6 @@ + rdataset, + sigrdataset, + valoptions, task); +- /* +- * Defer any further validations. +- * This prevents multiple validators +- * from manipulating fctx->rmessage +- * simultaneously. +- */ +- valoptions |= DNS_VALIDATOR_DEFER; + } + } else if (CHAINING(rdataset)) { + if (rdataset->type == dns_rdatatype_cname) +@@ -5655,6 +5650,11 @@ + eresult == DNS_R_NCACHENXRRSET); + } + event->result = eresult; ++ if (adbp != NULL && *adbp != NULL) { ++ if (anodep != NULL && *anodep != NULL) ++ dns_db_detachnode(*adbp, anodep); ++ dns_db_detach(adbp); ++ } + dns_db_attach(fctx->cache, adbp); + dns_db_transfernode(fctx->cache, &node, anodep); + clone_results(fctx); +@@ -5905,6 +5905,11 @@ + fctx->attributes |= FCTX_ATTR_HAVEANSWER; + if (event != NULL) { + event->result = eresult; ++ if (adbp != NULL && *adbp != NULL) { ++ if (anodep != NULL && *anodep != NULL) ++ dns_db_detachnode(*adbp, anodep); ++ dns_db_detach(adbp); ++ } + dns_db_attach(fctx->cache, adbp); + dns_db_transfernode(fctx->cache, &node, anodep); + clone_results(fctx); +@@ -6726,13 +6731,15 @@ + answer_response(fetchctx_t *fctx) { + isc_result_t result; + dns_message_t *message; +- dns_name_t *name, *dname = NULL, *qname, tname, *ns_name; ++ dns_name_t *name, *dname = NULL, *qname, *dqname, tname, *ns_name; ++ dns_name_t *cname = NULL; + dns_rdataset_t *rdataset, *ns_rdataset; + isc_boolean_t done, external, chaining, aa, found, want_chaining; +- isc_boolean_t have_answer, found_cname, found_type, wanted_chaining; ++ isc_boolean_t have_answer, found_cname, found_dname, found_type; ++ isc_boolean_t wanted_chaining; + unsigned int aflag; + dns_rdatatype_t type; +- dns_fixedname_t fdname, fqname; ++ dns_fixedname_t fdname, fqname, fqdname; + dns_view_t *view; + + FCTXTRACE("answer_response"); +@@ -6746,6 +6753,7 @@ + + done = ISC_FALSE; + found_cname = ISC_FALSE; ++ found_dname = ISC_FALSE; + found_type = ISC_FALSE; + chaining = ISC_FALSE; + have_answer = ISC_FALSE; +@@ -6755,12 +6763,13 @@ + aa = ISC_TRUE; + else + aa = ISC_FALSE; +- qname = &fctx->name; ++ dqname = qname = &fctx->name; + type = fctx->type; + view = fctx->res->view; ++ dns_fixedname_init(&fqdname); + result = dns_message_firstname(message, DNS_SECTION_ANSWER); + while (!done && result == ISC_R_SUCCESS) { +- dns_namereln_t namereln; ++ dns_namereln_t namereln, dnamereln; + int order; + unsigned int nlabels; + +@@ -6768,6 +6777,8 @@ + dns_message_currentname(message, DNS_SECTION_ANSWER, &name); + external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain)); + namereln = dns_name_fullcompare(qname, name, &order, &nlabels); ++ dnamereln = dns_name_fullcompare(dqname, name, &order, ++ &nlabels); + if (namereln == dns_namereln_equal) { + wanted_chaining = ISC_FALSE; + for (rdataset = ISC_LIST_HEAD(name->list); +@@ -6862,7 +6873,7 @@ + } + } else if (rdataset->type == dns_rdatatype_rrsig + && rdataset->covers == +- dns_rdatatype_cname ++ dns_rdatatype_cname + && !found_type) { + /* + * We're looking for something else, +@@ -6892,11 +6903,18 @@ + * a CNAME or DNAME). + */ + INSIST(!external); +- if (aflag == +- DNS_RDATASETATTR_ANSWER) { ++ if ((rdataset->type != ++ dns_rdatatype_cname) || ++ !found_dname || ++ (aflag == ++ DNS_RDATASETATTR_ANSWER)) ++ { + have_answer = ISC_TRUE; ++ if (rdataset->type == ++ dns_rdatatype_cname) ++ cname = name; + name->attributes |= +- DNS_NAMEATTR_ANSWER; ++ DNS_NAMEATTR_ANSWER; + } + rdataset->attributes |= aflag; + if (aa) +@@ -6990,11 +7008,11 @@ + return (DNS_R_FORMERR); + } + +- if (namereln != dns_namereln_subdomain) { ++ if (dnamereln != dns_namereln_subdomain) { + char qbuf[DNS_NAME_FORMATSIZE]; + char obuf[DNS_NAME_FORMATSIZE]; + +- dns_name_format(qname, qbuf, ++ dns_name_format(dqname, qbuf, + sizeof(qbuf)); + dns_name_format(name, obuf, + sizeof(obuf)); +@@ -7009,7 +7027,7 @@ + want_chaining = ISC_TRUE; + POST(want_chaining); + aflag = DNS_RDATASETATTR_ANSWER; +- result = dname_target(rdataset, qname, ++ result = dname_target(rdataset, dqname, + nlabels, &fdname); + if (result == ISC_R_NOSPACE) { + /* +@@ -7026,10 +7044,13 @@ + + dname = dns_fixedname_name(&fdname); + if (!is_answertarget_allowed(view, +- qname, rdataset->type, +- dname, &fctx->domain)) { ++ dqname, rdataset->type, ++ dname, &fctx->domain)) ++ { + return (DNS_R_SERVFAIL); + } ++ dqname = dns_fixedname_name(&fqdname); ++ dns_name_copy(dname, dqname, NULL); + } else { + /* + * We've found a signature that +@@ -7054,6 +7075,10 @@ + INSIST(!external); + if (aflag == DNS_RDATASETATTR_ANSWER) { + have_answer = ISC_TRUE; ++ found_dname = ISC_TRUE; ++ if (cname != NULL) ++ cname->attributes &= ++ ~DNS_NAMEATTR_ANSWER; + name->attributes |= + DNS_NAMEATTR_ANSWER; + } diff -Nru bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-9131.patch bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-9131.patch --- bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-9131.patch 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-9131.patch 2017-01-09 13:39:53.000000000 +0000 @@ -0,0 +1,49 @@ +#diff --git a/CHANGES b/CHANGES +#index a53e413..0ca2f93 100644 +#--- a/CHANGES +#+++ b/CHANGES +#@@ -1,3 +1,7 @@ +#+4508. [security] Named incorrectly tried to cache TKEY records which +#+ could trigger a assertion failure when there was +#+ a class mismatch. (CVE-2016-9131) [RT #43522] +#+ +# --- 9.10.4-P4 released --- +# +# 4489. [security] It was possible to trigger assertions when processing +Index: bind9-9.10.3.dfsg.P4/lib/dns/resolver.c +=================================================================== +--- bind9-9.10.3.dfsg.P4.orig/lib/dns/resolver.c 2017-01-09 08:37:00.305520045 -0500 ++++ bind9-9.10.3.dfsg.P4/lib/dns/resolver.c 2017-01-09 08:37:00.301519997 -0500 +@@ -6795,6 +6795,19 @@ + log_formerr(fctx, "NSEC3 in answer"); + return (DNS_R_FORMERR); + } ++ if (rdataset->type == dns_rdatatype_tkey) { ++ /* ++ * TKEY is not a valid record in a ++ * response to any query we can make. ++ */ ++ log_formerr(fctx, "TKEY in answer"); ++ return (DNS_R_FORMERR); ++ } ++ if (rdataset->rdclass != fctx->res->rdclass) { ++ log_formerr(fctx, "Mismatched class " ++ "in answer"); ++ return (DNS_R_FORMERR); ++ } + + /* + * Apply filters, if given, on answers to reject +@@ -6981,6 +6994,12 @@ + rdataset != NULL; + rdataset = ISC_LIST_NEXT(rdataset, link)) + { ++ if (rdataset->rdclass != fctx->res->rdclass) { ++ log_formerr(fctx, "Mismatched class " ++ "in answer"); ++ return (DNS_R_FORMERR); ++ } ++ + /* + * Only pass DNAME or RRSIG(DNAME). + */ diff -Nru bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-9147.patch bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-9147.patch --- bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-9147.patch 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-9147.patch 2017-01-09 13:37:09.000000000 +0000 @@ -0,0 +1,44 @@ +#diff --git a/CHANGES b/CHANGES +#index a53e413..3babc7c 100644 +#--- a/CHANGES +#+++ b/CHANGES +#@@ -1,3 +1,8 @@ +#+4510. [security] Named mishandled some responses where covering RRSIG +#+ records are returned without the requested data +#+ resulting in a assertion failure. (CVE-2016-9147) +#+ [RT #43548] +#+ +# --- 9.10.4-P4 released --- +# +# 4489. [security] It was possible to trigger assertions when processing +Index: bind9-9.10.3.dfsg.P4/lib/dns/resolver.c +=================================================================== +--- bind9-9.10.3.dfsg.P4.orig/lib/dns/resolver.c 2017-01-09 08:37:07.829610230 -0500 ++++ bind9-9.10.3.dfsg.P4/lib/dns/resolver.c 2017-01-09 08:37:07.825610182 -0500 +@@ -6916,15 +6916,19 @@ + * a CNAME or DNAME). + */ + INSIST(!external); +- if ((rdataset->type != +- dns_rdatatype_cname) || +- !found_dname || +- (aflag == +- DNS_RDATASETATTR_ANSWER)) ++ /* ++ * Don't use found_cname here ++ * as we have just set it ++ * above. ++ */ ++ if (cname == NULL && ++ !found_dname && ++ aflag == ++ DNS_RDATASETATTR_ANSWER) + { + have_answer = ISC_TRUE; +- if (rdataset->type == +- dns_rdatatype_cname) ++ if (found_cname && ++ cname == NULL) + cname = name; + name->attributes |= + DNS_NAMEATTR_ANSWER; diff -Nru bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-9444.patch bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-9444.patch --- bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-9444.patch 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.10.3.dfsg.P4/debian/patches/CVE-2016-9444.patch 2017-01-09 13:37:17.000000000 +0000 @@ -0,0 +1,165 @@ +#diff --git a/CHANGES b/CHANGES +#index a53e413..60efdca 100644 +#--- a/CHANGES +#+++ b/CHANGES +#@@ -1,3 +1,7 @@ +#+4517. [security] Named could mishandle authority sections that were +#+ missing RRSIGs triggering an assertion failure. +#+ (CVE-2016-9444) [RT # 43632] +#+ +# --- 9.10.4-P4 released --- +# +# 4489. [security] It was possible to trigger assertions when processing +Index: bind9-9.10.3.dfsg.P4/lib/dns/message.c +=================================================================== +--- bind9-9.10.3.dfsg.P4.orig/lib/dns/message.c 2017-01-09 08:37:15.409701143 -0500 ++++ bind9-9.10.3.dfsg.P4/lib/dns/message.c 2017-01-09 08:37:15.405701095 -0500 +@@ -1179,6 +1179,63 @@ + return (ISC_FALSE); + } + ++/* ++ * Check to confirm that all DNSSEC records (DS, NSEC, NSEC3) have ++ * covering RRSIGs. ++ */ ++static isc_boolean_t ++auth_signed(dns_namelist_t *section) { ++ dns_name_t *name; ++ ++ for (name = ISC_LIST_HEAD(*section); ++ name != NULL; ++ name = ISC_LIST_NEXT(name, link)) ++ { ++ int auth_dnssec = 0, auth_rrsig = 0; ++ dns_rdataset_t *rds; ++ ++ for (rds = ISC_LIST_HEAD(name->list); ++ rds != NULL; ++ rds = ISC_LIST_NEXT(rds, link)) ++ { ++ switch (rds->type) { ++ case dns_rdatatype_ds: ++ auth_dnssec |= 0x1; ++ break; ++ case dns_rdatatype_nsec: ++ auth_dnssec |= 0x2; ++ break; ++ case dns_rdatatype_nsec3: ++ auth_dnssec |= 0x4; ++ break; ++ case dns_rdatatype_rrsig: ++ break; ++ default: ++ continue; ++ } ++ ++ switch (rds->covers) { ++ case dns_rdatatype_ds: ++ auth_rrsig |= 0x1; ++ break; ++ case dns_rdatatype_nsec: ++ auth_rrsig |= 0x2; ++ break; ++ case dns_rdatatype_nsec3: ++ auth_rrsig |= 0x4; ++ break; ++ default: ++ break; ++ } ++ } ++ ++ if (auth_dnssec != auth_rrsig) ++ return (ISC_FALSE); ++ } ++ ++ return (ISC_TRUE); ++} ++ + static isc_result_t + getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, + dns_section_t sectionid, unsigned int options) +@@ -1204,12 +1261,12 @@ + best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT); + seen_problem = ISC_FALSE; + ++ section = &msg->sections[sectionid]; ++ + for (count = 0; count < msg->counts[sectionid]; count++) { + int recstart = source->current; + isc_boolean_t skip_name_search, skip_type_search; + +- section = &msg->sections[sectionid]; +- + skip_name_search = ISC_FALSE; + skip_type_search = ISC_FALSE; + free_rdataset = ISC_FALSE; +@@ -1382,7 +1439,7 @@ + goto cleanup; + rdata->rdclass = rdclass; + issigzero = ISC_FALSE; +- if (rdtype == dns_rdatatype_rrsig && ++ if (rdtype == dns_rdatatype_rrsig && + rdata->flags == 0) { + covers = dns_rdata_covers(rdata); + if (covers == 0) +@@ -1597,6 +1654,19 @@ + INSIST(free_rdataset == ISC_FALSE); + } + ++ /* ++ * If any of DS, NSEC or NSEC3 appeared in the ++ * authority section of a query response without ++ * a covering RRSIG, FORMERR ++ */ ++ if (sectionid == DNS_SECTION_AUTHORITY && ++ msg->opcode == dns_opcode_query && ++ ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) && ++ ((msg->flags & DNS_MESSAGEFLAG_TC) == 0) && ++ !preserve_order && ++ !auth_signed(section)) ++ DO_FORMERR; ++ + if (seen_problem) + return (DNS_R_RECOVERABLE); + return (ISC_R_SUCCESS); +Index: bind9-9.10.3.dfsg.P4/lib/dns/resolver.c +=================================================================== +--- bind9-9.10.3.dfsg.P4.orig/lib/dns/resolver.c 2017-01-09 08:37:15.409701143 -0500 ++++ bind9-9.10.3.dfsg.P4/lib/dns/resolver.c 2017-01-09 08:37:15.409701143 -0500 +@@ -5447,16 +5447,13 @@ + rdataset->type, + &noqname); + if (tresult == ISC_R_SUCCESS && +- noqname != NULL) { +- tresult = +- dns_rdataset_addnoqname( ++ noqname != NULL) ++ (void) dns_rdataset_addnoqname( + rdataset, noqname); +- RUNTIME_CHECK(tresult == +- ISC_R_SUCCESS); +- } + } +- if ((fctx->options & DNS_FETCHOPT_PREFETCH) != 0) +- options = DNS_DBADD_PREFETCH; ++ if ((fctx->options & ++ DNS_FETCHOPT_PREFETCH) != 0) ++ options = DNS_DBADD_PREFETCH; + addedrdataset = ardataset; + result = dns_db_addrdataset(fctx->cache, node, + NULL, now, rdataset, +@@ -5589,11 +5586,9 @@ + tresult = findnoqname(fctx, name, + rdataset->type, &noqname); + if (tresult == ISC_R_SUCCESS && +- noqname != NULL) { +- tresult = dns_rdataset_addnoqname( +- rdataset, noqname); +- RUNTIME_CHECK(tresult == ISC_R_SUCCESS); +- } ++ noqname != NULL) ++ (void) dns_rdataset_addnoqname( ++ rdataset, noqname); + } + + /* diff -Nru bind9-9.10.3.dfsg.P4/debian/patches/rt43779.patch bind9-9.10.3.dfsg.P4/debian/patches/rt43779.patch --- bind9-9.10.3.dfsg.P4/debian/patches/rt43779.patch 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.10.3.dfsg.P4/debian/patches/rt43779.patch 2017-01-09 13:37:35.000000000 +0000 @@ -0,0 +1,173 @@ +commit 7a5837e0b4b6fc8d18751674f4df4951c87fd6a6 +Author: Mark Andrews +Date: Fri Dec 9 12:50:18 2016 +1100 + + 4530. [bug] Change 4489 broke the handling of CNAME -> DNAME + in responses resulting in SERVFAIL being returned. + [RT #43779] + + (cherry picked from commit 60cb462c56536f307fac4db8bdebf1247e2b5f66) + +#diff --git a/CHANGES b/CHANGES +#index 4b89cb4..a82bdbe 100644 +#--- a/CHANGES +#+++ b/CHANGES +#@@ -1,5 +1,9 @@ +# --- 9.10.4-P5 released --- +# +#+4530. [bug] Change 4489 broke the handling of CNAME -> DNAME +#+ in responses resulting in SERVFAIL being returned. +#+ [RT #43779] +#+ +# 4528. [bug] Only set the flag bits for the i/o we are waiting +# for on EPOLLERR or EPOLLHUP. [RT #43617] +# +Index: bind9-9.10.3.dfsg.P4/bin/tests/system/dname/ns2/example.db +=================================================================== +--- bind9-9.10.3.dfsg.P4.orig/bin/tests/system/dname/ns2/example.db 2017-01-09 08:37:33.573919227 -0500 ++++ bind9-9.10.3.dfsg.P4/bin/tests/system/dname/ns2/example.db 2017-01-09 08:37:33.565919131 -0500 +@@ -29,4 +29,6 @@ + short-dname DNAME short + a.longlonglonglonglonglonglonglonglonglonglonglonglong A 10.0.0.2 + long-dname DNAME longlonglonglonglonglonglonglonglonglonglonglonglong +-; ++cname CNAME a.cnamedname ++cnamedname DNAME target ++a.target A 10.0.0.3 +Index: bind9-9.10.3.dfsg.P4/bin/tests/system/dname/tests.sh +=================================================================== +--- bind9-9.10.3.dfsg.P4.orig/bin/tests/system/dname/tests.sh 2017-01-09 08:37:33.573919227 -0500 ++++ bind9-9.10.3.dfsg.P4/bin/tests/system/dname/tests.sh 2017-01-09 08:37:33.565919131 -0500 +@@ -63,6 +63,24 @@ + if [ $ret != 0 ]; then echo "I:failed"; fi + status=`expr $status + $ret` + ++echo "I:checking cname to dname from authoritative" ++ret=0 ++$DIG cname.example @10.53.0.2 a -p 5300 > dig.out.ns2.cname ++grep "status: NOERROR" dig.out.ns2.cname > /dev/null || ret=1 ++if [ $ret != 0 ]; then echo "I:failed"; fi ++status=`expr $status + $ret` ++ ++echo "I:checking cname to dname from recursive" ++ret=0 ++$DIG cname.example @10.53.0.4 a -p 5300 > dig.out.ns4.cname ++grep "status: NOERROR" dig.out.ns4.cname > /dev/null || ret=1 ++grep '^cname.example.' dig.out.ns4.cname > /dev/null || ret=1 ++grep '^cnamedname.example.' dig.out.ns4.cname > /dev/null || ret=1 ++grep '^a.cnamedname.example.' dig.out.ns4.cname > /dev/null || ret=1 ++grep '^a.target.example.' dig.out.ns4.cname > /dev/null || ret=1 ++if [ $ret != 0 ]; then echo "I:failed"; fi ++status=`expr $status + $ret` ++ + echo "I:exit status: $status" + + exit $status +Index: bind9-9.10.3.dfsg.P4/lib/dns/resolver.c +=================================================================== +--- bind9-9.10.3.dfsg.P4.orig/lib/dns/resolver.c 2017-01-09 08:37:33.573919227 -0500 ++++ bind9-9.10.3.dfsg.P4/lib/dns/resolver.c 2017-01-09 08:37:33.569919179 -0500 +@@ -6726,7 +6726,7 @@ + answer_response(fetchctx_t *fctx) { + isc_result_t result; + dns_message_t *message; +- dns_name_t *name, *dname = NULL, *qname, *dqname, tname, *ns_name; ++ dns_name_t *name, *dname = NULL, *qname, tname, *ns_name; + dns_name_t *cname = NULL; + dns_rdataset_t *rdataset, *ns_rdataset; + isc_boolean_t done, external, chaining, aa, found, want_chaining; +@@ -6734,7 +6734,7 @@ + isc_boolean_t wanted_chaining; + unsigned int aflag; + dns_rdatatype_t type; +- dns_fixedname_t fdname, fqname, fqdname; ++ dns_fixedname_t fdname, fqname; + dns_view_t *view; + + FCTXTRACE("answer_response"); +@@ -6758,13 +6758,12 @@ + aa = ISC_TRUE; + else + aa = ISC_FALSE; +- dqname = qname = &fctx->name; ++ qname = &fctx->name; + type = fctx->type; + view = fctx->res->view; +- dns_fixedname_init(&fqdname); + result = dns_message_firstname(message, DNS_SECTION_ANSWER); + while (!done && result == ISC_R_SUCCESS) { +- dns_namereln_t namereln, dnamereln; ++ dns_namereln_t namereln; + int order; + unsigned int nlabels; + +@@ -6772,8 +6771,6 @@ + dns_message_currentname(message, DNS_SECTION_ANSWER, &name); + external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain)); + namereln = dns_name_fullcompare(qname, name, &order, &nlabels); +- dnamereln = dns_name_fullcompare(dqname, name, &order, +- &nlabels); + if (namereln == dns_namereln_equal) { + wanted_chaining = ISC_FALSE; + for (rdataset = ISC_LIST_HEAD(name->list); +@@ -7026,11 +7023,24 @@ + return (DNS_R_FORMERR); + } + +- if (dnamereln != dns_namereln_subdomain) { ++ /* ++ * If DNAME + synthetic CNAME then the ++ * namereln is dns_namereln_subdomain. ++ * ++ * If synthetic CNAME + DNAME then the ++ * namereln is dns_namereln_commonancestor ++ * and the number of label must match the ++ * DNAME. This order is not RFC compliant. ++ */ ++ ++ if (namereln != dns_namereln_subdomain && ++ (namereln != dns_namereln_commonancestor || ++ nlabels != dns_name_countlabels(name))) ++ { + char qbuf[DNS_NAME_FORMATSIZE]; + char obuf[DNS_NAME_FORMATSIZE]; + +- dns_name_format(dqname, qbuf, ++ dns_name_format(qname, qbuf, + sizeof(qbuf)); + dns_name_format(name, obuf, + sizeof(obuf)); +@@ -7045,7 +7055,7 @@ + want_chaining = ISC_TRUE; + POST(want_chaining); + aflag = DNS_RDATASETATTR_ANSWER; +- result = dname_target(rdataset, dqname, ++ result = dname_target(rdataset, qname, + nlabels, &fdname); + if (result == ISC_R_NOSPACE) { + /* +@@ -7062,13 +7072,11 @@ + + dname = dns_fixedname_name(&fdname); + if (!is_answertarget_allowed(view, +- dqname, rdataset->type, ++ qname, rdataset->type, + dname, &fctx->domain)) + { + return (DNS_R_SERVFAIL); + } +- dqname = dns_fixedname_name(&fqdname); +- dns_name_copy(dname, dqname, NULL); + } else { + /* + * We've found a signature that +@@ -7214,7 +7222,8 @@ + rdataset->trust = + dns_trust_additional; + +- if (rdataset->type == dns_rdatatype_ns) { ++ if (rdataset->type == dns_rdatatype_ns) ++ { + ns_name = name; + ns_rdataset = rdataset; + } diff -Nru bind9-9.10.3.dfsg.P4/debian/patches/series bind9-9.10.3.dfsg.P4/debian/patches/series --- bind9-9.10.3.dfsg.P4/debian/patches/series 2016-11-15 05:04:41.000000000 +0000 +++ bind9-9.10.3.dfsg.P4/debian/patches/series 2017-01-25 14:28:10.000000000 +0000 @@ -11,3 +11,8 @@ 70_precise_time.diff 75_ctxstart_no_sighandling.diff CVE-2016-2776.patch +CVE-2016-8864.patch +CVE-2016-9131.patch +CVE-2016-9147.patch +CVE-2016-9444.patch +rt43779.patch