From: Ralph Dolmans Date: Thu, 18 Apr 2019 15:09:15 +0000 (+0000) Subject: - Scrub RRs from answer section when reusing NXDOMAIN message for subdomain X-Git-Tag: final-svn-state~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=edf1ad369aea0134fe7856ad3bc4bcf48d814fc3;p=thirdparty%2Funbound.git - 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. git-svn-id: file:///svn/unbound/trunk@5174 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 851147af7..ee0f90882 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c index be7965a60..2ab55ceb4 100644 --- a/iterator/iter_utils.c +++ b/iterator/iter_utils.c @@ -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; diff --git a/iterator/iter_utils.h b/iterator/iter_utils.h index ccfb28022..f771930bb 100644 --- a/iterator/iter_utils.h +++ b/iterator/iter_utils.h @@ -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. diff --git a/iterator/iterator.c b/iterator/iterator.c index c73fb5177..c906c2714 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -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. */ diff --git a/services/cache/dns.c b/services/cache/dns.c index 088efbcf8..aa4efec73 100644 --- a/services/cache/dns.c +++ b/services/cache/dns.c @@ -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);