]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix #3397: Fix that when the cache contains an unsigned DNAME in
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 22 Jan 2018 14:30:16 +0000 (14:30 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Mon, 22 Jan 2018 14:30:16 +0000 (14:30 +0000)
  the middle of a cname chain, a result without the DNAME could
  be returned.

git-svn-id: file:///svn/unbound/trunk@4446 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
services/cache/dns.c

index c867efde04ba69e73a1216355ac51afb877f20e4..e02ac95a5cf9e05862314d579f7ff02c5af6674e 100644 (file)
@@ -4,6 +4,9 @@
          tls-service-key, tls-service-pem, stub-tls-upstream and
          forward-tls-upstream.
        - Fix #3397: Fix that cachedb could return a partial CNAME chain.
+       - Fix #3397: Fix that when the cache contains an unsigned DNAME in
+         the middle of a cname chain, a result without the DNAME could
+         be returned.
 
 19 January 2018: Wouter
        - tag 1.6.8 for release with CVE fix.
index ddea47aa62a8582797a524e681d748651d089bfb..b725d8a34e93ad48d88ece9c3454d6bbf0e73403 100644 (file)
@@ -568,7 +568,7 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
 /** synthesize DNAME+CNAME response from cached DNAME item */
 static struct dns_msg*
 synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region, 
-       time_t now, struct query_info* q)
+       time_t now, struct query_info* q, struct module_env* env)
 {
        struct dns_msg* msg;
        struct ub_packed_rrset_key* ck;
@@ -580,8 +580,19 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
                return NULL;
        /* only allow validated (with DNSSEC) DNAMEs used from cache 
         * for insecure DNAMEs, query again. */
-       if(d->security != sec_status_secure)
-               return NULL;
+       if(d->security != sec_status_secure) {
+               /* but if we have a CNAME cached with this name, then we
+                * have previously already allowed this name to pass.
+                * the next cache lookup is going to fetch that CNAME itself,
+                * but it is better to have the (unsigned)DNAME + CNAME in
+                * that case */
+               struct ub_packed_rrset_key* cname_rrset = rrset_cache_lookup(
+                       env->rrset_cache, q->qname, q->qname_len,
+                       LDNS_RR_TYPE_CNAME, q->qclass, 0, now, 0);
+               if(!cname_rrset)
+                       return NULL;
+               lock_rw_unlock(&cname_rrset->entry.lock);
+       }
        msg = gen_dns_msg(region, q, 2); /* DNAME + CNAME RRset */
        if(!msg)
                return NULL;
@@ -748,7 +759,8 @@ dns_cache_lookup(struct module_env* env,
                (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);
+               struct dns_msg* msg = synth_dname_msg(rrset, region, now, &k,
+                       env);
                if(msg) {
                        lock_rw_unlock(&rrset->entry.lock);
                        return msg;