aboutsummaryrefslogtreecommitdiff
path: root/iterator/iter_scrub.c
diff options
context:
space:
mode:
Diffstat (limited to 'iterator/iter_scrub.c')
-rw-r--r--iterator/iter_scrub.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c
index f093c1bf999a..d1fedcd0f908 100644
--- a/iterator/iter_scrub.c
+++ b/iterator/iter_scrub.c
@@ -346,6 +346,26 @@ soa_in_auth(struct msg_parse* msg)
return 0;
}
+/** Check if type is allowed in the authority section */
+static int
+type_allowed_in_authority_section(uint16_t tp)
+{
+ if(tp == LDNS_RR_TYPE_SOA || tp == LDNS_RR_TYPE_NS ||
+ tp == LDNS_RR_TYPE_DS || tp == LDNS_RR_TYPE_NSEC ||
+ tp == LDNS_RR_TYPE_NSEC3)
+ return 1;
+ return 0;
+}
+
+/** Check if type is allowed in the additional section */
+static int
+type_allowed_in_additional_section(uint16_t tp)
+{
+ if(tp == LDNS_RR_TYPE_A || tp == LDNS_RR_TYPE_AAAA)
+ return 1;
+ return 0;
+}
+
/**
* This routine normalizes a response. This includes removing "irrelevant"
* records from the answer and additional sections and (re)synthesizing
@@ -355,11 +375,13 @@ soa_in_auth(struct msg_parse* msg)
* @param msg: msg to normalize.
* @param qinfo: original query.
* @param region: where to allocate synthesized CNAMEs.
+ * @param env: module env with config options.
* @return 0 on error.
*/
static int
scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
- struct query_info* qinfo, struct regional* region)
+ struct query_info* qinfo, struct regional* region,
+ struct module_env* env)
{
uint8_t* sname = qinfo->qname;
size_t snamelen = qinfo->qname_len;
@@ -511,6 +533,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
/* Mark additional names from AUTHORITY */
while(rrset && rrset->section == LDNS_SECTION_AUTHORITY) {
+ /* protect internals of recursor by making sure to del these */
if(rrset->type==LDNS_RR_TYPE_DNAME ||
rrset->type==LDNS_RR_TYPE_CNAME ||
rrset->type==LDNS_RR_TYPE_A ||
@@ -519,6 +542,13 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
"RRset:", pkt, msg, prev, &rrset);
continue;
}
+ /* Allowed list of types in the authority section */
+ if(env->cfg->harden_unknown_additional &&
+ !type_allowed_in_authority_section(rrset->type)) {
+ remove_rrset("normalize: removing irrelevant "
+ "RRset:", pkt, msg, prev, &rrset);
+ continue;
+ }
/* only one NS set allowed in authority section */
if(rrset->type==LDNS_RR_TYPE_NS) {
/* NS set must be pertinent to the query */
@@ -576,7 +606,6 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
* found in ANSWER and AUTHORITY. */
/* These records have not been marked OK previously */
while(rrset && rrset->section == LDNS_SECTION_ADDITIONAL) {
- /* FIXME: what about other types? */
if(rrset->type==LDNS_RR_TYPE_A ||
rrset->type==LDNS_RR_TYPE_AAAA)
{
@@ -589,6 +618,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
continue;
}
}
+ /* protect internals of recursor by making sure to del these */
if(rrset->type==LDNS_RR_TYPE_DNAME ||
rrset->type==LDNS_RR_TYPE_CNAME ||
rrset->type==LDNS_RR_TYPE_NS) {
@@ -596,6 +626,13 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
"RRset:", pkt, msg, prev, &rrset);
continue;
}
+ /* Allowed list of types in the additional section */
+ if(env->cfg->harden_unknown_additional &&
+ !type_allowed_in_additional_section(rrset->type)) {
+ remove_rrset("normalize: removing irrelevant "
+ "RRset:", pkt, msg, prev, &rrset);
+ continue;
+ }
prev = rrset;
rrset = rrset->rrset_all_next;
}
@@ -846,7 +883,7 @@ scrub_message(sldns_buffer* pkt, struct msg_parse* msg,
}
/* normalize the response, this cleans up the additional. */
- if(!scrub_normalize(pkt, msg, qinfo, region))
+ if(!scrub_normalize(pkt, msg, qinfo, region, env))
return 0;
/* delete all out-of-zone information */
if(!scrub_sanitize(pkt, msg, qinfo, zonename, env, ie))