]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Scrub RRs from answer section when reusing NXDOMAIN message for subdomain
authorRalph Dolmans <ralph@nlnetlabs.nl>
Thu, 18 Apr 2019 15:09:15 +0000 (15:09 +0000)
committerRalph Dolmans <ralph@nlnetlabs.nl>
Thu, 18 Apr 2019 15:09:15 +0000 (15:09 +0000)
   answers.
 - For harden-below-nxdomain: do not consider a name to be non-exitent when
   message contains a CNAME record.

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

doc/Changelog
iterator/iter_utils.c
iterator/iter_utils.h
iterator/iterator.c
services/cache/dns.c

index 851147af71db0a302b6d1f197067e7b93354781b..ee0f90882abcae60507cdb5afc3dd205484c6ef7 100644 (file)
@@ -1,3 +1,9 @@
+18 April 2019: Ralph
+       - Scrub RRs from answer section when reusing NXDOMAIN message for
+         subdomain answers.
+       - For harden-below-nxdomain: do not consider a name to be non-exitent
+         when message contains a CNAME record.
+
 18 April 2019: Wouter
        - travis build file.
 
index be7965a60e39bdb80064050471af296e0c9ad0f2..2ab55ceb49771044eabd2c4f47f2965911831a51 100644 (file)
@@ -1211,6 +1211,19 @@ iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns, uint8_t* z)
        }
 }
 
+void
+iter_scrub_nxdomain(struct dns_msg* msg)
+{
+       if(msg->rep->an_numrrsets == 0)
+               return;
+
+       memmove(msg->rep->rrsets, msg->rep->rrsets+msg->rep->an_numrrsets,
+               sizeof(struct ub_packed_rrset_key*) *
+               (msg->rep->rrset_count-msg->rep->an_numrrsets));
+       msg->rep->rrset_count -= msg->rep->an_numrrsets;
+       msg->rep->an_numrrsets = 0;
+}
+
 void iter_dec_attempts(struct delegpt* dp, int d)
 {
        struct delegpt_addr* a;
index ccfb280224b3d6d4f7021cb8526d7deb5f688b07..f771930bba2bac0847be935b9858fb53252bb884 100644 (file)
@@ -334,6 +334,13 @@ int iter_get_next_root(struct iter_hints* hints, struct iter_forwards* fwd,
 void iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns,
        uint8_t* z);
 
+/**
+ * Prepare an NXDOMAIN message to be used for a subdomain answer by removing all
+ * RRs from the ANSWER section.
+ * @param msg: the response to scrub.
+ */
+void iter_scrub_nxdomain(struct dns_msg* msg);
+
 /**
  * Remove query attempts from all available ips. For 0x20.
  * @param dp: delegpt.
index c73fb5177489042ef0795be29071f980d03f473f..c906c271448316fdd7ba920e5b4be71e215f6c99 100644 (file)
@@ -2718,8 +2718,15 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                        && !(iq->chase_flags & BIT_RD)) {
                        if(FLAGS_GET_RCODE(iq->response->rep->flags) != 
                                LDNS_RCODE_NOERROR) {
-                               if(qstate->env->cfg->qname_minimisation_strict)
-                                       return final_state(iq);
+                               if(qstate->env->cfg->qname_minimisation_strict) {
+                                       if(FLAGS_GET_RCODE(iq->response->rep->flags) ==
+                                               LDNS_RCODE_NXDOMAIN) {
+                                               iter_scrub_nxdomain(iq->response);
+                                               return final_state(iq);
+                                       }
+                                       return error_response(qstate, id,
+                                               LDNS_RCODE_SERVFAIL);
+                               }
                                /* Best effort qname-minimisation. 
                                 * Stop minimising and send full query when
                                 * RCODE is not NOERROR. */
index 088efbcf864184170f24c35bd77584897342d248..aa4efec73f412001f832fb27559a7b10122deedf 100644 (file)
@@ -40,6 +40,7 @@
  */
 #include "config.h"
 #include "iterator/iter_delegpt.h"
+#include "iterator/iter_utils.h"
 #include "validator/val_nsec.h"
 #include "validator/val_utils.h"
 #include "services/cache/dns.h"
@@ -914,12 +915,15 @@ dns_cache_lookup(struct module_env* env,
                        struct dns_msg* msg;
                        if(FLAGS_GET_RCODE(data->flags) == LDNS_RCODE_NXDOMAIN
                          && data->security == sec_status_secure
+                         && (data->an_numrrsets == 0 ||
+                               ntohs(data->rrsets[0]->rk.type) != LDNS_RR_TYPE_CNAME)
                          && (msg=tomsg(env, &k, data, region, now, scratch))){
                                lock_rw_unlock(&e->lock);
                                msg->qinfo.qname=qname;
                                msg->qinfo.qname_len=qnamelen;
                                /* check that DNSSEC really works out */
                                msg->rep->security = sec_status_unchecked;
+                               iter_scrub_nxdomain(msg);
                                return msg;
                        }
                        lock_rw_unlock(&e->lock);