From: Mark Andrews Date: Thu, 19 Dec 2013 23:58:32 +0000 (+1100) Subject: 3693. [security] memcpy was incorrectly called with overlapping X-Git-Tag: v9.9-ESV-R10-P2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=180069960575b2ce46ba7e03c30925660deffe11;p=thirdparty%2Fbind9.git 3693. [security] memcpy was incorrectly called with overlapping ranges resulting in malformed names being generated on some platforms. This could cause INSIST failures when serving NSEC3 signed zones. [RT #35120] (cherry picked from commit fa467e60c590072fd6848522456eb2cc41582c59) --- diff --git a/CHANGES b/CHANGES index e93da380236..d3443c62c49 100644 --- a/CHANGES +++ b/CHANGES @@ -1,10 +1,9 @@ --- 9.6-ESV-R10-P2 released --- 3693. [security] memcpy was incorrectly called with overlapping - ranges resulting a malformed names being generated - on some platforms. This was subsequently detected - resulting in INSIST failures when serving NSEC3 - signed zones. [RT #35120] + ranges resulting in malformed names being generated + on some platforms. This could cause INSIST failures + when serving NSEC3 signed zones. [RT #35120] --- 9.6-ESV-R10-P1 released --- diff --git a/bin/named/query.c b/bin/named/query.c index de190753063..5b5b9a89ee0 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -3679,8 +3679,7 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, dns_fixedname_t fixed; dns_hash_t hash; dns_name_t name; - int order; - unsigned int count; + unsigned int skip = 0, labels; dns_rdata_nsec3_t nsec3; dns_rdata_t rdata = DNS_RDATA_INIT; isc_boolean_t optout; @@ -3693,6 +3692,7 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, dns_name_init(&name, NULL); dns_name_clone(qname, &name); + labels = dns_name_countlabels(&name); /* * Map unknown algorithm to known value. @@ -3724,13 +3724,14 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, dns_rdata_reset(&rdata); optout = ISC_TF((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0); if (found != NULL && optout && - dns_name_fullcompare(&name, dns_db_origin(db), &order, - &count) == dns_namereln_subdomain) { + dns_name_issubdomain(&name, dns_db_origin(db))) + { dns_rdataset_disassociate(rdataset); if (dns_rdataset_isassociated(sigrdataset)) dns_rdataset_disassociate(sigrdataset); - count = dns_name_countlabels(&name) - 1; - dns_name_getlabelsequence(&name, 1, count, &name); + skip++; + dns_name_getlabelsequence(qname, skip, labels - skip, + &name); ns_client_log(client, DNS_LOGCATEGORY_DNSSEC, NS_LOGMODULE_QUERY, ISC_LOG_DEBUG(3), "looking for closest provable encloser"); @@ -3748,7 +3749,11 @@ query_findclosestnsec3(dns_name_t *qname, dns_db_t *db, ns_client_log(client, DNS_LOGCATEGORY_DNSSEC, NS_LOGMODULE_QUERY, ISC_LOG_WARNING, "expected covering NSEC3, got an exact match"); - if (found != NULL) + if (found == qname) { + if (skip != 0U) + dns_name_getlabelsequence(qname, skip, labels - skip, + found); + } else if (found != NULL) dns_name_copy(&name, found, NULL); return; }