Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
Hi, Please unblock unbound 1.4.22-3. This version addresses CVE-2014-8602, "denial of service by making resolver chase endless series of delegations", based on upstream's patch: http://unbound.net/downloads/CVE-2014-8602.txt Actually, I cherry picked upstream's svn r3289 and applied it against the version of unbound in testing: http://anonscm.debian.org/cgit/users/edmonds/unbound.git/commit/?h=branches/1.4.22%2bjessie&id=15037ee5f483ad5ef10ad7c99221b3b77018413b The Debian bug tracking this issue is #772622. This issue was found in at least three recursive DNS servers: BIND, Unbound, and PowerDNS Recursor and was fixed in coordinated releases. See also: https://kb.isc.org/article/AA-01216/ "A Defect in Delegation Handling Can Be Exploited to Crash BIND" [CVE-2014-8500] (And Debian #772610.) http://doc.powerdns.com/md/security/powerdns-advisory-2014-02/ "PowerDNS Recursor 3.6.1 and earlier can be made to provide bad service" [CVE-2014-8601] The debdiff is below. Thanks! diff -Nru unbound-1.4.22/debian/changelog unbound-1.4.22/debian/changelog --- unbound-1.4.22/debian/changelog 2014-08-18 16:22:31.000000000 -0400 +++ unbound-1.4.22/debian/changelog 2014-12-09 17:55:16.000000000 -0500 @@ -1,3 +1,10 @@ +unbound (1.4.22-3) unstable; urgency=medium + + * Fix CVE-2014-8602: denial of service by making resolver chase endless + series of delegations; closes: #772622. + + -- Robert Edmonds <edmo...@debian.org> Tue, 09 Dec 2014 17:52:08 -0500 + unbound (1.4.22-2) unstable; urgency=medium * Drop unneeded Build-Dependency on doxygen. diff -Nru unbound-1.4.22/debian/patches/debian-changes unbound-1.4.22/debian/patches/debian-changes --- unbound-1.4.22/debian/patches/debian-changes 2014-08-18 16:23:10.000000000 -0400 +++ unbound-1.4.22/debian/patches/debian-changes 2014-12-09 17:58:56.000000000 -0500 @@ -5,15 +5,12 @@ information below has been extracted from the changelog. Adjust it or drop it. . - unbound (1.4.22-2) unstable; urgency=medium + unbound (1.4.22-3) unstable; urgency=medium . - * Drop unneeded Build-Dependency on doxygen. - * Drop unneeded Build-Dependency on automake. (Unbound does not use - automake.) - * Use dh_autotools-dev_updateconfig to update the config.{guess,sub} files - at build time; closes: #746313. -Author: Robert S. Edmonds <edmo...@debian.org> -Bug-Debian: http://bugs.debian.org/746313 + * Fix CVE-2014-8602: denial of service by making resolver chase endless + series of delegations; closes: #772622. +Author: Robert Edmonds <edmo...@debian.org> +Bug-Debian: http://bugs.debian.org/772622 --- The information above should follow the Patch Tagging Guidelines, please @@ -66,6 +63,151 @@ If turned off, the server does not listen for control commands. .TP 5 .B control\-interface: <ip address> +--- unbound-1.4.22.orig/iterator/iterator.c ++++ unbound-1.4.22/iterator/iterator.c +@@ -120,6 +120,7 @@ iter_new(struct module_qstate* qstate, i + iq->query_restart_count = 0; + iq->referral_count = 0; + iq->sent_count = 0; ++ iq->target_count = NULL; + iq->wait_priming_stub = 0; + iq->refetch_glue = 0; + iq->dnssec_expected = 0; +@@ -445,6 +446,26 @@ handle_cname_response(struct module_qsta + return 1; + } + ++/** create target count structure for this query */ ++static void ++target_count_create(struct iter_qstate* iq) ++{ ++ if(!iq->target_count) { ++ iq->target_count = (int*)calloc(2, sizeof(int)); ++ /* if calloc fails we simply do not track this number */ ++ if(iq->target_count) ++ iq->target_count[0] = 1; ++ } ++} ++ ++static void ++target_count_increase(struct iter_qstate* iq, int num) ++{ ++ target_count_create(iq); ++ if(iq->target_count) ++ iq->target_count[1] += num; ++} ++ + /** + * Generate a subrequest. + * Generate a local request event. Local events are tied to this module, and +@@ -516,6 +537,10 @@ generate_sub_request(uint8_t* qname, siz + subiq = (struct iter_qstate*)subq->minfo[id]; + memset(subiq, 0, sizeof(*subiq)); + subiq->num_target_queries = 0; ++ target_count_create(iq); ++ subiq->target_count = iq->target_count; ++ if(iq->target_count) ++ iq->target_count[0] ++; /* extra reference */ + subiq->num_current_queries = 0; + subiq->depth = iq->depth+1; + outbound_list_init(&subiq->outlist); +@@ -1342,6 +1367,12 @@ query_for_targets(struct module_qstate* + + if(iq->depth == ie->max_dependency_depth) + return 0; ++ if(iq->depth > 0 && iq->target_count && ++ iq->target_count[1] > MAX_TARGET_COUNT) { ++ verbose(VERB_QUERY, "request has exceeded the maximum " ++ "number of glue fetches %d", iq->target_count[1]); ++ return 0; ++ } + + iter_mark_cycle_targets(qstate, iq->dp); + missing = (int)delegpt_count_missing_targets(iq->dp); +@@ -1524,6 +1555,7 @@ processLastResort(struct module_qstate* + return error_response(qstate, id, LDNS_RCODE_SERVFAIL); + } + iq->num_target_queries += qs; ++ target_count_increase(iq, qs); + if(qs != 0) { + qstate->ext_state[id] = module_wait_subquery; + return 0; /* and wait for them */ +@@ -1533,6 +1565,12 @@ processLastResort(struct module_qstate* + verbose(VERB_QUERY, "maxdepth and need more nameservers, fail"); + return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); + } ++ if(iq->depth > 0 && iq->target_count && ++ iq->target_count[1] > MAX_TARGET_COUNT) { ++ verbose(VERB_QUERY, "request has exceeded the maximum " ++ "number of glue fetches %d", iq->target_count[1]); ++ return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); ++ } + /* mark cycle targets for parent-side lookups */ + iter_mark_pside_cycle_targets(qstate, iq->dp); + /* see if we can issue queries to get nameserver addresses */ +@@ -1562,6 +1600,7 @@ processLastResort(struct module_qstate* + if(query_count != 0) { /* suspend to await results */ + verbose(VERB_ALGO, "try parent-side glue lookup"); + iq->num_target_queries += query_count; ++ target_count_increase(iq, query_count); + qstate->ext_state[id] = module_wait_subquery; + return 0; + } +@@ -1717,6 +1756,7 @@ processQueryTargets(struct module_qstate + return error_response(qstate, id, LDNS_RCODE_SERVFAIL); + } + iq->num_target_queries += extra; ++ target_count_increase(iq, extra); + if(iq->num_target_queries > 0) { + /* wait to get all targets, we want to try em */ + verbose(VERB_ALGO, "wait for all targets for fallback"); +@@ -1757,6 +1797,7 @@ processQueryTargets(struct module_qstate + /* errors ignored, these targets are not strictly necessary for + * this result, we do not have to reply with SERVFAIL */ + iq->num_target_queries += extra; ++ target_count_increase(iq, extra); + } + + /* Add the current set of unused targets to our queue. */ +@@ -1802,6 +1843,7 @@ processQueryTargets(struct module_qstate + return 1; + } + iq->num_target_queries += qs; ++ target_count_increase(iq, qs); + } + /* Since a target query might have been made, we + * need to check again. */ +@@ -2894,6 +2936,8 @@ iter_clear(struct module_qstate* qstate, + iq = (struct iter_qstate*)qstate->minfo[id]; + if(iq) { + outbound_list_clear(&iq->outlist); ++ if(iq->target_count && --iq->target_count[0] == 0) ++ free(iq->target_count); + iq->num_current_queries = 0; + } + qstate->minfo[id] = NULL; +--- unbound-1.4.22.orig/iterator/iterator.h ++++ unbound-1.4.22/iterator/iterator.h +@@ -52,6 +52,8 @@ struct iter_donotq; + struct iter_prep_list; + struct iter_priv; + ++/** max number of targets spawned for a query and its subqueries */ ++#define MAX_TARGET_COUNT 32 + /** max number of query restarts. Determines max number of CNAME chain. */ + #define MAX_RESTART_COUNT 8 + /** max number of referrals. Makes sure resolver does not run away */ +@@ -254,6 +256,10 @@ struct iter_qstate { + + /** number of queries fired off */ + int sent_count; ++ ++ /** number of target queries spawned in [1], for this query and its ++ * subqueries, the malloced-array is shared, [0] refcount. */ ++ int* target_count; + + /** + * The query must store NS records from referrals as parentside RRs --- unbound-1.4.22.orig/smallapp/unbound-control-setup.sh +++ unbound-1.4.22/smallapp/unbound-control-setup.sh @@ -157,6 +157,6 @@ chmod o-rw $SVR_BASE.pem $SVR_BASE.key $ -- Robert Edmonds edmo...@debian.org -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org