./0000775000175000017500000000000012511411356011434 5ustar nielsenrnielsenr./make-etc-initd-bind-stop-work.patch0000664000175000017500000000174512511411356020134 0ustar nielsenrnielsenrbind: make "/etc/init.d/bind stop" work Upstream-Status: Inappropriate [configuration] Add some configurations, make rndc command be able to controls the named daemon. Signed-off-by: Roy Li --- conf/named.conf | 5 +++++ conf/rndc.conf | 5 +++++ 2 files changed, 10 insertions(+), 0 deletions(-) create mode 100644 conf/rndc.conf diff --git a/conf/named.conf b/conf/named.conf index 95829cf..c8899e7 100644 --- a/conf/named.conf +++ b/conf/named.conf @@ -47,3 +47,8 @@ zone "255.in-addr.arpa" { // root-delegation-only exclude { "DE"; "MUSEUM"; }; include "/etc/bind/named.conf.local"; +include "/etc/bind/rndc.key" ; +controls { + inet 127.0.0.1 allow { localhost; } + keys { rndc-key; }; +}; diff --git a/conf/rndc.conf b/conf/rndc.conf new file mode 100644 index 0000000..a0b481d --- /dev/null +++ b/conf/rndc.conf @@ -0,0 +1,5 @@ +include "/etc/bind/rndc.key"; +options { + default-server localhost; + default-key rndc-key; +}; -- 1.7.5.4 ./init.d-add-support-for-read-only-rootfs.patch0000664000175000017500000000352712511411356022077 0ustar nielsenrnielsenrSubject: init.d: add support for read-only rootfs Upstream-Status: Inappropriate [oe specific] Signed-off-by: Chen Qi --- init.d | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/init.d b/init.d index 0111ed4..24677c8 100644 --- a/init.d +++ b/init.d @@ -6,8 +6,48 @@ PATH=/sbin:/bin:/usr/sbin:/usr/bin # Don't modify this line, change or create /etc/default/bind9. OPTIONS="" +test -f /etc/default/rcS && . /etc/default/rcS test -f /etc/default/bind9 && . /etc/default/bind9 +# This function is here because it's possible that /var and / are on different partitions. +is_on_read_only_partition () { + DIRECTORY=$1 + dir=`readlink -f $DIRECTORY` + while true; do + if [ ! -d "$dir" ]; then + echo "ERROR: $dir is not a directory" + exit 1 + else + for flag in `awk -v dir=$dir '{ if ($2 == dir) { print "FOUND"; split($4,FLAGS,",") } }; \ + END { for (f in FLAGS) print FLAGS[f] }' < /proc/mounts`; do + [ "$flag" = "FOUND" ] && partition="read-write" + [ "$flag" = "ro" ] && { partition="read-only"; break; } + done + if [ "$dir" = "/" -o -n "$partition" ]; then + break + else + dir=`dirname $dir` + fi + fi + done + [ "$partition" = "read-only" ] && echo "yes" || echo "no" +} + +bind_mount () { + olddir=$1 + newdir=$2 + mkdir -p $olddir + cp -a $newdir/* $olddir + mount --bind $olddir $newdir +} + +# Deal with read-only rootfs +if [ "$ROOTFS_READ_ONLY" = "yes" ]; then + [ "$VERBOSE" != "no" ] && echo "WARN: start bind service in read-only rootfs" + [ `is_on_read_only_partition /etc/bind` = "yes" ] && bind_mount /var/volatile/bind/etc /etc/bind + [ `is_on_read_only_partition /var/named` = "yes" ] && bind_mount /var/volatile/bind/named /var/named +fi + test -x /usr/sbin/rndc || exit 0 case "$1" in -- 1.7.9.5 ./bind-9.8.1-CVE-2012-5166.patch0000664000175000017500000000726212511411356015447 0ustar nielsenrnielsenrbind_Fix_for_CVE-2012-5166 Upstream-Status: Backport Reference:http://launchpadlibrarian.net/119212498/bind9_1%3A9.7.3.dfsOBg -1ubuntu2.6_1%3A9.7.3.dfsg-1ubuntu2.7.diff.gz ISC BIND 9.x before 9.7.6-P4, 9.8.x before 9.8.3-P4, 9.9.x before 9.9.1-P4, and 9.4-ESV and 9.6-ESV before 9.6-ESV-R7-P4 allows remote attackers to cause a denial of service (named daemon hang) via unspecified combinations of resource records. http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-5166 Signed-off-by: yanjun.zhu diff -urpN a/bin/named/query.c b/bin/named/query.c --- a/bin/named/query.c 2012-10-22 13:24:27.000000000 +0800 +++ b/bin/named/query.c 2012-10-22 13:17:04.000000000 +0800 @@ -1137,13 +1137,6 @@ query_isduplicate(ns_client_t *client, d mname = NULL; } - /* - * If the dns_name_t we're looking up is already in the message, - * we don't want to trigger the caller's name replacement logic. - */ - if (name == mname) - mname = NULL; - *mnamep = mname; CTRACE("query_isduplicate: false: done"); @@ -1341,6 +1334,7 @@ query_addadditional(void *arg, dns_name_ if (dns_rdataset_isassociated(rdataset) && !query_isduplicate(client, fname, type, &mname)) { if (mname != NULL) { + INSIST(mname != fname); query_releasename(client, &fname); fname = mname; } else @@ -1401,11 +1395,13 @@ query_addadditional(void *arg, dns_name_ mname = NULL; if (!query_isduplicate(client, fname, dns_rdatatype_a, &mname)) { - if (mname != NULL) { - query_releasename(client, &fname); - fname = mname; - } else - need_addname = ISC_TRUE; + if (mname != fname) { + if (mname != NULL) { + query_releasename(client, &fname); + fname = mname; + } else + need_addname = ISC_TRUE; + } ISC_LIST_APPEND(fname->list, rdataset, link); added_something = ISC_TRUE; if (sigrdataset != NULL && @@ -1444,11 +1440,13 @@ query_addadditional(void *arg, dns_name_ mname = NULL; if (!query_isduplicate(client, fname, dns_rdatatype_aaaa, &mname)) { - if (mname != NULL) { - query_releasename(client, &fname); - fname = mname; - } else - need_addname = ISC_TRUE; + if (mname != fname) { + if (mname != NULL) { + query_releasename(client, &fname); + fname = mname; + } else + need_addname = ISC_TRUE; + } ISC_LIST_APPEND(fname->list, rdataset, link); added_something = ISC_TRUE; if (sigrdataset != NULL && @@ -1960,22 +1958,24 @@ query_addadditional2(void *arg, dns_name crdataset->type == dns_rdatatype_aaaa) { if (!query_isduplicate(client, fname, crdataset->type, &mname)) { - if (mname != NULL) { - /* - * A different type of this name is - * already stored in the additional - * section. We'll reuse the name. - * Note that this should happen at most - * once. Otherwise, fname->link could - * leak below. - */ - INSIST(mname0 == NULL); - - query_releasename(client, &fname); - fname = mname; - mname0 = mname; - } else - need_addname = ISC_TRUE; + if (mname != fname) { + if (mname != NULL) { + /* + * A different type of this name is + * already stored in the additional + * section. We'll reuse the name. + * Note that this should happen at most + * once. Otherwise, fname->link could + * leak below. + */ + INSIST(mname0 == NULL); + + query_releasename(client, &fname); + fname = mname; + mname0 = mname; + } else + need_addname = ISC_TRUE; + } ISC_LIST_UNLINK(cfname.list, crdataset, link); ISC_LIST_APPEND(fname->list, crdataset, link); added_something = ISC_TRUE; ./bind-CVE-2012-1667.patch0000664000175000017500000000611212511411356014767 0ustar nielsenrnielsenrbind CVE-2012-1667 Upstream-Status: Backport ISC BIND 9.x before 9.7.6-P1, 9.8.x before 9.8.3-P1, 9.9.x before 9.9.1-P1, and 9.4-ESV and 9.6-ESV before 9.6-ESV-R7-P1 does not properly handle resource records with a zero-length RDATA section, which allows remote DNS servers to cause a denial of service (daemon crash or data corruption) or obtain sensitive information from process memory via a crafted record. http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-1667 The cve patch comes from bind97-9.7.0-10.P2.el5_8.1.src.rpm package. Signed-off-by: Li Wang --- lib/dns/rdata.c | 8 ++++---- lib/dns/rdataslab.c | 11 ++++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c index 063b1f6..9337a80 100644 --- a/lib/dns/rdata.c +++ b/lib/dns/rdata.c @@ -325,8 +325,8 @@ dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) { REQUIRE(rdata1 != NULL); REQUIRE(rdata2 != NULL); - REQUIRE(rdata1->data != NULL); - REQUIRE(rdata2->data != NULL); + REQUIRE(rdata1->length == 0 || rdata1->data != NULL); + REQUIRE(rdata2->length == 0 || rdata2->data != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2)); @@ -356,8 +356,8 @@ dns_rdata_casecompare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) { REQUIRE(rdata1 != NULL); REQUIRE(rdata2 != NULL); - REQUIRE(rdata1->data != NULL); - REQUIRE(rdata2->data != NULL); + REQUIRE(rdata1->length == 0 || rdata1->data != NULL); + REQUIRE(rdata2->length == 0 || rdata2->data != NULL); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1)); REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2)); diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c index a41f16f..ed13b30 100644 --- a/lib/dns/rdataslab.c +++ b/lib/dns/rdataslab.c @@ -125,6 +125,11 @@ isc_result_t dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, isc_region_t *region, unsigned int reservelen) { + /* + * Use &removed as a sentinal pointer for duplicate + * rdata as rdata.data == NULL is valid. + */ + static unsigned char removed; struct xrdata *x; unsigned char *rawbuf; #if DNS_RDATASET_FIXED @@ -168,6 +173,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, INSIST(result == ISC_R_SUCCESS); dns_rdata_init(&x[i].rdata); dns_rdataset_current(rdataset, &x[i].rdata); + INSIST(x[i].rdata.data != &removed); #if DNS_RDATASET_FIXED x[i].order = i; #endif @@ -200,8 +206,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, */ for (i = 1; i < nalloc; i++) { if (compare_rdata(&x[i-1].rdata, &x[i].rdata) == 0) { - x[i-1].rdata.data = NULL; - x[i-1].rdata.length = 0; + x[i-1].rdata.data = &removed; #if DNS_RDATASET_FIXED /* * Preserve the least order so A, B, A -> A, B @@ -291,7 +296,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, #endif for (i = 0; i < nalloc; i++) { - if (x[i].rdata.data == NULL) + if (x[i].rdata.data == &removed) continue; #if DNS_RDATASET_FIXED offsettable[x[i].order] = rawbuf - offsetbase; -- 1.7.0.5 ./dont-test-on-host.patch0000664000175000017500000000075412511411356015771 0ustar nielsenrnielsenrUpstream-Status: Pending Signed-off-by Saul Wold Index: bind-9.9.5/bin/Makefile.in =================================================================== --- bind-9.9.5.orig/bin/Makefile.in +++ bind-9.9.5/bin/Makefile.in @@ -19,7 +19,7 @@ srcdir = @srcdir@ VPATH = @srcdir@ top_srcdir = @top_srcdir@ -SUBDIRS = named rndc dig dnssec tools tests nsupdate \ +SUBDIRS = named rndc dig dnssec tools nsupdate \ check confgen @PYTHON_TOOLS@ @PKCS11_TOOLS@ TARGETS = ./bind-CVE-2012-3817.patch0000664000175000017500000000244412511411356014772 0ustar nielsenrnielsenrbind: fix for CVE-2012-3817 Upstream-Status: Backport ISC BIND 9.4.x, 9.5.x, 9.6.x, and 9.7.x before 9.7.6-P2; 9.8.x before 9.8.3-P2; 9.9.x before 9.9.1-P2; and 9.6-ESV before 9.6-ESV-R7-P2, when DNSSEC validation is enabled, does not properly initialize the failing-query cache, which allows remote attackers to cause a denial of service (assertion failure and daemon exit) by sending many queries. http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-3817 This patch is back-ported from bind-9.3.6-20.P1.el5_8.2.src.rpm package. Signed-off-by: Ming Liu --- resolver.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -8318,6 +8318,7 @@ dns_resolver_addbadcache(dns_resolver_t goto cleanup; bad->type = type; bad->hashval = hashval; + bad->expire = *expire; isc_buffer_init(&buffer, bad + 1, name->length); dns_name_init(&bad->name, NULL); dns_name_copy(name, &bad->name, &buffer); @@ -8329,8 +8330,8 @@ dns_resolver_addbadcache(dns_resolver_t if (resolver->badcount < resolver->badhash * 2 && resolver->badhash > DNS_BADCACHE_SIZE) resizehash(resolver, &now, ISC_FALSE); - } - bad->expire = *expire; + } else + bad->expire = *expire; cleanup: UNLOCK(&resolver->lock); } ./bind-CVE-2011-4313.patch0000664000175000017500000000604712511411356014764 0ustar nielsenrnielsenrThe patch to fix CVE-2011-4313 Upstream-Status: Backport Reference: https://www.redhat.com/security/data/cve/CVE-2011-4313.html query.c in ISC BIND 9.0.x through 9.6.x, 9.4-ESV through 9.4-ESV-R5, 9.6-ESV through 9.6-ESV-R5, 9.7.0 through 9.7.4, 9.8.0 through 9.8.1, and 9.9.0a1 through 9.9.0b1 allows remote attackers to cause a denial of service (assertion failure and named exit) via unknown vectors related to recursive DNS queries, error logging, and the caching of an invalid record by the resolver. Signed-off-by Ming Liu --- bin/named/query.c | 19 ++++++++----------- lib/dns/rbtdb.c | 4 ++-- 2 files changed, 10 insertions(+), 13 deletions(-) --- a/bin/named/query.c +++ b/bin/named/query.c @@ -1393,11 +1393,9 @@ query_addadditional(void *arg, dns_name_ goto addname; if (result == DNS_R_NCACHENXRRSET) { dns_rdataset_disassociate(rdataset); - /* - * Negative cache entries don't have sigrdatasets. - */ - INSIST(sigrdataset == NULL || - ! dns_rdataset_isassociated(sigrdataset)); + if (sigrdataset != NULL && + dns_rdataset_isassociated(sigrdataset)) + dns_rdataset_disassociate(sigrdataset); } if (result == ISC_R_SUCCESS) { mname = NULL; @@ -1438,8 +1436,9 @@ query_addadditional(void *arg, dns_name_ goto addname; if (result == DNS_R_NCACHENXRRSET) { dns_rdataset_disassociate(rdataset); - INSIST(sigrdataset == NULL || - ! dns_rdataset_isassociated(sigrdataset)); + if (sigrdataset != NULL && + dns_rdataset_isassociated(sigrdataset)) + dns_rdataset_disassociate(sigrdataset); } if (result == ISC_R_SUCCESS) { mname = NULL; @@ -1889,10 +1888,8 @@ query_addadditional2(void *arg, dns_name goto setcache; if (result == DNS_R_NCACHENXRRSET) { dns_rdataset_disassociate(rdataset); - /* - * Negative cache entries don't have sigrdatasets. - */ - INSIST(! dns_rdataset_isassociated(sigrdataset)); + if (dns_rdataset_isassociated(sigrdataset)) + dns_rdataset_disassociate(sigrdataset); } if (result == ISC_R_SUCCESS) { /* Remember the result as a cache */ --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -5053,7 +5053,7 @@ cache_find(dns_db_t *db, dns_name_t *nam rdataset); if (need_headerupdate(found, search.now)) update = found; - if (foundsig != NULL) { + if (!NEGATIVE(found) && foundsig != NULL) { bind_rdataset(search.rbtdb, node, foundsig, search.now, sigrdataset); if (need_headerupdate(foundsig, search.now)) @@ -5596,7 +5596,7 @@ zone_findrdataset(dns_db_t *db, dns_dbno } if (found != NULL) { bind_rdataset(rbtdb, rbtnode, found, now, rdataset); - if (foundsig != NULL) + if (!NEGATIVE(found) && foundsig != NULL) bind_rdataset(rbtdb, rbtnode, foundsig, now, sigrdataset); } @@ -5685,7 +5685,7 @@ cache_findrdataset(dns_db_t *db, dns_dbn } if (found != NULL) { bind_rdataset(rbtdb, rbtnode, found, now, rdataset); - if (foundsig != NULL) + if (!NEGATIVE(found) && foundsig != NULL) bind_rdataset(rbtdb, rbtnode, foundsig, now, sigrdataset); } ./bind-CVE-2013-2266.patch0000664000175000017500000000246112511411356014767 0ustar nielsenrnielsenrbind: fix for CVE-2013-2266 Upstream-Status: Backport libdns in ISC BIND 9.7.x and 9.8.x before 9.8.4-P2, 9.8.5 before 9.8.5b2, 9.9.x before 9.9.2-P2, and 9.9.3 before 9.9.3b2 on UNIX platforms allows remote attackers to cause a denial of service (memory consumption) via a crafted regular expression, as demonstrated by a memory-exhaustion attack against a machine running a named process. http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-2266 Signed-off-by Ming Liu --- config.h.in | 3 --- configure.in | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) --- a/config.h.in +++ b/config.h.in @@ -277,9 +277,6 @@ int sigwait(const unsigned int *set, int /* Define if your OpenSSL version supports GOST. */ #undef HAVE_OPENSSL_GOST -/* Define to 1 if you have the header file. */ -#undef HAVE_REGEX_H - /* Define to 1 if you have the `setegid' function. */ #undef HAVE_SETEGID --- a/configure.in +++ b/configure.in @@ -279,7 +279,7 @@ esac AC_HEADER_STDC -AC_CHECK_HEADERS(fcntl.h regex.h sys/time.h unistd.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h,,, +AC_CHECK_HEADERS(fcntl.h sys/time.h unistd.h sys/sockio.h sys/select.h sys/param.h sys/sysctl.h net/if6.h,,, [$ac_includes_default #ifdef HAVE_SYS_PARAM_H # include ./bind-Fix-CVE-2012-4244.patch0000664000175000017500000001157112511411356015512 0ustar nielsenrnielsenrbind_Fix_for_CVE-2012-4244 Upstream-Status: Backport Reference:https://bugzilla.novell.com/attachment.cgi?id=505661&action=edit ISC BIND 9.x before 9.7.6-P3, 9.8.x before 9.8.3-P3, 9.9.x before 9.9.1-P3, and 9.4-ESV and 9.6-ESV before 9.6-ESV-R7-P3 allows remote attackers to cause a denial of service (assertion failure and named daemon exit) via a query for a long resource record. Signed-off-by: yanjun.zhu diff -urpN a/lib/dns/include/dns/rdata.h b/lib/dns/include/dns/rdata.h --- a/lib/dns/include/dns/rdata.h 2012-10-08 12:19:42.000000000 +0800 +++ b/lib/dns/include/dns/rdata.h 2012-10-08 11:26:43.000000000 +0800 @@ -147,6 +147,17 @@ struct dns_rdata { (((rdata)->flags & ~(DNS_RDATA_UPDATE|DNS_RDATA_OFFLINE)) == 0) /* + * The maximum length of a RDATA that can be sent on the wire. + * Max packet size (65535) less header (12), less name (1), type (2), + * class (2), ttl(4), length (2). + * + * None of the defined types that support name compression can exceed + * this and all new types are to be sent uncompressed. + */ + +#define DNS_RDATA_MAXLENGTH 65512U + +/* * Flags affecting rdata formatting style. Flags 0xFFFF0000 * are used by masterfile-level formatting and defined elsewhere. * See additional comments at dns_rdata_tofmttext(). diff -urpN a/lib/dns/master.c b/lib/dns/master.c --- a/lib/dns/master.c 2012-10-08 12:19:42.000000000 +0800 +++ b/lib/dns/master.c 2012-10-08 11:27:06.000000000 +0800 @@ -75,7 +75,7 @@ /*% * max message size - header - root - type - class - ttl - rdlen */ -#define MINTSIZ (65535 - 12 - 1 - 2 - 2 - 4 - 2) +#define MINTSIZ DNS_RDATA_MAXLENGTH /*% * Size for tokens in the presentation format, * The largest tokens are the base64 blocks in KEY and CERT records, diff -urpN a/lib/dns/rdata.c b/lib/dns/rdata.c --- a/lib/dns/rdata.c 2012-10-08 12:19:42.000000000 +0800 +++ b/lib/dns/rdata.c 2012-10-08 11:27:27.000000000 +0800 @@ -425,6 +425,7 @@ dns_rdata_fromwire(dns_rdata_t *rdata, d isc_buffer_t st; isc_boolean_t use_default = ISC_FALSE; isc_uint32_t activelength; + size_t length; REQUIRE(dctx != NULL); if (rdata != NULL) { @@ -455,6 +456,14 @@ dns_rdata_fromwire(dns_rdata_t *rdata, d } /* + * Reject any rdata that expands out to more than DNS_RDATA_MAXLENGTH + * as we cannot transmit it. + */ + length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st); + if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH) + result = DNS_R_FORMERR; + + /* * We should have consumed all of our buffer. */ if (result == ISC_R_SUCCESS && !buffer_empty(source)) @@ -462,8 +471,7 @@ dns_rdata_fromwire(dns_rdata_t *rdata, d if (rdata != NULL && result == ISC_R_SUCCESS) { region.base = isc_buffer_used(&st); - region.length = isc_buffer_usedlength(target) - - isc_buffer_usedlength(&st); + region.length = length; dns_rdata_fromregion(rdata, rdclass, type, ®ion); } @@ -598,6 +606,7 @@ dns_rdata_fromtext(dns_rdata_t *rdata, d unsigned long line; void (*callback)(dns_rdatacallbacks_t *, const char *, ...); isc_result_t tresult; + size_t length; REQUIRE(origin == NULL || dns_name_isabsolute(origin) == ISC_TRUE); if (rdata != NULL) { @@ -670,10 +679,13 @@ dns_rdata_fromtext(dns_rdata_t *rdata, d } } while (1); + length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st); + if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH) + result = ISC_R_NOSPACE; + if (rdata != NULL && result == ISC_R_SUCCESS) { region.base = isc_buffer_used(&st); - region.length = isc_buffer_usedlength(target) - - isc_buffer_usedlength(&st); + region.length = length; dns_rdata_fromregion(rdata, rdclass, type, ®ion); } if (result != ISC_R_SUCCESS) { @@ -781,6 +793,7 @@ dns_rdata_fromstruct(dns_rdata_t *rdata, isc_buffer_t st; isc_region_t region; isc_boolean_t use_default = ISC_FALSE; + size_t length; REQUIRE(source != NULL); if (rdata != NULL) { @@ -795,10 +808,13 @@ dns_rdata_fromstruct(dns_rdata_t *rdata, if (use_default) (void)NULL; + length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st); + if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH) + result = ISC_R_NOSPACE; + if (rdata != NULL && result == ISC_R_SUCCESS) { region.base = isc_buffer_used(&st); - region.length = isc_buffer_usedlength(target) - - isc_buffer_usedlength(&st); + region.length = length; dns_rdata_fromregion(rdata, rdclass, type, ®ion); } if (result != ISC_R_SUCCESS) diff -urpN a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c --- a/lib/dns/rdataslab.c 2012-10-08 12:19:42.000000000 +0800 +++ b/lib/dns/rdataslab.c 2012-10-08 11:27:54.000000000 +0800 @@ -304,6 +304,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_ length = x[i].rdata.length; if (rdataset->type == dns_rdatatype_rrsig) length++; + INSIST(length <= 0xffff); *rawbuf++ = (length & 0xff00) >> 8; *rawbuf++ = (length & 0x00ff); #if DNS_RDATASET_FIXED ./conf.patch0000664000175000017500000002417512511411356013413 0ustar nielsenrnielsenrUpstream-Status: Inappropriate [configuration] the patch is imported from openembedded project 11/30/2010 - Qing He diff -urN bind-9.3.1.orig/conf/db.0 bind-9.3.1/conf/db.0 --- bind-9.3.1.orig/conf/db.0 1970-01-01 01:00:00.000000000 +0100 +++ bind-9.3.1/conf/db.0 2005-07-10 22:14:00.000000000 +0200 @@ -0,0 +1,12 @@ +; +; BIND reverse data file for broadcast zone +; +$TTL 604800 +@ IN SOA localhost. root.localhost. ( + 1 ; Serial + 604800 ; Refresh + 86400 ; Retry + 2419200 ; Expire + 604800 ) ; Negative Cache TTL +; +@ IN NS localhost. diff -urN bind-9.3.1.orig/conf/db.127 bind-9.3.1/conf/db.127 --- bind-9.3.1.orig/conf/db.127 1970-01-01 01:00:00.000000000 +0100 +++ bind-9.3.1/conf/db.127 2005-07-10 22:14:00.000000000 +0200 @@ -0,0 +1,13 @@ +; +; BIND reverse data file for local loopback interface +; +$TTL 604800 +@ IN SOA localhost. root.localhost. ( + 1 ; Serial + 604800 ; Refresh + 86400 ; Retry + 2419200 ; Expire + 604800 ) ; Negative Cache TTL +; +@ IN NS localhost. +1.0.0 IN PTR localhost. diff -urN bind-9.3.1.orig/conf/db.empty bind-9.3.1/conf/db.empty --- bind-9.3.1.orig/conf/db.empty 1970-01-01 01:00:00.000000000 +0100 +++ bind-9.3.1/conf/db.empty 2005-07-10 22:14:00.000000000 +0200 @@ -0,0 +1,14 @@ +; BIND reverse data file for empty rfc1918 zone +; +; DO NOT EDIT THIS FILE - it is used for multiple zones. +; Instead, copy it, edit named.conf, and use that copy. +; +$TTL 86400 +@ IN SOA localhost. root.localhost. ( + 1 ; Serial + 604800 ; Refresh + 86400 ; Retry + 2419200 ; Expire + 86400 ) ; Negative Cache TTL +; +@ IN NS localhost. diff -urN bind-9.3.1.orig/conf/db.local bind-9.3.1/conf/db.local --- bind-9.3.1.orig/conf/db.local 1970-01-01 01:00:00.000000000 +0100 +++ bind-9.3.1/conf/db.local 2005-07-10 22:14:00.000000000 +0200 @@ -0,0 +1,13 @@ +; +; BIND data file for local loopback interface +; +$TTL 604800 +@ IN SOA localhost. root.localhost. ( + 1 ; Serial + 604800 ; Refresh + 86400 ; Retry + 2419200 ; Expire + 604800 ) ; Negative Cache TTL +; +@ IN NS localhost. +@ IN A 127.0.0.1 diff -urN bind-9.3.1.orig/conf/db.root bind-9.3.1/conf/db.root --- bind-9.3.1.orig/conf/db.root 1970-01-01 01:00:00.000000000 +0100 +++ bind-9.3.1/conf/db.root 2005-07-10 22:14:00.000000000 +0200 @@ -0,0 +1,45 @@ + +; <<>> DiG 9.2.3 <<>> ns . @a.root-servers.net. +;; global options: printcmd +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18944 +;; flags: qr aa rd; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 13 + +;; QUESTION SECTION: +;. IN NS + +;; ANSWER SECTION: +. 518400 IN NS A.ROOT-SERVERS.NET. +. 518400 IN NS B.ROOT-SERVERS.NET. +. 518400 IN NS C.ROOT-SERVERS.NET. +. 518400 IN NS D.ROOT-SERVERS.NET. +. 518400 IN NS E.ROOT-SERVERS.NET. +. 518400 IN NS F.ROOT-SERVERS.NET. +. 518400 IN NS G.ROOT-SERVERS.NET. +. 518400 IN NS H.ROOT-SERVERS.NET. +. 518400 IN NS I.ROOT-SERVERS.NET. +. 518400 IN NS J.ROOT-SERVERS.NET. +. 518400 IN NS K.ROOT-SERVERS.NET. +. 518400 IN NS L.ROOT-SERVERS.NET. +. 518400 IN NS M.ROOT-SERVERS.NET. + +;; ADDITIONAL SECTION: +A.ROOT-SERVERS.NET. 3600000 IN A 198.41.0.4 +B.ROOT-SERVERS.NET. 3600000 IN A 192.228.79.201 +C.ROOT-SERVERS.NET. 3600000 IN A 192.33.4.12 +D.ROOT-SERVERS.NET. 3600000 IN A 128.8.10.90 +E.ROOT-SERVERS.NET. 3600000 IN A 192.203.230.10 +F.ROOT-SERVERS.NET. 3600000 IN A 192.5.5.241 +G.ROOT-SERVERS.NET. 3600000 IN A 192.112.36.4 +H.ROOT-SERVERS.NET. 3600000 IN A 128.63.2.53 +I.ROOT-SERVERS.NET. 3600000 IN A 192.36.148.17 +J.ROOT-SERVERS.NET. 3600000 IN A 192.58.128.30 +K.ROOT-SERVERS.NET. 3600000 IN A 193.0.14.129 +L.ROOT-SERVERS.NET. 3600000 IN A 198.32.64.12 +M.ROOT-SERVERS.NET. 3600000 IN A 202.12.27.33 + +;; Query time: 81 msec +;; SERVER: 198.41.0.4#53(a.root-servers.net.) +;; WHEN: Sun Feb 1 11:27:14 2004 +;; MSG SIZE rcvd: 436 + diff -urN bind-9.3.1.orig/conf/named.conf bind-9.3.1/conf/named.conf --- bind-9.3.1.orig/conf/named.conf 1970-01-01 01:00:00.000000000 +0100 +++ bind-9.3.1/conf/named.conf 2005-07-10 22:33:46.000000000 +0200 @@ -0,0 +1,49 @@ +// This is the primary configuration file for the BIND DNS server named. +// +// If you are just adding zones, please do that in /etc/bind/named.conf.local + +include "/etc/bind/named.conf.options"; + +// prime the server with knowledge of the root servers +zone "." { + type hint; + file "/etc/bind/db.root"; +}; + +// be authoritative for the localhost forward and reverse zones, and for +// broadcast zones as per RFC 1912 + +zone "localhost" { + type master; + file "/etc/bind/db.local"; +}; + +zone "127.in-addr.arpa" { + type master; + file "/etc/bind/db.127"; +}; + +zone "0.in-addr.arpa" { + type master; + file "/etc/bind/db.0"; +}; + +zone "255.in-addr.arpa" { + type master; + file "/etc/bind/db.255"; +}; + +// zone "com" { type delegation-only; }; +// zone "net" { type delegation-only; }; + +// From the release notes: +// Because many of our users are uncomfortable receiving undelegated answers +// from root or top level domains, other than a few for whom that behaviour +// has been trusted and expected for quite some length of time, we have now +// introduced the "root-delegations-only" feature which applies delegation-only +// logic to all top level domains, and to the root domain. An exception list +// should be specified, including "MUSEUM" and "DE", and any other top level +// domains from whom undelegated responses are expected and trusted. +// root-delegation-only exclude { "DE"; "MUSEUM"; }; + +include "/etc/bind/named.conf.local"; diff -urN bind-9.3.1.orig/conf/named.conf.local bind-9.3.1/conf/named.conf.local --- bind-9.3.1.orig/conf/named.conf.local 1970-01-01 01:00:00.000000000 +0100 +++ bind-9.3.1/conf/named.conf.local 2005-07-10 22:14:06.000000000 +0200 @@ -0,0 +1,8 @@ +// +// Do any local configuration here +// + +// Consider adding the 1918 zones here, if they are not used in your +// organization +//include "/etc/bind/zones.rfc1918"; + diff -urN bind-9.3.1.orig/conf/named.conf.options bind-9.3.1/conf/named.conf.options --- bind-9.3.1.orig/conf/named.conf.options 1970-01-01 01:00:00.000000000 +0100 +++ bind-9.3.1/conf/named.conf.options 2005-07-10 22:14:06.000000000 +0200 @@ -0,0 +1,24 @@ +options { + directory "/var/cache/bind"; + + // If there is a firewall between you and nameservers you want + // to talk to, you might need to uncomment the query-source + // directive below. Previous versions of BIND always asked + // questions using port 53, but BIND 8.1 and later use an unprivileged + // port by default. + + // query-source address * port 53; + + // If your ISP provided one or more IP addresses for stable + // nameservers, you probably want to use them as forwarders. + // Uncomment the following block, and insert the addresses replacing + // the all-0's placeholder. + + // forwarders { + // 0.0.0.0; + // }; + + auth-nxdomain no; # conform to RFC1035 + +}; + diff -urN bind-9.3.1.orig/conf/zones.rfc1918 bind-9.3.1/conf/zones.rfc1918 --- bind-9.3.1.orig/conf/zones.rfc1918 1970-01-01 01:00:00.000000000 +0100 +++ bind-9.3.1/conf/zones.rfc1918 2005-07-10 22:14:10.000000000 +0200 @@ -0,0 +1,20 @@ +zone "10.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; + +zone "16.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; +zone "17.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; +zone "18.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; +zone "19.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; +zone "20.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; +zone "21.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; +zone "22.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; +zone "23.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; +zone "24.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; +zone "25.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; +zone "26.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; +zone "27.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; +zone "28.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; +zone "29.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; +zone "30.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; +zone "31.172.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; + +zone "168.192.in-addr.arpa" { type master; file "/etc/bind/db.empty"; }; diff -urN bind-9.3.1.orig/init.d bind-9.3.1/init.d --- bind-9.3.1.orig/init.d 1970-01-01 01:00:00.000000000 +0100 +++ bind-9.3.1/init.d 2005-07-10 23:09:58.000000000 +0200 @@ -0,0 +1,70 @@ +#!/bin/sh + +PATH=/sbin:/bin:/usr/sbin:/usr/bin + +# for a chrooted server: "-u bind -t /var/lib/named" +# Don't modify this line, change or create /etc/default/bind9. +OPTIONS="" + +test -f /etc/default/bind9 && . /etc/default/bind9 + +test -x /usr/sbin/rndc || exit 0 + +case "$1" in + start) + echo -n "Starting domain name service: named" + + modprobe capability >/dev/null 2>&1 || true + if [ ! -f /etc/bind/rndc.key ]; then + /usr/sbin/rndc-confgen -a -b 512 -r /dev/urandom + chmod 0640 /etc/bind/rndc.key + fi + if [ -f /var/run/named/named.pid ]; then + ps `cat /var/run/named/named.pid` > /dev/null && exit 1 + fi + + # dirs under /var/run can go away on reboots. + mkdir -p /var/run/named + mkdir -p /var/cache/bind + chmod 775 /var/run/named + chown root:bind /var/run/named >/dev/null 2>&1 || true + + if [ ! -x /usr/sbin/named ]; then + echo "named binary missing - not starting" + exit 1 + fi + if start-stop-daemon --start --quiet --exec /usr/sbin/named \ + --pidfile /var/run/named/named.pid -- $OPTIONS; then + if [ -x /sbin/resolvconf ] ; then + echo "nameserver 127.0.0.1" | /sbin/resolvconf -a lo + fi + fi + echo "." + ;; + + stop) + echo -n "Stopping domain name service: named" + if [ -x /sbin/resolvconf ]; then + /sbin/resolvconf -d lo + fi + /usr/sbin/rndc stop >/dev/null 2>&1 + echo "." + ;; + + reload) + /usr/sbin/rndc reload + ;; + + restart|force-reload) + $0 stop + sleep 2 + $0 start + ;; + + *) + echo "Usage: /etc/init.d/bind {start|stop|reload|restart|force-reload}" >&2 + exit 1 + ;; +esac + +exit 0 ./bind90000664000175000017500000000006312511411356012363 0ustar nielsenrnielsenr# startup options for the server OPTIONS="-u bind" ./bind9_9_5-CVE-2014-8500.patch0000664000175000017500000010174412511411356015536 0ustar nielsenrnielsenrFrom 603a0e2637b35a2da820bc807f69bcf09c682dce Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Mon, 17 Nov 2014 23:49:07 -0800 Subject: [PATCH] [v9_9] limit recursion depth and iterative queries 4006. [security] A flaw in delegation handling could be exploited to put named into an infinite loop. This has been addressed by placing limits on the number of levels of recursion named will allow (default 7), and the number of iterative queries that it will send (default 50) before terminating a recursive query (CVE-2014-8500). The recursion depth limit is configured via the "max-recursion-depth" option. [RT #35780] Upstream-Status: Backport Signed-off-by: Sona Sarmadi --- bin/named/config.c | 3 +- bin/named/include/named/query.h | 2 - bin/named/query.c | 7 ++- bin/named/server.c | 5 ++ bin/tests/system/many/clean.sh | 7 +++ bin/tests/system/many/ns1/named.conf | 33 +++++++++++++ bin/tests/system/many/ns2/named.conf | 30 ++++++++++++ bin/tests/system/many/ns3/named.conf | 32 +++++++++++++ bin/tests/system/many/ns4/named.conf | 30 ++++++++++++ bin/tests/system/many/ns5/hints.db | 2 + bin/tests/system/many/ns5/named.conf | 29 ++++++++++++ bin/tests/system/many/setup.sh | 75 ++++++++++++++++++++++++++++++ bin/tests/system/many/tests.sh | 48 +++++++++++++++++++ doc/arm/Bv9ARM-book.xml | 12 +++++ lib/dns/adb.c | 58 ++++++++++++++++------- lib/dns/include/dns/adb.h | 8 ++++ lib/dns/include/dns/resolver.h | 25 ++++++++++ lib/dns/resolver.c | 90 ++++++++++++++++++++++++++++++------ lib/isccfg/namedconf.c | 1 + 20 files changed, 471 insertions(+), 37 deletions(-) create mode 100644 bin/tests/system/many/clean.sh create mode 100644 bin/tests/system/many/ns1/named.conf create mode 100644 bin/tests/system/many/ns2/named.conf create mode 100644 bin/tests/system/many/ns3/named.conf create mode 100644 bin/tests/system/many/ns4/named.conf create mode 100644 bin/tests/system/many/ns5/hints.db create mode 100644 bin/tests/system/many/ns5/named.conf create mode 100644 bin/tests/system/many/setup.sh create mode 100644 bin/tests/system/many/tests.sh diff --git a/bin/named/config.c b/bin/named/config.c index 2782720..5ee8c4e 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -15,8 +15,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: config.c,v 1.123 2012/01/06 23:46:41 tbox Exp $ */ - /*! \file */ #include @@ -160,6 +158,7 @@ options {\n\ dnssec-accept-expired no;\n\ clients-per-query 10;\n\ max-clients-per-query 100;\n\ + max-recursion-depth 7;\n\ zero-no-soa-ttl-cache no;\n\ nsec3-test-zone no;\n\ allow-new-zones no;\n\ diff --git a/bin/named/include/named/query.h b/bin/named/include/named/query.h index 3beabb8..b5e3900 100644 --- a/bin/named/include/named/query.h +++ b/bin/named/include/named/query.h @@ -15,8 +15,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: query.h,v 1.45 2011/01/13 04:59:24 tbox Exp $ */ - #ifndef NAMED_QUERY_H #define NAMED_QUERY_H 1 diff --git a/bin/named/query.c b/bin/named/query.c index 982f76d..47bfc6a 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -3877,12 +3877,11 @@ query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname, peeraddr = &client->peeraddr; else peeraddr = NULL; - result = dns_resolver_createfetch2(client->view->resolver, + result = dns_resolver_createfetch3(client->view->resolver, qname, qtype, qdomain, nameservers, NULL, peeraddr, client->message->id, - client->query.fetchoptions, - client->task, - query_resume, client, + client->query.fetchoptions, 0, + client->task, query_resume, client, rdataset, sigrdataset, &client->query.fetch); diff --git a/bin/named/server.c b/bin/named/server.c index ac015a4..0559977 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -3161,6 +3161,11 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, cfg_obj_asuint32(obj), max_clients_per_query); + obj = NULL; + result = ns_config_get(maps, "max-recursion-depth", &obj); + INSIST(result == ISC_R_SUCCESS); + dns_resolver_setmaxdepth(view->resolver, cfg_obj_asuint32(obj)); + #ifdef ALLOW_FILTER_AAAA_ON_V4 obj = NULL; result = ns_config_get(maps, "filter-aaaa-on-v4", &obj); diff --git a/bin/tests/system/many/clean.sh b/bin/tests/system/many/clean.sh new file mode 100644 index 0000000..119b1f5 --- /dev/null +++ b/bin/tests/system/many/clean.sh @@ -0,0 +1,7 @@ +rm -f ns1/[1-9]*example.tld?.db +rm -f ns2/[1-9]*example.tld?.db +rm -f ns1/zones.conf +rm -f ns2/zones.conf +rm -f */root.db +rm -f ns3/tld1.db +rm -f ns4/tld2.db diff --git a/bin/tests/system/many/ns1/named.conf b/bin/tests/system/many/ns1/named.conf new file mode 100644 index 0000000..abc9dca --- /dev/null +++ b/bin/tests/system/many/ns1/named.conf @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +controls { /* empty */ }; + +options { + query-source address 10.53.0.1; + notify-source 10.53.0.1; + transfer-source 10.53.0.1; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.1; }; + listen-on-v6 { none; }; + recursion no; +}; + +include "zones.conf"; + +// zone "tld1" { type master; file "tld1.db"; }; +// zone "tld2" { type master; file "tld2.db"; }; diff --git a/bin/tests/system/many/ns2/named.conf b/bin/tests/system/many/ns2/named.conf new file mode 100644 index 0000000..16266e2 --- /dev/null +++ b/bin/tests/system/many/ns2/named.conf @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +controls { /* empty */ }; + +options { + query-source address 10.53.0.2; + notify-source 10.53.0.2; + transfer-source 10.53.0.2; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.2; }; + listen-on-v6 { none; }; + recursion no; +}; + +include "zones.conf"; diff --git a/bin/tests/system/many/ns3/named.conf b/bin/tests/system/many/ns3/named.conf new file mode 100644 index 0000000..b950afe --- /dev/null +++ b/bin/tests/system/many/ns3/named.conf @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +controls { /* empty */ }; + +options { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { none; }; + recursion no; +}; + +zone "." { type master; file "root.db"; }; + +zone "tld1" { type master; file "tld1.db"; }; diff --git a/bin/tests/system/many/ns4/named.conf b/bin/tests/system/many/ns4/named.conf new file mode 100644 index 0000000..ca9aa6a --- /dev/null +++ b/bin/tests/system/many/ns4/named.conf @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +controls { /* empty */ }; + +options { + query-source address 10.53.0.4; + notify-source 10.53.0.4; + transfer-source 10.53.0.4; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.4; }; + listen-on-v6 { none; }; + recursion no; +}; + +zone "tld2" { type master; file "tld2.db"; }; diff --git a/bin/tests/system/many/ns5/hints.db b/bin/tests/system/many/ns5/hints.db new file mode 100644 index 0000000..c05809b --- /dev/null +++ b/bin/tests/system/many/ns5/hints.db @@ -0,0 +1,2 @@ +. 60 in ns ns.nil. +ns.nil. 60 in A 10.53.0.3 diff --git a/bin/tests/system/many/ns5/named.conf b/bin/tests/system/many/ns5/named.conf new file mode 100644 index 0000000..fce7d59 --- /dev/null +++ b/bin/tests/system/many/ns5/named.conf @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +controls { /* empty */ }; + +options { + query-source address 10.53.0.5; + notify-source 10.53.0.5; + transfer-source 10.53.0.5; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.5; }; + listen-on-v6 { none; }; +}; + +zone "." { type hint; file "hints.db"; }; diff --git a/bin/tests/system/many/setup.sh b/bin/tests/system/many/setup.sh new file mode 100644 index 0000000..80695b5 --- /dev/null +++ b/bin/tests/system/many/setup.sh @@ -0,0 +1,75 @@ +i=1 + +cat > ns3/root.db << EOF +. 60 in soa ns.nil. hostmaster.ns.nil. 1 0 0 0 0 +. 60 in ns ns.nil. +ns.nil. 60 in a 10.53.0.3 +tld1. 60 in ns ns.tld1. +ns.tld1. 60 in a 10.53.0.3 +tld2. 60 in ns ns.tld2. +ns.tld2. 60 in a 10.53.0.4 +EOF + +cat > ns3/tld1.db << EOF +tld1. 60 in soa ns.tld1. hostmaster.ns.tld1. 1 0 0 0 0 +tld1. 60 in ns ns.tld1. +ns.tld1. 60 in a 10.53.0.1 +EOF + +cat > ns4/tld2.db << EOF +tld2. 60 in soa ns.tld2. hostmaster.ns.tld4. 1 0 0 0 0 +tld2. 60 in ns ns.tld2. +ns.tld2. 60 in a 10.53.0.1 +EOF + +: > ns1/zones.conf +: > ns2/zones.conf + +while [ $i -lt 1000 ] +do +j=`expr $i + 1` +s=`expr $j % 2 + 1` +n=`expr $i % 2 + 1` +t=`expr $s + 2` + +# i=1 j=2 s=1 n=2 +# i=2 j=3 s=1 n=2 +# i=3 j=4 s=1 n=2 + +cat > ns1/${i}example.tld${s}.db << EOF +${i}example.tld${s}. 60 in soa ns.${j}example.tld${n}. hostmaster 1 0 0 0 0 +${i}example.tld${s}. 60 in ns ns.${j}example.tld${n}. +ns.${i}example.tld${s}. 60 in a 10.53.0.1 +EOF + +cat >> ns1/zones.conf << EOF +zone "${i}example.tld${s}" { type master; file "${i}example.tld${s}.db"; }; +EOF + +cat >> ns${t}/tld${s}.db << EOF +${i}example.tld${s}. 60 in ns ns.${j}example.tld${n}. +EOF + +i=$j + +done + +j=`expr $i + 1` +s=`expr $j % 2 + 1` +n=`expr $s % 2 + 1` +t=`expr $s + 2` + +cat > ns1/${i}example.tld${s}.db << EOF +${i}example.tld${s}. 60 in soa ns.${i}example.tld${s}. hostmaster 1 0 0 0 0 +${i}example.tld${s}. 60 in ns ns.${i}example.tld${s}. +ns.${i}example.tld${s}. 60 in a 10.53.0.1 +EOF + +cat >> ns1/zones.conf << EOF +zone "${i}example.tld${s}" { type master; file "${i}example.tld${s}.db"; }; +EOF + +cat >> ns${t}/tld${s}.db << EOF +${i}example.tld${s}. 60 in ns ns.${i}example.tld${s}. +ns.${i}example.tld${s}. 60 in a 10.53.0.1 +EOF diff --git a/bin/tests/system/many/tests.sh b/bin/tests/system/many/tests.sh new file mode 100644 index 0000000..37964e2 --- /dev/null +++ b/bin/tests/system/many/tests.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# +# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +SYSTEMTESTTOP=.. +. $SYSTEMTESTTOP/conf.sh + +status=0 +n=0 + +n=`expr $n + 1` +echo "I: attempt lookup 1example.tld2 soa ($n)" +ret=0 +$DIG +tcp 1example.tld1 soa @10.53.0.5 -p 5300 > dig.out.test$n +grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: attempt lookup 992example.tld2 soa ($n)" +ret=0 +$DIG +tcp 992example.tld2 soa @10.53.0.5 -p 5300 > dig.out.test$n +grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo "I: attempt lookup 993example.tld1 soa ($n)" +ret=0 +$DIG +tcp 993example.tld1 soa @10.53.0.5 -p 5300 > dig.out.test$n +grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:exit status: $status" +exit $status diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 9f7bd38..fff4249 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -4861,6 +4861,7 @@ badresp:1,adberr:0,findfail:0,valfail:0] max-acache-size size_spec ; clients-per-query number ; max-clients-per-query number ; + max-recursion-depth number ; masterfile-format (text|raw) ; empty-server name ; empty-contact name ; @@ -8680,6 +8681,17 @@ avoid-v6-udp-ports { 40000; range 50000 60000; }; + + max-recursion-depth + + + Sets the maximum number of levels of recursion + permitted at any one time while resolving a name. + The default is 7. + + + + notify-delay diff --git a/lib/dns/adb.c b/lib/dns/adb.c index 2ccb51e..fe9b3f7 100644 --- a/lib/dns/adb.c +++ b/lib/dns/adb.c @@ -199,6 +199,7 @@ struct dns_adbfetch { unsigned int magic; dns_fetch_t *fetch; dns_rdataset_t rdataset; + unsigned int depth; }; /*% @@ -300,7 +301,7 @@ static inline void violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *); static isc_boolean_t clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *); static void clean_target(dns_adb_t *, dns_name_t *); static void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t, - unsigned int); + isc_uint32_t, unsigned int); static isc_boolean_t check_expire_namehooks(dns_adbname_t *, isc_stdtime_t); static isc_boolean_t check_expire_entry(dns_adb_t *, dns_adbentry_t **, isc_stdtime_t); @@ -308,7 +309,7 @@ static void cancel_fetches_at_name(dns_adbname_t *); static isc_result_t dbfind_name(dns_adbname_t *, isc_stdtime_t, dns_rdatatype_t); static isc_result_t fetch_name(dns_adbname_t *, isc_boolean_t, - dns_rdatatype_t); + unsigned int, dns_rdatatype_t); static inline void check_exit(dns_adb_t *); static void destroy(dns_adb_t *); static isc_boolean_t shutdown_names(dns_adb_t *); @@ -984,7 +985,7 @@ kill_name(dns_adbname_t **n, isc_eventtype_t ev) { * Clean up the name's various lists. These two are destructive * in that they will always empty the list. */ - clean_finds_at_name(name, ev, DNS_ADBFIND_ADDRESSMASK); + clean_finds_at_name(name, ev, 0, DNS_ADBFIND_ADDRESSMASK); result4 = clean_namehooks(adb, &name->v4); result6 = clean_namehooks(adb, &name->v6); clean_target(adb, &name->target); @@ -1409,7 +1410,7 @@ event_free(isc_event_t *event) { */ static void clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype, - unsigned int addrs) + isc_uint32_t qtotal, unsigned int addrs) { isc_event_t *ev; isc_task_t *task; @@ -1469,6 +1470,7 @@ clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype, ev->ev_sender = find; find->result_v4 = find_err_map[name->fetch_err]; find->result_v6 = find_err_map[name->fetch6_err]; + find->qtotal += qtotal; ev->ev_type = evtype; ev->ev_destroy = event_free; ev->ev_destroy_arg = find; @@ -1827,6 +1829,7 @@ new_adbfind(dns_adb_t *adb) { h->flags = 0; h->result_v4 = ISC_R_UNEXPECTED; h->result_v6 = ISC_R_UNEXPECTED; + h->qtotal = 0; ISC_LINK_INIT(h, publink); ISC_LINK_INIT(h, plink); ISC_LIST_INIT(h->list); @@ -2799,6 +2802,19 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, isc_stdtime_t now, dns_name_t *target, in_port_t port, dns_adbfind_t **findp) { + return (dns_adb_createfind2(adb, task, action, arg, name, + qname, qtype, options, now, + target, port, 0, findp)); +} + +isc_result_t +dns_adb_createfind2(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, + void *arg, dns_name_t *name, dns_name_t *qname, + dns_rdatatype_t qtype, unsigned int options, + isc_stdtime_t now, dns_name_t *target, + in_port_t port, unsigned int depth, + dns_adbfind_t **findp) +{ dns_adbfind_t *find; dns_adbname_t *adbname; int bucket; @@ -3029,7 +3045,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, * Start V4. */ if (WANT_INET(wanted_fetches) && - fetch_name(adbname, start_at_zone, + fetch_name(adbname, start_at_zone, depth, dns_rdatatype_a) == ISC_R_SUCCESS) { DP(DEF_LEVEL, "dns_adb_createfind: started A fetch for name %p", @@ -3040,7 +3056,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, * Start V6. */ if (WANT_INET6(wanted_fetches) && - fetch_name(adbname, start_at_zone, + fetch_name(adbname, start_at_zone, depth, dns_rdatatype_aaaa) == ISC_R_SUCCESS) { DP(DEF_LEVEL, "dns_adb_createfind: " @@ -3656,6 +3672,7 @@ fetch_callback(isc_task_t *task, isc_event_t *ev) { isc_result_t result; unsigned int address_type; isc_boolean_t want_check_exit = ISC_FALSE; + isc_uint32_t qtotal = 0; UNUSED(task); @@ -3666,6 +3683,8 @@ fetch_callback(isc_task_t *task, isc_event_t *ev) { adb = name->adb; INSIST(DNS_ADB_VALID(adb)); + qtotal = dev->qtotal; + bucket = name->lock_bucket; LOCK(&adb->namelocks[bucket]); @@ -3783,6 +3802,12 @@ fetch_callback(isc_task_t *task, isc_event_t *ev) { DP(DEF_LEVEL, "adb: fetch of '%s' %s failed: %s", buf, address_type == DNS_ADBFIND_INET ? "A" : "AAAA", dns_result_totext(dev->result)); + /* + * Don't record a failure unless this is the initial + * fetch of a chain. + */ + if (fetch->depth > 1) + goto out; /* XXXMLG Don't pound on bad servers. */ if (address_type == DNS_ADBFIND_INET) { name->expire_v4 = ISC_MIN(name->expire_v4, now + 300); @@ -3814,15 +3839,14 @@ fetch_callback(isc_task_t *task, isc_event_t *ev) { free_adbfetch(adb, &fetch); isc_event_free(&ev); - clean_finds_at_name(name, ev_status, address_type); + clean_finds_at_name(name, ev_status, qtotal, address_type); UNLOCK(&adb->namelocks[bucket]); } static isc_result_t -fetch_name(dns_adbname_t *adbname, - isc_boolean_t start_at_zone, - dns_rdatatype_t type) +fetch_name(dns_adbname_t *adbname, isc_boolean_t start_at_zone, + unsigned int depth, dns_rdatatype_t type) { isc_result_t result; dns_adbfetch_t *fetch = NULL; @@ -3867,12 +3891,14 @@ fetch_name(dns_adbname_t *adbname, result = ISC_R_NOMEMORY; goto cleanup; } - - result = dns_resolver_createfetch(adb->view->resolver, &adbname->name, - type, name, nameservers, NULL, - options, adb->task, fetch_callback, - adbname, &fetch->rdataset, NULL, - &fetch->fetch); + fetch->depth = depth; + + result = dns_resolver_createfetch3(adb->view->resolver, &adbname->name, + type, name, nameservers, NULL, + NULL, 0, options, depth, adb->task, + fetch_callback, adbname, + &fetch->rdataset, NULL, + &fetch->fetch); if (result != ISC_R_SUCCESS) goto cleanup; diff --git a/lib/dns/include/dns/adb.h b/lib/dns/include/dns/adb.h index 35350ff..7501f01 100644 --- a/lib/dns/include/dns/adb.h +++ b/lib/dns/include/dns/adb.h @@ -118,6 +118,8 @@ struct dns_adbfind { isc_result_t result_v6; /*%< RO: v6 result */ ISC_LINK(dns_adbfind_t) publink; /*%< RW: client use */ + isc_uint32_t qtotal; + /* Private */ isc_mutex_t lock; /* locks all below */ in_port_t port; @@ -334,6 +336,12 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, dns_rdatatype_t qtype, unsigned int options, isc_stdtime_t now, dns_name_t *target, in_port_t port, dns_adbfind_t **find); +isc_result_t +dns_adb_createfind2(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, + void *arg, dns_name_t *name, dns_name_t *qname, + dns_rdatatype_t qtype, unsigned int options, + isc_stdtime_t now, dns_name_t *target, in_port_t port, + unsigned int depth, dns_adbfind_t **find); /*%< * Main interface for clients. The adb will look up the name given in * "name" and will build up a list of found addresses, and perhaps start diff --git a/lib/dns/include/dns/resolver.h b/lib/dns/include/dns/resolver.h index 4e20eb6..c256049 100644 --- a/lib/dns/include/dns/resolver.h +++ b/lib/dns/include/dns/resolver.h @@ -82,6 +82,7 @@ typedef struct dns_fetchevent { isc_sockaddr_t * client; dns_messageid_t id; isc_result_t vresult; + isc_uint32_t qtotal; } dns_fetchevent_t; /* @@ -275,6 +276,18 @@ dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp); +isc_result_t +dns_resolver_createfetch3(dns_resolver_t *res, dns_name_t *name, + dns_rdatatype_t type, + dns_name_t *domain, dns_rdataset_t *nameservers, + dns_forwarders_t *forwarders, + isc_sockaddr_t *client, isc_uint16_t id, + unsigned int options, unsigned int depth, + isc_task_t *task, + isc_taskaction_t action, void *arg, + dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset, + dns_fetch_t **fetchp); /*%< * Recurse to answer a question. * @@ -576,6 +589,18 @@ dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp); * \li resolver to be valid. */ +void +dns_resolver_setmaxdepth(dns_resolver_t *resolver, unsigned int maxdepth); +unsigned int +dns_resolver_getmaxdepth(dns_resolver_t *resolver); +/*% + * Get and set how many NS indirections will be followed when looking for + * nameserver addresses. + * + * Requires: + * \li resolver to be valid. + */ + ISC_LANG_ENDDECLS #endif /* DNS_RESOLVER_H */ diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index e517dad..6a635b2 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -131,6 +131,16 @@ #define MAXIMUM_QUERY_TIMEOUT 30 /* The maximum time in seconds for the whole query to live. */ #endif +/* The default maximum number of recursions to follow before giving up. */ +#ifndef DEFAULT_RECURSION_DEPTH +#define DEFAULT_RECURSION_DEPTH 7 +#endif + +/* The default maximum number of iterative queries to allow before giving up. */ +#ifndef DEFAULT_MAX_QUERIES +#define DEFAULT_MAX_QUERIES 50 +#endif + /*% * Maximum EDNS0 input packet size. */ @@ -297,6 +307,7 @@ struct fetchctx { isc_uint64_t duration; isc_boolean_t logged; unsigned int querysent; + unsigned int totalqueries; unsigned int referrals; unsigned int lamecount; unsigned int neterr; @@ -307,6 +318,7 @@ struct fetchctx { isc_boolean_t timeout; dns_adbaddrinfo_t *addrinfo; isc_sockaddr_t *client; + unsigned int depth; }; #define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!') @@ -419,6 +431,7 @@ struct dns_resolver { isc_timer_t * spillattimer; isc_boolean_t zero_no_soa_ttl; unsigned int query_timeout; + unsigned int maxdepth; /* Locked by lock. */ unsigned int references; @@ -1097,6 +1110,7 @@ fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) { event->result == DNS_R_NCACHENXRRSET); } + event->qtotal = fctx->totalqueries; isc_task_sendanddetach(&task, ISC_EVENT_PTR(&event)); count++; } @@ -1537,7 +1551,9 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, if (result != ISC_R_SUCCESS) goto cleanup_dispatch; } + fctx->querysent++; + fctx->totalqueries++; ISC_LIST_APPEND(fctx->queries, query, link); query->fctx->nqueries++; @@ -2194,9 +2210,10 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) { */ INSIST(!SHUTTINGDOWN(fctx)); fctx->attributes &= ~FCTX_ATTR_ADDRWAIT; - if (event->ev_type == DNS_EVENT_ADBMOREADDRESSES) + if (event->ev_type == DNS_EVENT_ADBMOREADDRESSES) { want_try = ISC_TRUE; - else { + fctx->totalqueries += find->qtotal; + } else { fctx->findfail++; if (fctx->pending == 0) { /* @@ -2479,12 +2496,13 @@ findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port, * See what we know about this address. */ find = NULL; - result = dns_adb_createfind(fctx->adb, - res->buckets[fctx->bucketnum].task, - fctx_finddone, fctx, name, - &fctx->name, fctx->type, - options, now, NULL, - res->view->dstport, &find); + result = dns_adb_createfind2(fctx->adb, + res->buckets[fctx->bucketnum].task, + fctx_finddone, fctx, name, + &fctx->name, fctx->type, + options, now, NULL, + res->view->dstport, + fctx->depth + 1, &find); if (result != ISC_R_SUCCESS) { if (result == DNS_R_ALIAS) { /* @@ -2592,6 +2610,11 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) { res = fctx->res; + if (fctx->depth > res->maxdepth) { + FCTXTRACE("too much NS indirection"); + return (DNS_R_SERVFAIL); + } + /* * Forwarders. */ @@ -3030,6 +3053,9 @@ fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) { REQUIRE(!ADDRWAIT(fctx)); + if (fctx->totalqueries > DEFAULT_MAX_QUERIES) + fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); + addrinfo = fctx_nextaddress(fctx); if (addrinfo == NULL) { /* @@ -3388,6 +3414,7 @@ fctx_start(isc_task_t *task, isc_event_t *event) { * Normal fctx startup. */ fctx->state = fetchstate_active; + fctx->totalqueries = 0; /* * Reset the control event for later use in shutting down * the fctx. @@ -3457,6 +3484,7 @@ fctx_join(fetchctx_t *fctx, isc_task_t *task, isc_sockaddr_t *client, event->fetch = fetch; event->client = client; event->id = id; + event->qtotal = 0; dns_fixedname_init(&event->foundname); /* @@ -3493,7 +3521,8 @@ log_ns_ttl(fetchctx_t *fctx, const char *where) { static isc_result_t fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, dns_name_t *domain, dns_rdataset_t *nameservers, - unsigned int options, unsigned int bucketnum, fetchctx_t **fctxp) + unsigned int options, unsigned int bucketnum, unsigned int depth, + fetchctx_t **fctxp) { fetchctx_t *fctx; isc_result_t result; @@ -3545,6 +3574,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, fctx->state = fetchstate_init; fctx->want_shutdown = ISC_FALSE; fctx->cloned = ISC_FALSE; + fctx->depth = depth; ISC_LIST_INIT(fctx->queries); ISC_LIST_INIT(fctx->finds); ISC_LIST_INIT(fctx->altfinds); @@ -3563,6 +3593,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, fctx->pending = 0; fctx->restarts = 0; fctx->querysent = 0; + fctx->totalqueries = 0; fctx->referrals = 0; TIME_NOW(&fctx->start); fctx->timeouts = 0; @@ -7781,6 +7812,7 @@ dns_resolver_create(dns_view_t *view, res->spillattimer = NULL; res->zero_no_soa_ttl = ISC_FALSE; res->query_timeout = DEFAULT_QUERY_TIMEOUT; + res->maxdepth = DEFAULT_RECURSION_DEPTH; res->nbuckets = ntasks; res->activebuckets = ntasks; res->buckets = isc_mem_get(view->mctx, @@ -8219,9 +8251,9 @@ dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name, dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp) { - return (dns_resolver_createfetch2(res, name, type, domain, + return (dns_resolver_createfetch3(res, name, type, domain, nameservers, forwarders, NULL, 0, - options, task, action, arg, + options, 0, task, action, arg, rdataset, sigrdataset, fetchp)); } @@ -8237,6 +8269,25 @@ dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name, dns_rdataset_t *sigrdataset, dns_fetch_t **fetchp) { + return (dns_resolver_createfetch3(res, name, type, domain, + nameservers, forwarders, client, id, + options, 0, task, action, arg, + rdataset, sigrdataset, fetchp)); +} + +isc_result_t +dns_resolver_createfetch3(dns_resolver_t *res, dns_name_t *name, + dns_rdatatype_t type, + dns_name_t *domain, dns_rdataset_t *nameservers, + dns_forwarders_t *forwarders, + isc_sockaddr_t *client, dns_messageid_t id, + unsigned int options, unsigned int depth, + isc_task_t *task, + isc_taskaction_t action, void *arg, + dns_rdataset_t *rdataset, + dns_rdataset_t *sigrdataset, + dns_fetch_t **fetchp) +{ dns_fetch_t *fetch; fetchctx_t *fctx = NULL; isc_result_t result = ISC_R_SUCCESS; @@ -8325,11 +8376,12 @@ dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name, if (fctx == NULL) { result = fctx_create(res, name, type, domain, nameservers, - options, bucketnum, &fctx); + options, bucketnum, depth, &fctx); if (result != ISC_R_SUCCESS) goto unlock; new_fctx = ISC_TRUE; - } + } else if (fctx->depth > depth) + fctx->depth = depth; result = fctx_join(fctx, task, client, id, action, arg, rdataset, sigrdataset, fetch); @@ -9101,3 +9153,15 @@ dns_resolver_settimeout(dns_resolver_t *resolver, unsigned int seconds) { resolver->query_timeout = seconds; } + +void +dns_resolver_setmaxdepth(dns_resolver_t *resolver, unsigned int maxdepth) { + REQUIRE(VALID_RESOLVER(resolver)); + resolver->maxdepth = maxdepth; +} + +unsigned int +dns_resolver_getmaxdepth(dns_resolver_t *resolver) { + REQUIRE(VALID_RESOLVER(resolver)); + return (resolver->maxdepth); +} diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index bfd4bab..5f8b037 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1393,6 +1393,7 @@ view_clauses[] = { { "max-cache-ttl", &cfg_type_uint32, 0 }, { "max-clients-per-query", &cfg_type_uint32, 0 }, { "max-ncache-ttl", &cfg_type_uint32, 0 }, + { "max-recursion-depth", &cfg_type_uint32, 0 }, { "max-udp-size", &cfg_type_uint32, 0 }, { "min-roots", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP }, { "minimal-responses", &cfg_type_boolean, 0 }, -- 1.9.1 ./mips1-not-support-opcode.diff0000664000175000017500000000462012511411356017100 0ustar nielsenrnielsenrbind: port a patch to fix a build failure mips1 does not support ll and sc instructions, and lead to below error, now we port a patch from debian to fix it [http://security.debian.org/debian-security/pool/updates/main/b/bind9/bind9_9.8.4.dfsg.P1-6+nmu2+deb7u1.diff.gz] | {standard input}: Assembler messages: | {standard input}:47: Error: Opcode not supported on this processor: mips1 (mips1) `ll $3,0($6)' | {standard input}:50: Error: Opcode not supported on this processor: mips1 (mips1) `sc $3,0($6)' Upstream-Status: Pending Signed-off-by: Roy Li --- bind9-9.8.4.dfsg.P1.orig/lib/isc/mips/include/isc/atomic.h +++ bind9-9.8.4.dfsg.P1/lib/isc/mips/include/isc/atomic.h @@ -31,18 +31,20 @@ isc_atomic_xadd(isc_int32_t *p, int val) { isc_int32_t orig; - /* add is a cheat, since MIPS has no mov instruction */ - __asm__ volatile ( - "1:" - "ll $3, %1\n" - "add %0, $0, $3\n" - "add $3, $3, %2\n" - "sc $3, %1\n" - "beq $3, 0, 1b" - : "=&r"(orig) - : "m"(*p), "r"(val) - : "memory", "$3" - ); + __asm__ __volatile__ ( + " .set push \n" + " .set mips2 \n" + " .set noreorder \n" + " .set noat \n" + "1: ll $1, %1 \n" + " addu %0, $1, %2 \n" + " sc %0, %1 \n" + " beqz %0, 1b \n" + " move %0, $1 \n" + " .set pop \n" + : "=&r" (orig), "+R" (*p) + : "r" (val) + : "memory"); return (orig); } @@ -52,16 +54,7 @@ */ static inline void isc_atomic_store(isc_int32_t *p, isc_int32_t val) { - __asm__ volatile ( - "1:" - "ll $3, %0\n" - "add $3, $0, %1\n" - "sc $3, %0\n" - "beq $3, 0, 1b" - : - : "m"(*p), "r"(val) - : "memory", "$3" - ); + *p = val; } /* @@ -72,20 +65,23 @@ static inline isc_int32_t isc_atomic_cmpxchg(isc_int32_t *p, int cmpval, int val) { isc_int32_t orig; + isc_int32_t tmp; - __asm__ volatile( - "1:" - "ll $3, %1\n" - "add %0, $0, $3\n" - "bne $3, %2, 2f\n" - "add $3, $0, %3\n" - "sc $3, %1\n" - "beq $3, 0, 1b\n" - "2:" - : "=&r"(orig) - : "m"(*p), "r"(cmpval), "r"(val) - : "memory", "$3" - ); + __asm__ __volatile__ ( + " .set push \n" + " .set mips2 \n" + " .set noreorder \n" + " .set noat \n" + "1: ll $1, %1 \n" + " bne $1, %3, 2f \n" + " move %2, %4 \n" + " sc %2, %1 \n" + " beqz %2, 1b \n" + "2: move %0, $1 \n" + " .set pop \n" + : "=&r"(orig), "+R" (*p), "=r" (tmp) + : "r"(cmpval), "r"(val) + : "memory"); return (orig); } ./cross-build-fix.patch0000664000175000017500000000122212511411356015464 0ustar nielsenrnielsenrUpstream-Status: Inappropriate [configuration] 11/30/2010 gen.c should be build by ${BUILD_CC} Signed-off-by: Qing He diff --git a/lib/export/dns/Makefile.in b/lib/export/dns/Makefile.in index aeadf57..d3fae74 100644 --- a/lib/export/dns/Makefile.in +++ b/lib/export/dns/Makefile.in @@ -166,7 +166,8 @@ code.h: gen ./gen -s ${srcdir} > code.h gen: ${srcdir}/gen.c - ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ ${srcdir}/gen.c ${LIBS} + ${BUILD_CC} ${BUILD_CFLAGS} -I${top_srcdir}/lib/isc/include \ + ${BUILD_CPPFLAGS} ${BUILD_LDFLAGS} -o $@ ${srcdir}/gen.c ${BUILD_LIBS} #We don't need rbtdb64 for this library #rbtdb64.@O@: rbtdb.c ./generate-rndc-key.sh0000664000175000017500000000026712511411356015301 0ustar nielsenrnielsenr#!/bin/sh if [ ! -s /etc/bind/rndc.key ]; then echo -n "Generating /etc/bind/rndc.key:" /usr/sbin/rndc-confgen -a -b 512 -r /dev/urandom chmod 0640 /etc/bind/rndc.key fi ./named.service0000664000175000017500000000106412511411356014103 0ustar nielsenrnielsenr[Unit] Description=Berkeley Internet Name Domain (DNS) Wants=nss-lookup.target Before=nss-lookup.target After=network.target [Service] Type=forking EnvironmentFile=-/etc/default/bind9 PIDFile=/run/named/named.pid ExecStartPre=@SBINDIR@/generate-rndc-key.sh ExecStart=@SBINDIR@/named $OPTIONS ExecReload=@BASE_BINDIR@/sh -c '@SBINDIR@/rndc reload > /dev/null 2>&1 || @BASE_BINDIR@/kill -HUP $MAINPID' ExecStop=@BASE_BINDIR@/sh -c '@SBINDIR@/rndc stop > /dev/null 2>&1 || @BASE_BINDIR@/kill -TERM $MAINPID' PrivateTmp=true [Install] WantedBy=multi-user.target