From: Wouter Wijngaards Date: Mon, 22 Jan 2018 13:54:20 +0000 (+0000) Subject: - Fix #3397: Fix that cachedb could return a partial CNAME chain. X-Git-Tag: release-1.7.0rc1~116 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=df6fbb82bec61aae9993851871d899b0586a4260;p=thirdparty%2Funbound.git - Fix #3397: Fix that cachedb could return a partial CNAME chain. git-svn-id: file:///svn/unbound/trunk@4445 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/cachedb/cachedb.c b/cachedb/cachedb.c index d07d76973..a11baccee 100644 --- a/cachedb/cachedb.c +++ b/cachedb/cachedb.c @@ -568,7 +568,9 @@ cachedb_intcache_lookup(struct module_qstate* qstate) msg = dns_cache_lookup(qstate->env, qstate->qinfo.qname, qstate->qinfo.qname_len, qstate->qinfo.qtype, qstate->qinfo.qclass, qstate->query_flags, - qstate->region, qstate->env->scratch); + qstate->region, qstate->env->scratch, + 1 /* no partial messages with only a CNAME */ + ); if(!msg && qstate->env->neg_cache) { /* lookup in negative cache; may result in * NOERROR/NODATA or NXDOMAIN answers that need validation */ diff --git a/doc/Changelog b/doc/Changelog index 41510b434..c867efde0 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -3,6 +3,7 @@ also recognized and means the same. Also for tls-port, tls-service-key, tls-service-pem, stub-tls-upstream and forward-tls-upstream. + - Fix #3397: Fix that cachedb could return a partial CNAME chain. 19 January 2018: Wouter - tag 1.6.8 for release with CVE fix. diff --git a/iterator/iterator.c b/iterator/iterator.c index d95a6e034..ddad1da9f 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -1109,7 +1109,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, msg = dns_cache_lookup(qstate->env, iq->qchase.qname, iq->qchase.qname_len, iq->qchase.qtype, iq->qchase.qclass, qstate->query_flags, - qstate->region, qstate->env->scratch); + qstate->region, qstate->env->scratch, 0); if(!msg && qstate->env->neg_cache) { /* lookup in negative cache; may result in * NOERROR/NODATA or NXDOMAIN answers that need validation */ @@ -2170,7 +2170,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, iq->qinfo_out.qname, iq->qinfo_out.qname_len, iq->qinfo_out.qtype, iq->qinfo_out.qclass, qstate->query_flags, qstate->region, - qstate->env->scratch); + qstate->env->scratch, 0); if(msg && msg->rep->an_numrrsets == 0 && FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_NOERROR) diff --git a/services/cache/dns.c b/services/cache/dns.c index f9dc5922f..ddea47aa6 100644 --- a/services/cache/dns.c +++ b/services/cache/dns.c @@ -711,7 +711,8 @@ fill_any(struct module_env* env, struct dns_msg* dns_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, - uint16_t flags, struct regional* region, struct regional* scratch) + uint16_t flags, struct regional* region, struct regional* scratch, + int no_partial) { struct lruhash_entry* e; struct query_info k; @@ -743,7 +744,8 @@ dns_cache_lookup(struct module_env* env, /* see if a DNAME exists. Checked for first, to enforce that DNAMEs * are more important, the CNAME is resynthesized and thus * consistent with the DNAME */ - if( (rrset=find_closest_of_type(env, qname, qnamelen, qclass, now, + if(!no_partial && + (rrset=find_closest_of_type(env, qname, qnamelen, qclass, now, LDNS_RR_TYPE_DNAME, 1))) { /* synthesize a DNAME+CNAME message based on this */ struct dns_msg* msg = synth_dname_msg(rrset, region, now, &k); @@ -756,7 +758,7 @@ dns_cache_lookup(struct module_env* env, /* see if we have CNAME for this domain, * but not for DS records (which are part of the parent) */ - if( qtype != LDNS_RR_TYPE_DS && + if(!no_partial && qtype != LDNS_RR_TYPE_DS && (rrset=rrset_cache_lookup(env->rrset_cache, qname, qnamelen, LDNS_RR_TYPE_CNAME, qclass, 0, now, 0))) { uint8_t* wc = NULL; diff --git a/services/cache/dns.h b/services/cache/dns.h index 9e10f437f..6475a012a 100644 --- a/services/cache/dns.h +++ b/services/cache/dns.h @@ -159,13 +159,16 @@ struct dns_msg* tomsg(struct module_env* env, struct query_info* q, * @param flags: flags with BIT_CD for AAAA queries in dns64 translation. * @param region: where to allocate result. * @param scratch: where to allocate temporary data. + * @param no_partial: if true, only complete messages and not a partial + * one (with only the start of the CNAME chain and not the rest). * @return new response message (alloced in region, rrsets do not have IDs). * or NULL on error or if not found in cache. * TTLs are made relative to the current time. */ struct dns_msg* dns_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, - uint16_t flags, struct regional* region, struct regional* scratch); + uint16_t flags, struct regional* region, struct regional* scratch, + int no_partial); /** * find and add A and AAAA records for missing nameservers in delegpt