[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

freeze exception for unbound 1.0.2?



hi,

i'd like to inquire if the release team would permit a new point release
of unbound 1.0 to migrate to lenny.  apparently a few dns data scrubbing
fixes were held back until after august 6th, see

    http://www.unbound.net/documentation/patch_announce102.html
    http://www.unbound.net/pipermail/unbound-users/2008-August/000153.html

    Major feature is a more strict scrubber that filters incoming DNS
    replies for possibly malicious content.  It is more strict in 1.0.2
    to prevent certain types of malicious content.  This can stop
    certain variants of the recently disclosed attacks on Blackhat.

relevant source code changes are below.  i have elided autoconf churn,
unit tests, etc.  for the full diff, execute

    svn diff http://unbound.nlnetlabs.nl/svn/tags/release-1.0.1/ \
        http://unbound.nlnetlabs.nl/svn/tags/release-1.0.2/


Index: services/cache/dns.c
===================================================================
--- services/cache/dns.c	(.../release-1.0.1)	(revision 1182)
+++ services/cache/dns.c	(.../release-1.0.2)	(revision 1182)
@@ -465,6 +465,10 @@
 	size_t newlen, dtarglen;
 	if(now > d->ttl)
 		return NULL;
+	/* only allow validated (with DNSSEC) DNAMEs used from cache 
+	 * for insecure DNAMEs, query again. */
+	if(d->security != sec_status_secure)
+		return NULL;
 	msg = gen_dns_msg(region, q, 2); /* DNAME + CNAME RRset */
 	if(!msg)
 		return NULL;
Index: services/outside_network.c
===================================================================
--- services/outside_network.c	(.../release-1.0.1)	(revision 1182)
+++ services/outside_network.c	(.../release-1.0.2)	(revision 1182)
@@ -668,6 +668,23 @@
 {
 	if(!p)
 		return;
+	if(outnet && outnet->udp_wait_first &&
+                (p->next_waiting || p == outnet->udp_wait_last) ) {
+                /* delete from waiting list, if it is in the waiting list */
+                struct pending* prev = NULL, *x = outnet->udp_wait_first;
+                while(x && x != p) {
+                        prev = x;
+                        x = x->next_waiting;
+                }
+                if(x) {
+                        log_assert(x == p);
+                        if(prev)
+                                prev->next_waiting = p->next_waiting;
+                        else    outnet->udp_wait_first = p->next_waiting;
+                        if(outnet->udp_wait_last == p)
+                                outnet->udp_wait_last = prev;
+                }
+        }
 	if(outnet) {
 		(void)rbtree_delete(outnet->pending, p->node.key);
 	}
@@ -1067,7 +1084,8 @@
 		if(sq->status == serviced_query_UDP_EDNS ||
 			sq->status == serviced_query_UDP) {
 			struct pending* p = (struct pending*)sq->pending;
-			portcomm_loweruse(sq->outnet, p->pc);
+			if(p->pc)
+				portcomm_loweruse(sq->outnet, p->pc);
 			pending_delete(sq->outnet, p);
 			outnet_send_wait_udp(sq->outnet);
 		} else {
Index: validator/val_nsec.c
===================================================================
--- validator/val_nsec.c	(.../release-1.0.1)	(revision 1182)
+++ validator/val_nsec.c	(.../release-1.0.2)	(revision 1182)
@@ -343,10 +343,16 @@
 
 	/* If an NS set exists at this name, and NOT a SOA (so this is a 
 	 * zone cut, not a zone apex), then we should have gotten a 
-	 * referral (or we just got the wrong NSEC). */
-	if(nsec_has_type(nsec, LDNS_RR_TYPE_NS) && 
+	 * referral (or we just got the wrong NSEC).
+	 * The reverse of this check is used when qtype is DS, since that
+	 * must use the NSEC from above the zone cut. */
+	if(qinfo->qtype != LDNS_RR_TYPE_DS &&
+		nsec_has_type(nsec, LDNS_RR_TYPE_NS) &&
 		!nsec_has_type(nsec, LDNS_RR_TYPE_SOA)) {
 		return 0;
+	} else if(qinfo->qtype == LDNS_RR_TYPE_DS &&
+		nsec_has_type(nsec, LDNS_RR_TYPE_SOA)) {
+		return 0;
 	}
 
 	return 1;
Index: iterator/iter_scrub.c
===================================================================
--- iterator/iter_scrub.c	(.../release-1.0.1)	(revision 1182)
+++ iterator/iter_scrub.c	(.../release-1.0.2)	(revision 1182)
@@ -320,7 +320,7 @@
 {
 	uint8_t* sname = qinfo->qname;
 	size_t snamelen = qinfo->qname_len;
-	struct rrset_parse* rrset, *prev;
+	struct rrset_parse* rrset, *prev, *nsset=NULL;
 
 	if(FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NOERROR &&
 		FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NXDOMAIN)
@@ -416,7 +416,10 @@
 		}
 
 		/* Mark the additional names from relevant rrset as OK. */
-		mark_additional_rrset(pkt, msg, rrset);
+		/* only for RRsets that match the query name, other ones
+		 * will be removed by sanitize, so no additional for them */
+		if(dname_pkt_compare(pkt, qinfo->qname, rrset->dname) == 0)
+			mark_additional_rrset(pkt, msg, rrset);
 		
 		prev = rrset;
 		rrset = rrset->rrset_all_next;
@@ -424,6 +427,24 @@
 
 	/* Mark additional names from AUTHORITY */
 	while(rrset && rrset->section == LDNS_SECTION_AUTHORITY) {
+		if(rrset->type==LDNS_RR_TYPE_DNAME ||
+			rrset->type==LDNS_RR_TYPE_CNAME ||
+			rrset->type==LDNS_RR_TYPE_A ||
+			rrset->type==LDNS_RR_TYPE_AAAA) {
+			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) {
+			if(nsset == NULL) {
+				nsset = rrset;
+			} else {
+				remove_rrset("normalize: removing irrelevant "
+					"RRset:", pkt, msg, prev, &rrset);
+				continue;
+			}
+		}
 		mark_additional_rrset(pkt, msg, rrset);
 		prev = rrset;
 		rrset = rrset->rrset_all_next;
@@ -447,6 +468,13 @@
 				continue;
 			}
 		}
+		if(rrset->type==LDNS_RR_TYPE_DNAME || 
+			rrset->type==LDNS_RR_TYPE_CNAME ||
+			rrset->type==LDNS_RR_TYPE_NS) {
+			remove_rrset("normalize: removing irrelevant "
+				"RRset:", pkt, msg, prev, &rrset);
+			continue;
+		}
 		prev = rrset;
 		rrset = rrset->rrset_all_next;
 	}
@@ -498,18 +526,47 @@
  *
  * @param pkt: packet.
  * @param msg: msg to normalize.
+ * @param qinfo: the question originally asked.
  * @param zonename: name of server zone.
  * @param env: module environment with config and cache.
  * @return 0 on error.
  */
 static int
-scrub_sanitize(ldns_buffer* pkt, struct msg_parse* msg, uint8_t* zonename,
-	struct module_env* env)
+scrub_sanitize(ldns_buffer* pkt, struct msg_parse* msg, 
+	struct query_info* qinfo, uint8_t* zonename, struct module_env* env)
 {
 	struct rrset_parse* rrset, *prev;
 	prev = NULL;
 	rrset = msg->rrset_first;
 
+	/* the first DNAME is allowed to stay. It needs checking before
+	 * it can be used from the cache. After normalization, an initial 
+	 * DNAME will have a correctly synthesized CNAME after it. */
+	if(rrset && rrset->type == LDNS_RR_TYPE_DNAME && 
+		rrset->section == LDNS_SECTION_ANSWER &&
+		pkt_strict_sub(pkt, qinfo->qname, rrset->dname) &&
+		pkt_sub(pkt, rrset->dname, zonename)) {
+		prev = rrset; /* DNAME allowed to stay in answer section */
+		rrset = rrset->rrset_all_next;
+	}
+	
+	/* remove all records from the answer section that are 
+	 * not the same domain name as the query domain name.
+	 * The answer section should contain rrsets with the same name
+	 * as the question. For DNAMEs a CNAME has been synthesized.
+	 * Wildcards have the query name in answer section.
+	 * ANY queries get query name in answer section.
+	 * Remainders of CNAME chains are cut off and resolved by iterator. */
+	while(rrset && rrset->section == LDNS_SECTION_ANSWER) {
+		if(dname_pkt_compare(pkt, qinfo->qname, rrset->dname) != 0) {
+			remove_rrset("sanitize: removing extraneous answer "
+				"RRset:", pkt, msg, prev, &rrset);
+			continue;
+		}
+		prev = rrset;
+		rrset = rrset->rrset_all_next;
+	}
+
 	/* At this point, we brutally remove ALL rrsets that aren't 
 	 * children of the originating zone. The idea here is that, 
 	 * as far as we know, the server that we contacted is ONLY 
@@ -517,6 +574,8 @@
 	 * be authoriative for any other zones, and of course, MAY 
 	 * NOT be authoritative for some subdomains of the originating 
 	 * zone. */
+	prev = NULL;
+	rrset = msg->rrset_first;
 	while(rrset) {
 		
 		/* skip DNAME records -- they will always be followed by a 
@@ -589,7 +648,7 @@
 	if(!scrub_normalize(pkt, msg, qinfo, region))
 		return 0;
 	/* delete all out-of-zone information */
-	if(!scrub_sanitize(pkt, msg, zonename, env))
+	if(!scrub_sanitize(pkt, msg, qinfo, zonename, env))
 		return 0;
 	return 1;
 }
Index: daemon/unbound.c
===================================================================
--- daemon/unbound.c	(.../release-1.0.1)	(revision 1182)
+++ daemon/unbound.c	(.../release-1.0.2)	(revision 1182)
@@ -141,6 +141,21 @@
 		log_warn("increased limit(open files) from %u to %u",
 			(unsigned)avail, (unsigned)total+10);
 	}
+	if(total > 1024 && 
+		strncmp(event_get_version(), "mini-event", 10) == 0) {
+		log_err("too many file descriptors requested. The builtin"
+			"mini-event cannot handle more than 1024. Config "
+			"for less fds or compile with libevent");
+		fatal_exit("configuration needs too many file descriptors");
+	}
+	if(perthread > 64 && 
+		strncmp(event_get_version(), "winsock-event", 13) == 0) {
+		log_err("too many file descriptors requested. The winsock"
+			" event handler cannot handle more than 64 per "
+			" thread. Config for less fds or compile with "
+			" libevent");
+		fatal_exit("configuration needs too many file descriptors");
+	}
 #else	
 	(void)cfg;
 #endif /* HAVE_GETRLIMIT */
Index: doc/Changelog
===================================================================
--- doc/Changelog	(.../release-1.0.1)	(revision 1182)
+++ doc/Changelog	(.../release-1.0.2)	(revision 1182)
@@ -1,3 +1,32 @@
+6 August 2008: Wouter
+	- patch for scrubber that removes ends of CNAMEs, no more DNAMEs
+	  from cache. Remove more irrelevant rrsets from the message.
+
+5 August 2008: Wouter
+	- fixup DS test so apex nodata works again (from trunk).
+
+4 August 2008: Wouter
+	- Bug #201 fixup from trunk; fixes segfault on exit cleanup
+	- iana port nrs updated.
+
+30 July 2008: Wouter
+	- fixup DS qtype validation bug. (fix taken from trunk).
+
+21 July 2008: Wouter
+	- #198: nicer entropy warning message. manpage OS hints.
+
+19 July 2008: Wouter
+	- #198: fixup manpage to suggest entropy chroot fix.
+
+18 July 2008: Wouter
+	- branch for 1.0 support.
+
+17 July 2008: Wouter
+	- fix bug #196, compile outside source tree.
+	- fix bug #195, add --with-username=user configure option.
+	- print error and exit if started with config that requires more
+	  fds than the builtin minievent can handle.
+
 16 July 2008: Wouter
 	- made svn tag 1.0.1, trunk now 1.0.2
 	- sha256 checksums enabled in makedist.sh


-- 
Robert Edmonds
edmonds@debian.org

Attachment: signature.asc
Description: Digital signature


Reply to: