diff --git a/share/security/advisories/FreeBSD-SA-14:27.stdio.asc b/share/security/advisories/FreeBSD-SA-14:27.stdio.asc
new file mode 100644
index 0000000000..fdc36a51e8
--- /dev/null
+++ b/share/security/advisories/FreeBSD-SA-14:27.stdio.asc
@@ -0,0 +1,126 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-SA-14:27.stdio Security Advisory
+ The FreeBSD Project
+
+Topic: Buffer overflow in stdio
+
+Category: core
+Module: libc
+Announced: 2014-12-10
+Credits: Adrian Chadd and Alfred Perlstein, Norse Corporation
+Affects: FreeBSD 10.1
+Corrected: 2014-12-10 08:24:02 UTC (stable/10, 10.1-STABLE)
+ 2014-12-10 08:35:55 UTC (releng/10.1, 10.1-RELEASE-p1)
+CVE Name: CVE-2014-8611
+
+For general information regarding FreeBSD Security Advisories,
+including descriptions of the fields above, security branches, and the
+following sections, please visit .
+
+I. Background
+
+The standard I/O library provides a simple and efficient buffered stream
+I/O interface. The library writes buffered data when it is full or when
+the application explicitly request so by calling the fflush(3) function.
+
+II. Problem Description
+
+A programming error in the standard I/O library's __sflush() function could
+erroneously adjust the buffered stream's internal state even when no write
+actually occurred in the case when write(2) system call returns an error.
+
+III. Impact
+
+The accounting mismatch would accumulate, if the caller does not check for
+stream status and will eventually lead to a heap buffer overflow.
+
+Such overflows may lead to data corruption or the execution of arbitrary
+code at the privilege level of the calling program.
+
+IV. Workaround
+
+No workaround is available.
+
+V. Solution
+
+Perform one of the following:
+
+1) Upgrade your vulnerable system to a supported FreeBSD stable or
+release / security branch (releng) dated after the correction date.
+
+2) To update your vulnerable system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+
+3) To update your vulnerable system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+# fetch http://security.FreeBSD.org/patches/SA-14:27/stdio.patch
+# fetch http://security.FreeBSD.org/patches/SA-14:27/stdio.patch.asc
+# gpg --verify stdio.patch.asc
+
+b) Apply the patch. Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile the operating system using buildworld and installworld as
+described in .
+
+Reboot the system.
+
+VI. Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path Revision
+- -------------------------------------------------------------------------
+stable/10/ r275667
+releng/10.1/ r275670
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+
+
+VII. References
+
+
+
+The latest revision of this advisory is available at
+
+-----BEGIN PGP SIGNATURE-----
+
+iQIcBAEBCgAGBQJUiA11AAoJEO1n7NZdz2rnZLMP/ic0j0lykvkZ4x39Th4vUIX7
+SCqROB8zxKj8qA3QlXhusaJA9o9hAPX8HA99ZVbDyugz0m4ST0t6JAYL+w3eVYZm
+RpEszshxi7rwUXaoue99lk0JnP2ssZbNZn5y4Z0XCYvingfP7Um6tOG0XqUs+N45
+Mivhuz+JKaFSYG4WwrSIr2pNpn6XnDeGoihtuXOkinBv8Ga3xHyuTY+30vUnEEH+
+Vr2MftHMm3Wo87OM1XhrTQS5jYzD8u0xgwKjcf0/+6Q+iXzLDkk8MfCE1W9SP7FE
+zas1MHxWeV5AICAX0CUI/9R2Zgymi/xJksw4BNZsDyGnOvIRdcMv+0KOWnCn42mk
+HCm2NTyvUM2Cgjbj5T4yICQBEi5dI6WiTp2yKTKQOiqDsszUW1NyqGQdYPfyjjMS
+kQA5RTdGVxwxp8FMnJGvYdlVRZgx5BAI8znhlxxqKs25uhbOnn+zKm+rA2XnLLMk
+sg2V/E906vldjLw8ddvNKm5oy0UkezBj0J1NOgkpN3atvUB8X2H251h2n51+oAbE
+FSd4qqN70vwHdOmIGNrjWZpOqSJzeGs5JjbaxMpo6MoIWJz2zrK2WLiFVWZGohgh
+9TGU6Ubs/yTLLfu1jTDAMl1dbZd1lChmycKRuqTpe56keOlHghquCMxhogWY0PQE
+nE47N3BP/KCtuQw1uxuK
+=F9uH
+-----END PGP SIGNATURE-----
diff --git a/share/security/advisories/FreeBSD-SA-14:28.file.asc b/share/security/advisories/FreeBSD-SA-14:28.file.asc
new file mode 100644
index 0000000000..915d5ab8b3
--- /dev/null
+++ b/share/security/advisories/FreeBSD-SA-14:28.file.asc
@@ -0,0 +1,157 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-SA-14:28.file Security Advisory
+ The FreeBSD Project
+
+Topic: Multiple vulnerabilities in file(1) and libmagic(3)
+
+Category: contrib
+Module: file
+Announced: 2014-12-10
+Affects: All supported versions of FreeBSD.
+Credits: Thomas Jarosch of Intra2net AG
+Corrected: 2014-12-10 08:26:53 UTC (stable/10, 10.1-STABLE)
+ 2014-12-10 08:35:55 UTC (releng/10.1, 10.1-RELEASE-p1)
+ 2014-12-10 08:36:07 UTC (releng/10.0, 10.0-RELEASE-p13)
+ 2014-12-10 08:31:41 UTC (stable/9, 9.3-STABLE)
+ 2014-12-10 08:36:40 UTC (releng/9.3, 9.3-RELEASE-p6)
+ 2014-12-10 08:36:40 UTC (releng/9.2, 9.2-RELEASE-p16)
+ 2014-12-10 08:36:40 UTC (releng/9.1, 9.1-RELEASE-p23)
+ 2014-12-10 08:31:41 UTC (stable/8, 8.4-STABLE)
+ 2014-12-10 08:36:40 UTC (releng/8.4, 8.4-RELEASE-p20)
+CVE Name: CVE-2014-3710, CVE-2014-8116, CVE-2014-8117
+
+For general information regarding FreeBSD Security Advisories,
+including descriptions of the fields above, security branches, and the
+following sections, please visit .
+
+I. Background
+
+The file(1) utility attempts to classify file system objects based on
+filesystem, magic number and language tests.
+
+The libmagic(3) library provides most of the functionality of file(1)
+and may be used by other applications.
+
+II. Problem Description
+
+There are a number of denial of service issues in the ELF parser used
+by file(1).
+
+III. Impact
+
+An attacker who can cause file(1) or any other applications using the
+libmagic(3) library to be run on a maliciously constructed input can
+cause the application to crash or consume excessive CPU resources,
+resulting in a denial-of-service.
+
+IV. Workaround
+
+No workaround is available, but systems where file(1) and other
+libmagic(3)-using applications are never run on untrusted input are not
+vulnerable.
+
+V. Solution
+
+Perform one of the following:
+
+1) Upgrade your vulnerable system to a supported FreeBSD stable or
+release / security branch (releng) dated after the correction date.
+
+2) To update your vulnerable system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+
+3) To update your vulnerable system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+[FreeBSD 10.1]
+# fetch http://security.FreeBSD.org/patches/SA-14:28/file-12.patch
+# fetch http://security.FreeBSD.org/patches/SA-14:28/file-12.patch.asc
+# gpg --verify file-12.patch.asc
+
+[FreeBSD 9.1, 9.2, 9.3 and 10.0]
+# fetch http://security.FreeBSD.org/patches/SA-14:28/file-8.patch
+# fetch http://security.FreeBSD.org/patches/SA-14:28/file-8.patch.asc
+# gpg --verify file-8.patch.asc
+
+[FreeBSD 8.4]
+# fetch http://security.FreeBSD.org/patches/SA-14:28/file-7.patch
+# fetch http://security.FreeBSD.org/patches/SA-14:28/file-7.patch.asc
+# gpg --verify file-7.patch.asc
+
+b) Apply the patch. Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile the operating system using buildworld and installworld as
+described in .
+
+Restart all deamons using the library, or reboot the system.
+
+VI. Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path Revision
+- -------------------------------------------------------------------------
+stable/8/ r275669
+releng/8.4/ r275672
+stable/9/ r275669
+releng/9.1/ r275672
+releng/9.2/ r275672
+releng/9.3/ r275672
+stable/10/ r275668
+releng/10.0/ r275671
+releng/10.1/ r275670
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+
+
+VII. References
+
+
+
+
+
+
+
+The latest revision of this advisory is available at
+
+-----BEGIN PGP SIGNATURE-----
+
+iQIcBAEBCgAGBQJUiA11AAoJEO1n7NZdz2rnCBMQAL/22vlzYOuAilNqQu5SZCZ8
+i+VVrq9ZQv9Q32JiSs/eZtiz8d1OrhZK86a6dzx2vd5cV3QjWTOh5oK00gnO6Nq1
+g1tqRDYVSzoPBVNLkpH0gKJjUNcxhzehQy2oge+7mtkcj3RsIX9MrPDpagIwdlOm
+KOHlfHL5w3sVbXvA9hqASH6GkvWKaj/QRm9wyHitVHYI9EbJE6jAyeDfzR1sFP54
+f4FkT3TtsVw712+TYkC/EmgyPA8R6tK08LpYsa0pnwCtuMUkT+/zmDhcjXEyqZ0X
+cimkXyANSyDxzFjNrec0ETno35a5dNeasZvRg8DZXAGko9ainwUKTk5p+AUiKUOh
+MGxCFCkAPK/jbzBfZmQ7WMwpEDpjCxKK/C1qM2hHmpXwodzMtxSONicomcQrHm3O
+f2C1JWIy7V8pLZDVN8Ce25JLjDRt+cZc6JR2sICrfAjUWXRyCbmIsTj/+CjLHH1a
+/8hXs/TI0Z4jvcPsujoo7GhOdXvLz4Z7bY9cdZgEmZaUw+OwPN3DGiUEkK1+VNNt
+ClufF6cHWE9UaUp26fjoZ/qVTFt/ixIy7Qsx9EqA1YrnemI9mOxgxTFB1jqMM6uR
+NGEFUsyUQWLJxpinrEJIvJj5r9lQw11GaqsvyOyZ8IzPLJ31okYUXUFiFUECI+aN
+P0XVV9PyCfdO6tq8ajOi
+=+w7r
+-----END PGP SIGNATURE-----
diff --git a/share/security/advisories/FreeBSD-SA-14:29.bind.asc b/share/security/advisories/FreeBSD-SA-14:29.bind.asc
new file mode 100644
index 0000000000..564e86e5a4
--- /dev/null
+++ b/share/security/advisories/FreeBSD-SA-14:29.bind.asc
@@ -0,0 +1,158 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-SA-14:29.bind Security Advisory
+ The FreeBSD Project
+
+Topic: BIND remote denial of service vulnerability
+
+Category: contrib
+Module: bind
+Announced: 2014-12-10
+Credits: ISC
+Affects: FreeBSD 8.4, 9.1, 9.2 and 9.3.
+Corrected: 2014-12-10 08:31:41 UTC (stable/9, 9.3-STABLE)
+ 2014-12-10 08:36:40 UTC (releng/9.3, 9.3-RELEASE-p6)
+ 2014-12-10 08:36:40 UTC (releng/9.2, 9.2-RELEASE-p16)
+ 2014-12-10 08:36:40 UTC (releng/9.1, 9.1-RELEASE-p23)
+ 2014-12-10 08:31:41 UTC (stable/8, 8.4-STABLE)
+ 2014-12-10 08:36:40 UTC (releng/8.4, 8.4-RELEASE-p20)
+CVE Name: CVE-2014-8500
+
+For general information regarding FreeBSD Security Advisories,
+including descriptions of the fields above, security branches, and the
+following sections, please visit .
+
+I. Background
+
+BIND 9 is an implementation of the Domain Name System (DNS) protocols.
+The named(8) daemon is an Internet Domain Name Server.
+
+II. Problem Description
+
+By causing queries to be made against a maliciously-constructed zone or
+against a malicious DNS server, an attacker who is able to cause
+specific queries to be sent to a nameserver can cause named(8) to
+crash, leading to a denial of service.
+
+All recursive BIND DNS servers are vulnerable to this. Authoritative
+servers are only vulnerable if the attacker is able to control a
+delegation traversed by the authoritative server in order to serve
+the zone.
+
+III. Impact
+
+An attacker who can cause specific queries to be sent to a nameserver
+could cause named(8) to crash, resulting in a denial of service.
+
+IV. Workaround
+
+No workaround is available, but hosts not running named(8) are not
+vulnerable.
+
+V. Solution
+
+Perform one of the following:
+
+1) Upgrade your vulnerable system to a supported FreeBSD stable or
+release / security branch (releng) dated after the correction date.
+
+2) To update your vulnerable system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+
+3) To update your vulnerable system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+[FreeBSD 9.3-RELEASE and 9.3-STABLE]
+# fetch http://security.FreeBSD.org/patches/SA-14:29/bind995.patch
+# fetch http://security.FreeBSD.org/patches/SA-14:29/bind995.patch.asc
+# gpg --verify bind995.patch.asc
+
+[FreeBSD 9.2-RELEASE]
+# fetch http://security.FreeBSD.org/patches/SA-14:29/bind984.patch
+# fetch http://security.FreeBSD.org/patches/SA-14:29/bind984.patch.asc
+# gpg --verify bind984.patch.asc
+
+[FreeBSD 9.1-RELEASE]
+# fetch http://security.FreeBSD.org/patches/SA-14:29/bind983.patch
+# fetch http://security.FreeBSD.org/patches/SA-14:29/bind983.patch.asc
+# gpg --verify bind983.patch.asc
+
+[FreeBSD 8.4-STABLE]
+# fetch http://security.FreeBSD.org/patches/SA-14:29/bind987.patch
+# fetch http://security.FreeBSD.org/patches/SA-14:29/bind987.patch.asc
+# gpg --verify bind987.patch.asc
+
+[FreeBSD 8.4-RELEASE]
+# fetch http://security.FreeBSD.org/patches/SA-14:29/bind984.patch
+# fetch http://security.FreeBSD.org/patches/SA-14:29/bind984.patch.asc
+# gpg --verify bind984.patch.asc
+
+b) Apply the patch. Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile the operating system using buildworld and installworld as
+described in .
+
+Restart the applicable daemons, or reboot the system.
+
+VI. Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path Revision
+- -------------------------------------------------------------------------
+stable/8/ r275669
+releng/8.4/ r275672
+stable/9/ r275669
+releng/9.1/ r275672
+releng/9.2/ r275672
+releng/9.3/ r275672
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+
+
+VII. References
+
+
+
+The latest revision of this advisory is available at
+
+-----BEGIN PGP SIGNATURE-----
+
+iQIcBAEBCgAGBQJUiA11AAoJEO1n7NZdz2rn7kgP/RWw0Q9dx8/xS+NSypV3Hfqr
+6D4Zh8LGsrKuWMGD29MYrFle2Ze5gUfjOFfaqonD2P5vyrCfnyVUhGiIRUKcFn/z
+dF6XwWKoZHRRHxNL7d71ZRwG3o4gEJP0SWFbfIVUg0YCDdwpChASyHJkXR5rgrTB
+6MFDdeNGq+NzQzESmJJyLT/hgWZB0p/g5tLnez+XNxxk4oGywJlNACEq9SfD618Q
+86Pl7oFJjaKrAtb7kzI2tYG+UvUHdQriRwo9C87fnSH4TNf2G1VwVoV0Lip45w4I
+MwJ8j4U3Vqr8cepqc6HSZauIA7N3N1Key7qzcnEP56iIfM1yIg+k7FTeaGM7tw45
+lxlrxgLDBpFt+F24cnROagNFZ8o2iWsnaH9ZhEkV6Qabu7eU/XjwKwY9evqqPgeP
+bCFZeFCxl4DSNTgkLmP+GjXoRxXQ2NokboU7o+KnZGPnxduDK9RG4yx0IvQc3uyv
+ad+zW4luYGuuIwVXiHif8y7SnOrp4LiVIX04isavaBVSndWC4VenlajoH8IvYxIW
+P/Bc8J0qxPmEJzZmutzLNQEDEHnxz3o9s/6C7FSASRkMMJ7QXvq0bIdVpkubh0bE
+PqJVu6WN2KD6tKjuZq4P/WVrRedsRG+qDYb819guIok2kGa6A4tgQ/DAvuZur+do
+K3JRKm1SZmozOqV/SVmy
+=uNWP
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/SA-14:27/stdio.patch b/share/security/patches/SA-14:27/stdio.patch
new file mode 100644
index 0000000000..e22504215e
--- /dev/null
+++ b/share/security/patches/SA-14:27/stdio.patch
@@ -0,0 +1,22 @@
+Index: lib/libc/stdio/fflush.c
+===================================================================
+--- lib/libc/stdio/fflush.c.orig
++++ lib/libc/stdio/fflush.c
+@@ -124,11 +124,13 @@
+ t = _swrite(fp, (char *)p, n);
+ if (t <= 0) {
+ /* Reset _p and _w. */
+- if (p > fp->_p) /* Some was written. */
++ if (p > fp->_p) {
++ /* Some was written. */
+ memmove(fp->_p, p, n);
+- fp->_p += n;
+- if ((fp->_flags & (__SLBF | __SNBF)) == 0)
+- fp->_w -= n;
++ fp->_p += n;
++ if ((fp->_flags & (__SLBF | __SNBF)) == 0)
++ fp->_w -= n;
++ }
+ fp->_flags |= __SERR;
+ return (EOF);
+ }
diff --git a/share/security/patches/SA-14:27/stdio.patch.asc b/share/security/patches/SA-14:27/stdio.patch.asc
new file mode 100644
index 0000000000..42f6b97ebd
--- /dev/null
+++ b/share/security/patches/SA-14:27/stdio.patch.asc
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIcBAABCgAGBQJUiA2QAAoJEO1n7NZdz2rnM3AP/0HoTCXA+hqUYQ3RuFXQJYLr
+2/cbSEiMvfB40rvB9T7WvZYsiWJN+V0R1yMRDu2uF4KJB6Au5GGNzdeG742yU3B4
+W2IVFtCMST0DlsGuUQV/zXeMhQiwXZx0cP5iIoukeyf/vZ7+p8b+WObB81D6+gPf
+tBlRG5cHc3eX+SGXzhbpuUQrG35KtFA0JijLIAy2criCFo+nN6iRBnVa5Uk0X3hx
+p7lRK7G9tY9fQX3Z7BqoOHxBWC1YNJEWrzkLMVWUmowXMOWvcyab6k/kwtfVCrV0
+ZilEOukghDLhzeL9oeRCgQioMHjST4wi34n7ouU6mKb+IzouyPrR42Qfax3u7Lke
+ndDauZU3G1D46+D7/O6lLpQWK8g5AYk9AL/PPDr2ewYQrxYRNchaZUdIHz9gNnud
+HITnxYsRa3/ArooIti9wF2vsqM/iuzIJ7BEGntEFsCtQgLjMUnl0Hx+Gnu+cg3aj
+Liy+bPXqtRhZdbGRVQyoFKeWjjbvwzBx692hBXqjWRhmPIWvggLHSP6o30qpsZmT
+dJNmC2m5TBFaJOpQSaq6fk6ExPKVSMjQX/IrY22IfKZ+FN1tHXsnf2l3PcZEdjd/
+PgdNjNX9EP0Pp5GzND87ooe3Z+kJewzSdWNHTpT0i6ljhH/AaJbq5VYAVlx2B/9K
+ctb+fAKvwGuyGGzZdibE
+=3A4p
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/SA-14:28/file-12.patch b/share/security/patches/SA-14:28/file-12.patch
new file mode 100644
index 0000000000..358f23c181
--- /dev/null
+++ b/share/security/patches/SA-14:28/file-12.patch
@@ -0,0 +1,288 @@
+Index: contrib/file/src/elfclass.h
+===================================================================
+--- contrib/file/src/elfclass.h.orig
++++ contrib/file/src/elfclass.h
+@@ -35,10 +35,12 @@
+ switch (type) {
+ #ifdef ELFCORE
+ case ET_CORE:
++ phnum = elf_getu16(swap, elfhdr.e_phnum);
++ if (phnum > MAX_PHNUM)
++ return toomany(ms, "program", phnum);
+ flags |= FLAGS_IS_CORE;
+ if (dophn_core(ms, clazz, swap, fd,
+- (off_t)elf_getu(swap, elfhdr.e_phoff),
+- elf_getu16(swap, elfhdr.e_phnum),
++ (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
+ (size_t)elf_getu16(swap, elfhdr.e_phentsize),
+ fsize, &flags) == -1)
+ return -1;
+@@ -46,18 +48,24 @@
+ #endif
+ case ET_EXEC:
+ case ET_DYN:
++ phnum = elf_getu16(swap, elfhdr.e_phnum);
++ if (phnum > MAX_PHNUM)
++ return toomany(ms, "program", phnum);
++ shnum = elf_getu16(swap, elfhdr.e_shnum);
++ if (shnum > MAX_SHNUM)
++ return toomany(ms, "section", shnum);
+ if (dophn_exec(ms, clazz, swap, fd,
+- (off_t)elf_getu(swap, elfhdr.e_phoff),
+- elf_getu16(swap, elfhdr.e_phnum),
++ (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
+ (size_t)elf_getu16(swap, elfhdr.e_phentsize),
+- fsize, &flags, elf_getu16(swap, elfhdr.e_shnum))
+- == -1)
++ fsize, &flags, shnum) == -1)
+ return -1;
+ /*FALLTHROUGH*/
+ case ET_REL:
++ shnum = elf_getu16(swap, elfhdr.e_shnum);
++ if (shnum > MAX_SHNUM)
++ return toomany(ms, "section", shnum);
+ if (doshn(ms, clazz, swap, fd,
+- (off_t)elf_getu(swap, elfhdr.e_shoff),
+- elf_getu16(swap, elfhdr.e_shnum),
++ (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
+ (size_t)elf_getu16(swap, elfhdr.e_shentsize),
+ fsize, &flags, elf_getu16(swap, elfhdr.e_machine),
+ (int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1)
+Index: contrib/file/src/file.h
+===================================================================
+--- contrib/file/src/file.h.orig
++++ contrib/file/src/file.h
+@@ -482,6 +482,14 @@
+ protected void file_regfree(file_regex_t *);
+ protected void file_regerror(file_regex_t *, int, struct magic_set *);
+
++typedef struct {
++ char *buf;
++ uint32_t offset;
++} file_pushbuf_t;
++
++protected file_pushbuf_t *file_push_buffer(struct magic_set *);
++protected char *file_pop_buffer(struct magic_set *, file_pushbuf_t *);
++
+ #ifndef COMPILE_ONLY
+ extern const char *file_names[];
+ extern const size_t file_nnames;
+Index: contrib/file/src/funcs.c
+===================================================================
+--- contrib/file/src/funcs.c.orig
++++ contrib/file/src/funcs.c
+@@ -491,3 +491,43 @@
+ file_magerror(ms, "regex error %d for `%s', (%s)", rc, rx->pat,
+ errmsg);
+ }
++
++protected file_pushbuf_t *
++file_push_buffer(struct magic_set *ms)
++{
++ file_pushbuf_t *pb;
++
++ if (ms->event_flags & EVENT_HAD_ERR)
++ return NULL;
++
++ if ((pb = (CAST(file_pushbuf_t *, malloc(sizeof(*pb))))) == NULL)
++ return NULL;
++
++ pb->buf = ms->o.buf;
++ pb->offset = ms->offset;
++
++ ms->o.buf = NULL;
++ ms->offset = 0;
++
++ return pb;
++}
++
++protected char *
++file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
++{
++ char *rbuf;
++
++ if (ms->event_flags & EVENT_HAD_ERR) {
++ free(pb->buf);
++ free(pb);
++ return NULL;
++ }
++
++ rbuf = ms->o.buf;
++
++ ms->o.buf = pb->buf;
++ ms->offset = pb->offset;
++
++ free(pb);
++ return rbuf;
++}
+Index: contrib/file/src/readelf.c
+===================================================================
+--- contrib/file/src/readelf.c.orig
++++ contrib/file/src/readelf.c
+@@ -60,6 +60,18 @@
+ private uint32_t getu32(int, uint32_t);
+ private uint64_t getu64(int, uint64_t);
+
++#define MAX_PHNUM 256
++#define MAX_SHNUM 1024
++
++private int
++toomany(struct magic_set *ms, const char *name, uint16_t num)
++{
++ if (file_printf(ms, ", too many %s header sections (%u)", name, num
++ ) == -1)
++ return -1;
++ return 0;
++}
++
+ private uint16_t
+ getu16(int swap, uint16_t value)
+ {
+@@ -477,6 +489,13 @@
+ uint32_t namesz, descsz;
+ unsigned char *nbuf = CAST(unsigned char *, vbuf);
+
++ if (xnh_sizeof + offset > size) {
++ /*
++ * We're out of note headers.
++ */
++ return xnh_sizeof + offset;
++ }
++
+ (void)memcpy(xnh_addr, &nbuf[offset], xnh_sizeof);
+ offset += xnh_sizeof;
+
+@@ -492,13 +511,13 @@
+ if (namesz & 0x80000000) {
+ (void)file_printf(ms, ", bad note name size 0x%lx",
+ (unsigned long)namesz);
+- return offset;
++ return 0;
+ }
+
+ if (descsz & 0x80000000) {
+ (void)file_printf(ms, ", bad note description size 0x%lx",
+ (unsigned long)descsz);
+- return offset;
++ return 0;
+ }
+
+
+@@ -900,6 +919,7 @@
+ Elf32_Shdr sh32;
+ Elf64_Shdr sh64;
+ int stripped = 1;
++ size_t nbadcap = 0;
+ void *nbuf;
+ off_t noff, coff, name_off;
+ uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
+@@ -988,6 +1008,8 @@
+ goto skip;
+ }
+
++ if (nbadcap > 5)
++ break;
+ if (lseek(fd, xsh_offset, SEEK_SET) == (off_t)-1) {
+ file_badseek(ms);
+ return -1;
+@@ -1053,6 +1075,8 @@
+ (unsigned long long)xcap_tag,
+ (unsigned long long)xcap_val) == -1)
+ return -1;
++ if (nbadcap++ > 2)
++ coff = xsh_size;
+ break;
+ }
+ }
+@@ -1233,7 +1257,7 @@
+ int flags = 0;
+ Elf32_Ehdr elf32hdr;
+ Elf64_Ehdr elf64hdr;
+- uint16_t type;
++ uint16_t type, phnum, shnum;
+
+ if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
+ return 0;
+Index: contrib/file/src/softmagic.c
+===================================================================
+--- contrib/file/src/softmagic.c.orig
++++ contrib/file/src/softmagic.c
+@@ -67,6 +67,9 @@
+ private void cvt_64(union VALUETYPE *, const struct magic *);
+
+ #define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o)))
++
++#define MAX_RECURSION_LEVEL 10
++
+ /*
+ * softmagic - lookup one file in parsed, in-memory copy of database
+ * Passed the name and FILE * of one file to be typed.
+@@ -1193,14 +1196,15 @@
+ int flip, int recursion_level, int *printed_something,
+ int *need_separator, int *returnval)
+ {
+- uint32_t soffset, offset = ms->offset;
++ uint32_t offset = ms->offset;
+ uint32_t lhs;
++ file_pushbuf_t *pb;
+ int rv, oneed_separator, in_type;
+- char *sbuf, *rbuf;
++ char *rbuf;
+ union VALUETYPE *p = &ms->ms_value;
+ struct mlist ml;
+
+- if (recursion_level >= 20) {
++ if (recursion_level >= MAX_RECURSION_LEVEL) {
+ file_error(ms, 0, "recursion nesting exceeded");
+ return -1;
+ }
+@@ -1644,19 +1648,23 @@
+ case FILE_INDIRECT:
+ if (offset == 0)
+ return 0;
++
+ if (nbytes < offset)
+ return 0;
+- sbuf = ms->o.buf;
+- soffset = ms->offset;
+- ms->o.buf = NULL;
+- ms->offset = 0;
++
++ if ((pb = file_push_buffer(ms)) == NULL)
++ return -1;
++
+ rv = file_softmagic(ms, s + offset, nbytes - offset,
+ recursion_level, BINTEST, text);
++
+ if ((ms->flags & MAGIC_DEBUG) != 0)
+ fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
+- rbuf = ms->o.buf;
+- ms->o.buf = sbuf;
+- ms->offset = soffset;
++
++ rbuf = file_pop_buffer(ms, pb);
++ if (rbuf == NULL && ms->event_flags & EVENT_HAD_ERR)
++ return -1;
++
+ if (rv == 1) {
+ if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
+ file_printf(ms, F(ms, m, "%u"), offset) == -1) {
+@@ -1674,13 +1682,13 @@
+ case FILE_USE:
+ if (nbytes < offset)
+ return 0;
+- sbuf = m->value.s;
+- if (*sbuf == '^') {
+- sbuf++;
++ rbuf = m->value.s;
++ if (*rbuf == '^') {
++ rbuf++;
+ flip = !flip;
+ }
+- if (file_magicfind(ms, sbuf, &ml) == -1) {
+- file_error(ms, 0, "cannot find entry `%s'", sbuf);
++ if (file_magicfind(ms, rbuf, &ml) == -1) {
++ file_error(ms, 0, "cannot find entry `%s'", rbuf);
+ return -1;
+ }
+
diff --git a/share/security/patches/SA-14:28/file-12.patch.asc b/share/security/patches/SA-14:28/file-12.patch.asc
new file mode 100644
index 0000000000..b8e4acd256
--- /dev/null
+++ b/share/security/patches/SA-14:28/file-12.patch.asc
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIcBAABCgAGBQJUiA2QAAoJEO1n7NZdz2rnjzAQANogueUdUbRBgn+EYwcnKUgQ
+8y4P5VDNnAIxKrPCRGpRF9IvGaxAzO62y/GlZ6Fq+H+VFk+1poCIXDY3escUM0uk
+BM/V+k3wuvsaefTiNIfTMEOYiJ81nrcMZ5cDtO4wgN1Pem44Lmh8O3gztAMSGgFm
+IzJBYcDp8XgGYZqCtZN0gAQjLuJHn6vrqdW//dyXNmpsNFMLAlBFI9IJ6R/EuHyF
+gcmw2UDtnTvR5+PfBSo9T/DZUB6sWrh3h2FQi2AFnOm1qbzhsRoZy+ea8zgnnYYD
+kdTkiyXq6opoQYLeCrYcyaIksCNXvQNh6ocQKrEpTXNO9p6/uN4QSrd35HK+/8JK
+4zgMWWOQB35QBhtxevVjR03JtPXa1r61Y/jY00nnGrnzVx01/GKo2vzbo3+iwBJB
+rvkSvQKuJxm6k54oOUtCIOKzkackSiKIcbaPXt7g0dZhLrsV7JwXuCrXfz+aDFqt
+F/gxckIybZjM1NW3/4PNN1W7nvc+cW3dsHaEW2susGXRi2eHlM2VqZjAoMHmqN3v
+9swzo5Cu3Xotx3gSPGH19g6MLZh/xMSXCIylRYw5xxCOP3H3o2lO3Gnet+rFIJVs
+pXUlibCmuTnalxlUT7q5OXancUItUQ4haYkXf7FglqOAeekdLvwboQoANKnBubhr
+c07kINUBCQlbtRDd66Qs
+=9qt7
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/SA-14:28/file-7.patch b/share/security/patches/SA-14:28/file-7.patch
new file mode 100644
index 0000000000..ce0326305d
--- /dev/null
+++ b/share/security/patches/SA-14:28/file-7.patch
@@ -0,0 +1,146 @@
+Index: contrib/file/elfclass.h
+===================================================================
+--- contrib/file/elfclass.h.orig
++++ contrib/file/elfclass.h
+@@ -35,9 +35,11 @@
+ switch (type) {
+ #ifdef ELFCORE
+ case ET_CORE:
++ phnum = elf_getu16(swap, elfhdr.e_phnum);
++ if (phnum > MAX_PHNUM)
++ return toomany(ms, "program", phnum);
+ if (dophn_core(ms, clazz, swap, fd,
+- (off_t)elf_getu(swap, elfhdr.e_phoff),
+- elf_getu16(swap, elfhdr.e_phnum),
++ (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
+ (size_t)elf_getu16(swap, elfhdr.e_phentsize),
+ fsize, &flags) == -1)
+ return -1;
+@@ -45,18 +47,24 @@
+ #endif
+ case ET_EXEC:
+ case ET_DYN:
++ phnum = elf_getu16(swap, elfhdr.e_phnum);
++ if (phnum > MAX_PHNUM)
++ return toomany(ms, "program", phnum);
++ shnum = elf_getu16(swap, elfhdr.e_shnum);
++ if (shnum > MAX_SHNUM)
++ return toomany(ms, "section", shnum);
+ if (dophn_exec(ms, clazz, swap, fd,
+- (off_t)elf_getu(swap, elfhdr.e_phoff),
+- elf_getu16(swap, elfhdr.e_phnum),
++ (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
+ (size_t)elf_getu16(swap, elfhdr.e_phentsize),
+- fsize, &flags, elf_getu16(swap, elfhdr.e_shnum))
+- == -1)
++ fsize, &flags, shnum) == -1)
+ return -1;
+ /*FALLTHROUGH*/
+ case ET_REL:
++ shnum = elf_getu16(swap, elfhdr.e_shnum);
++ if (shnum > MAX_SHNUM)
++ return toomany(ms, "section", shnum);
+ if (doshn(ms, clazz, swap, fd,
+- (off_t)elf_getu(swap, elfhdr.e_shoff),
+- elf_getu16(swap, elfhdr.e_shnum),
++ (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
+ (size_t)elf_getu16(swap, elfhdr.e_shentsize),
+ &flags,
+ elf_getu16(swap, elfhdr.e_machine)) == -1)
+Index: contrib/file/readelf.c
+===================================================================
+--- contrib/file/readelf.c.orig
++++ contrib/file/readelf.c
+@@ -60,6 +60,18 @@
+ private uint32_t getu32(int, uint32_t);
+ private uint64_t getu64(int, uint64_t);
+
++#define MAX_PHNUM 256
++#define MAX_SHNUM 1024
++
++private int
++toomany(struct magic_set *ms, const char *name, uint16_t num)
++{
++ if (file_printf(ms, ", too many %s header sections (%u)", name, num
++ ) == -1)
++ return -1;
++ return 0;
++}
++
+ private uint16_t
+ getu16(int swap, uint16_t value)
+ {
+@@ -391,13 +403,13 @@
+ if (namesz & 0x80000000) {
+ (void)file_printf(ms, ", bad note name size 0x%lx",
+ (unsigned long)namesz);
+- return offset;
++ return 0;
+ }
+
+ if (descsz & 0x80000000) {
+ (void)file_printf(ms, ", bad note description size 0x%lx",
+ (unsigned long)descsz);
+- return offset;
++ return 0;
+ }
+
+
+@@ -821,6 +833,7 @@
+ Elf32_Shdr sh32;
+ Elf64_Shdr sh64;
+ int stripped = 1;
++ size_t nbadcap = 0;
+ void *nbuf;
+ off_t noff;
+ uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
+@@ -893,6 +906,8 @@
+ case SHT_SUNW_cap:
+ {
+ off_t coff;
++ if (nbadcap > 5)
++ break;
+ if ((off = lseek(fd, (off_t)0, SEEK_CUR)) ==
+ (off_t)-1) {
+ file_badread(ms);
+@@ -933,6 +948,8 @@
+ (unsigned long long)xcap_tag,
+ (unsigned long long)xcap_val) == -1)
+ return -1;
++ if (nbadcap++ > 2)
++ coff = xsh_size;
+ break;
+ }
+ }
+@@ -1139,7 +1156,7 @@
+ int flags = 0;
+ Elf32_Ehdr elf32hdr;
+ Elf64_Ehdr elf64hdr;
+- uint16_t type;
++ uint16_t type, phnum, shnum;
+
+ if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
+ return 0;
+Index: contrib/file/softmagic.c
+===================================================================
+--- contrib/file/softmagic.c.orig
++++ contrib/file/softmagic.c
+@@ -61,6 +61,9 @@
+ private void cvt_64(union VALUETYPE *, const struct magic *);
+
+ #define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o)))
++
++#define MAX_RECURSION_LEVEL 10
++
+ /*
+ * softmagic - lookup one file in parsed, in-memory copy of database
+ * Passed the name and FILE * of one file to be typed.
+@@ -1030,7 +1033,7 @@
+ uint32_t count = m->str_range;
+ union VALUETYPE *p = &ms->ms_value;
+
+- if (recursion_level >= 20) {
++ if (recursion_level >= MAX_RECURSION_LEVEL) {
+ file_error(ms, 0, "recursion nesting exceeded");
+ return -1;
+ }
diff --git a/share/security/patches/SA-14:28/file-7.patch.asc b/share/security/patches/SA-14:28/file-7.patch.asc
new file mode 100644
index 0000000000..e5bb6a3db7
--- /dev/null
+++ b/share/security/patches/SA-14:28/file-7.patch.asc
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIcBAABCgAGBQJUiA2RAAoJEO1n7NZdz2rnaRIQAOy5fBvNnNRIM2mEoiDVbI2a
+nVoDsiSHWX9roIRdY/3L0d/S4mbvt08Sbd10qF6pR/haJlniDBR8BHxjkUHU5rTF
+C/rkIsVJwasf4Mb6yTIlJntAqZDRVr4vtv3Y4EN9qJqI85q3KhSNJByrllltiBzg
+BfHUxKV8vaBULDNbAICeNa6HJ9dOzup9Fr1zu+N+dup3SCIbvHBiS8I/fHvQvzf4
+to5kkp4XwHUDgemS9cuwLzs9Xs5VJbhJht8n/2flJI80mTrLa+sGlNLARjOMJU3n
+NFW7oZ01spsWfLrdCr9fI/zsf7QowKHHEquZaX305BysmBqdes4FqkjMbRelM8a3
+4kKzV8b1ZLXXzqw6Tj4XXFcC0SAqvYtDou2u+AoIJwfdO7AbFDYBKS6AD5sP5tb6
+3ZwoiWk09Xnb3gVOPrzvh/9nF6BrjhHC5qlSt8Kdp1XWupoXBaxWbSu9Dcfu1Amd
+PhivZ1DrK5lMkzIDCjW/aXrbhIWrZR/a2ilsWbeSgO8Wq899gPlj6zHnf9pxBKVJ
+QKO/hkb0f4fmFd7RDi3fCN6dOXEyT3lo8GcDVLvfbJYjbbWveylPmg6/O2SOKqYY
+KMFrECyoSRSgY9aV3pISw/ioukukkS+R0vDCdthNUHdxbpAM53OnnVaeJrZnoAt5
+xjvvLOy4c+UQZDj4GuON
+=ZtPX
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/SA-14:28/file-8.patch b/share/security/patches/SA-14:28/file-8.patch
new file mode 100644
index 0000000000..4eb36a7cb1
--- /dev/null
+++ b/share/security/patches/SA-14:28/file-8.patch
@@ -0,0 +1,147 @@
+Index: contrib/file/elfclass.h
+===================================================================
+--- contrib/file/elfclass.h.orig
++++ contrib/file/elfclass.h
+@@ -35,10 +35,12 @@
+ switch (type) {
+ #ifdef ELFCORE
+ case ET_CORE:
++ phnum = elf_getu16(swap, elfhdr.e_phnum);
++ if (phnum > MAX_PHNUM)
++ return toomany(ms, "program", phnum);
+ flags |= FLAGS_IS_CORE;
+ if (dophn_core(ms, clazz, swap, fd,
+- (off_t)elf_getu(swap, elfhdr.e_phoff),
+- elf_getu16(swap, elfhdr.e_phnum),
++ (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
+ (size_t)elf_getu16(swap, elfhdr.e_phentsize),
+ fsize, &flags) == -1)
+ return -1;
+@@ -46,18 +48,24 @@
+ #endif
+ case ET_EXEC:
+ case ET_DYN:
++ phnum = elf_getu16(swap, elfhdr.e_phnum);
++ if (phnum > MAX_PHNUM)
++ return toomany(ms, "program", phnum);
++ shnum = elf_getu16(swap, elfhdr.e_shnum);
++ if (shnum > MAX_SHNUM)
++ return toomany(ms, "section", shnum);
+ if (dophn_exec(ms, clazz, swap, fd,
+- (off_t)elf_getu(swap, elfhdr.e_phoff),
+- elf_getu16(swap, elfhdr.e_phnum),
++ (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
+ (size_t)elf_getu16(swap, elfhdr.e_phentsize),
+- fsize, &flags, elf_getu16(swap, elfhdr.e_shnum))
+- == -1)
++ fsize, &flags, shnum) == -1)
+ return -1;
+ /*FALLTHROUGH*/
+ case ET_REL:
++ shnum = elf_getu16(swap, elfhdr.e_shnum);
++ if (shnum > MAX_SHNUM)
++ return toomany(ms, "section", shnum);
+ if (doshn(ms, clazz, swap, fd,
+- (off_t)elf_getu(swap, elfhdr.e_shoff),
+- elf_getu16(swap, elfhdr.e_shnum),
++ (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
+ (size_t)elf_getu16(swap, elfhdr.e_shentsize),
+ fsize, &flags, elf_getu16(swap, elfhdr.e_machine)) == -1)
+ return -1;
+Index: contrib/file/readelf.c
+===================================================================
+--- contrib/file/readelf.c.orig
++++ contrib/file/readelf.c
+@@ -60,6 +60,18 @@
+ private uint32_t getu32(int, uint32_t);
+ private uint64_t getu64(int, uint64_t);
+
++#define MAX_PHNUM 256
++#define MAX_SHNUM 1024
++
++private int
++toomany(struct magic_set *ms, const char *name, uint16_t num)
++{
++ if (file_printf(ms, ", too many %s header sections (%u)", name, num
++ ) == -1)
++ return -1;
++ return 0;
++}
++
+ private uint16_t
+ getu16(int swap, uint16_t value)
+ {
+@@ -384,13 +396,13 @@
+ if (namesz & 0x80000000) {
+ (void)file_printf(ms, ", bad note name size 0x%lx",
+ (unsigned long)namesz);
+- return offset;
++ return 0;
+ }
+
+ if (descsz & 0x80000000) {
+ (void)file_printf(ms, ", bad note description size 0x%lx",
+ (unsigned long)descsz);
+- return offset;
++ return 0;
+ }
+
+
+@@ -847,6 +859,7 @@
+ Elf32_Shdr sh32;
+ Elf64_Shdr sh64;
+ int stripped = 1;
++ size_t nbadcap = 0;
+ void *nbuf;
+ off_t noff, coff;
+ uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
+@@ -919,6 +932,8 @@
+ free(nbuf);
+ break;
+ case SHT_SUNW_cap:
++ if (nbadcap > 5)
++ break;
+ if (lseek(fd, (off_t)xsh_offset, SEEK_SET) ==
+ (off_t)-1) {
+ file_badseek(ms);
+@@ -955,6 +970,8 @@
+ (unsigned long long)xcap_tag,
+ (unsigned long long)xcap_val) == -1)
+ return -1;
++ if (nbadcap++ > 2)
++ coff = xsh_size;
+ break;
+ }
+ }
+@@ -1142,7 +1159,7 @@
+ int flags = 0;
+ Elf32_Ehdr elf32hdr;
+ Elf64_Ehdr elf64hdr;
+- uint16_t type;
++ uint16_t type, phnum, shnum;
+
+ if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
+ return 0;
+Index: contrib/file/softmagic.c
+===================================================================
+--- contrib/file/softmagic.c.orig
++++ contrib/file/softmagic.c
+@@ -61,6 +61,9 @@
+ private void cvt_64(union VALUETYPE *, const struct magic *);
+
+ #define OFFSET_OOB(n, o, i) ((n) < (o) || (i) > ((n) - (o)))
++
++#define MAX_RECURSION_LEVEL 10
++
+ /*
+ * softmagic - lookup one file in parsed, in-memory copy of database
+ * Passed the name and FILE * of one file to be typed.
+@@ -1027,7 +1030,7 @@
+ uint32_t count = m->str_range;
+ union VALUETYPE *p = &ms->ms_value;
+
+- if (recursion_level >= 20) {
++ if (recursion_level >= MAX_RECURSION_LEVEL) {
+ file_error(ms, 0, "recursion nesting exceeded");
+ return -1;
+ }
diff --git a/share/security/patches/SA-14:28/file-8.patch.asc b/share/security/patches/SA-14:28/file-8.patch.asc
new file mode 100644
index 0000000000..6156541162
--- /dev/null
+++ b/share/security/patches/SA-14:28/file-8.patch.asc
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIcBAABCgAGBQJUiA2QAAoJEO1n7NZdz2rn6SAQAKXZOrvpfOUrSIN9HhGqdTn5
+IoHVlnPZnx7V4xikviHKkXfCRbRtTFHysB4XxcaMoeTqAdS2Kl9/pfPjMRdkPstA
+UtzMNw8NYJeFHu4tdPXgE3VULpfqIaOuUirCsvFP5xuIWJDDr3HhwlO9ZJE7JAex
+xASxuOA9jz22a/fkUuDu5iy5RLyzR9+n8zqDBHrkzZuPDFrLrbmtVL6kso+ka3zY
+RUnc6SD9hAKyP7XVO95/wj8QfjUrW6dsI1XJbTzKTAUIPSvH5aC/1cKj2uwSKDxl
+wsdC9ojCM3CaacqMfFQ5jTPsy72qtVTmVbCyZprPqHVNANRehweaDsyhbZZ4GwVW
+RGQdXf+NYdiNxg+2RthVXL6JLsC+vI8mncQoMnIGgsXSKk2PbCl7J9lpDTjZpxN1
+YOykFPg5BfieMM/vGzzC7MySIduvDQkbjk4S4w6ju2y9lsG/gsbr78ewYDCZcoBa
+jlGo3MB/3ip/k8sxLQwv+Rb4FYJE8OFlcGU/8UXwoBGEa5vNoAX3bVLgHzqnVztV
+jY6qwpWThbEdqCpfwf7ROTDN3RMZgMuQkIrqCAejvX8mctxCHULGy5GHiCkfEbAk
+9d5cTq+qeYMhbrgkwmAd0kT1lsBYvPyTISTEA3X6kfigFu7mQ7uc4dDOo5K2eEZJ
+f7B7AKy5HMEV3odsriNu
+=E3x/
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/SA-14:29/bind983.patch b/share/security/patches/SA-14:29/bind983.patch
new file mode 100644
index 0000000000..d83e9cce84
--- /dev/null
+++ b/share/security/patches/SA-14:29/bind983.patch
@@ -0,0 +1,956 @@
+Index: contrib/bind9/CHANGES
+===================================================================
+--- contrib/bind9/CHANGES.orig
++++ contrib/bind9/CHANGES
+@@ -1,3 +1,15 @@
++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, and the query limit
++ via the "max-recursion-queries" option. [RT #37580]
++
+ --- 9.8.3-P4 released ---
+
+ 3383. [security] A certain combination of records in the RBT could
+Index: contrib/bind9/bin/named/config.c
+===================================================================
+--- contrib/bind9/bin/named/config.c.orig
++++ contrib/bind9/bin/named/config.c
+@@ -15,8 +15,6 @@
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+-/* $Id: config.c,v 1.113.16.2 2011/02/28 01:19:58 tbox Exp $ */
+-
+ /*! \file */
+
+ #include
+@@ -158,6 +156,8 @@
+ dnssec-accept-expired no;\n\
+ clients-per-query 10;\n\
+ max-clients-per-query 100;\n\
++ max-recursion-depth 7;\n\
++ max-recursion-queries 50;\n\
+ zero-no-soa-ttl-cache no;\n\
+ nsec3-test-zone no;\n\
+ allow-new-zones no;\n\
+Index: contrib/bind9/bin/named/query.c
+===================================================================
+--- contrib/bind9/bin/named/query.c.orig
++++ contrib/bind9/bin/named/query.c
+@@ -3761,12 +3761,11 @@
+ 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, NULL,
++ client->task, query_resume, client,
+ rdataset, sigrdataset,
+ &client->query.fetch);
+
+Index: contrib/bind9/bin/named/server.c
+===================================================================
+--- contrib/bind9/bin/named/server.c.orig
++++ contrib/bind9/bin/named/server.c
+@@ -2566,6 +2566,16 @@
+ 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));
++
++ obj = NULL;
++ result = ns_config_get(maps, "max-recursion-queries", &obj);
++ INSIST(result == ISC_R_SUCCESS);
++ dns_resolver_setmaxqueries(view->resolver, cfg_obj_asuint32(obj));
++
+ #ifdef ALLOW_FILTER_AAAA_ON_V4
+ obj = NULL;
+ result = ns_config_get(maps, "filter-aaaa-on-v4", &obj);
+Index: contrib/bind9/lib/dns/adb.c
+===================================================================
+--- contrib/bind9/lib/dns/adb.c.orig
++++ contrib/bind9/lib/dns/adb.c
+@@ -200,6 +200,7 @@
+ unsigned int magic;
+ dns_fetch_t *fetch;
+ dns_rdataset_t rdataset;
++ unsigned int depth;
+ };
+
+ /*%
+@@ -299,8 +300,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);
++static void clean_finds_at_name(dns_adbname_t *, isc_eventtype_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,6 +308,7 @@
+ 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,
++ unsigned int, isc_counter_t *qc,
+ dns_rdatatype_t);
+ static inline void check_exit(dns_adb_t *);
+ static void destroy(dns_adb_t *);
+@@ -2743,6 +2744,19 @@
+ 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, NULL, 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, isc_counter_t *qc,
++ dns_adbfind_t **findp)
++{
+ dns_adbfind_t *find;
+ dns_adbname_t *adbname;
+ int bucket;
+@@ -2973,7 +2987,7 @@
+ * Start V4.
+ */
+ if (WANT_INET(wanted_fetches) &&
+- fetch_name(adbname, start_at_zone,
++ fetch_name(adbname, start_at_zone, depth, qc,
+ dns_rdatatype_a) == ISC_R_SUCCESS) {
+ DP(DEF_LEVEL,
+ "dns_adb_createfind: started A fetch for name %p",
+@@ -2984,7 +2998,7 @@
+ * Start V6.
+ */
+ if (WANT_INET6(wanted_fetches) &&
+- fetch_name(adbname, start_at_zone,
++ fetch_name(adbname, start_at_zone, depth, qc,
+ dns_rdatatype_aaaa) == ISC_R_SUCCESS) {
+ DP(DEF_LEVEL,
+ "dns_adb_createfind: "
+@@ -3727,6 +3741,12 @@
+ 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);
+@@ -3764,9 +3784,8 @@
+ }
+
+ 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, isc_counter_t *qc, dns_rdatatype_t type)
+ {
+ isc_result_t result;
+ dns_adbfetch_t *fetch = NULL;
+@@ -3811,12 +3830,14 @@
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
++ fetch->depth = depth;
+
+- result = dns_resolver_createfetch(adb->view->resolver, &adbname->name,
+- type, name, nameservers, NULL,
+- options, adb->task, fetch_callback,
+- adbname, &fetch->rdataset, NULL,
+- &fetch->fetch);
++ result = dns_resolver_createfetch3(adb->view->resolver, &adbname->name,
++ type, name, nameservers, NULL,
++ NULL, 0, options, depth, qc,
++ adb->task, fetch_callback, adbname,
++ &fetch->rdataset, NULL,
++ &fetch->fetch);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+Index: contrib/bind9/lib/dns/include/dns/adb.h
+===================================================================
+--- contrib/bind9/lib/dns/include/dns/adb.h.orig
++++ contrib/bind9/lib/dns/include/dns/adb.h
+@@ -334,6 +334,13 @@
+ 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, isc_counter_t *qc,
++ 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
+Index: contrib/bind9/lib/dns/include/dns/resolver.h
+===================================================================
+--- contrib/bind9/lib/dns/include/dns/resolver.h.orig
++++ contrib/bind9/lib/dns/include/dns/resolver.h
+@@ -271,6 +271,18 @@
+ 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_counter_t *qc, 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.
+ *
+@@ -572,6 +584,30 @@
+ * \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.
++ */
++
++void
++dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries);
++unsigned int
++dns_resolver_getmaxqueries(dns_resolver_t *resolver);
++/*%
++ * Get and set how many iterative queries will be allowed before
++ * terminating a recursive query.
++ *
++ * Requires:
++ * \li resolver to be valid.
++ */
++
+ ISC_LANG_ENDDECLS
+
+ #endif /* DNS_RESOLVER_H */
+Index: contrib/bind9/lib/dns/resolver.c
+===================================================================
+--- contrib/bind9/lib/dns/resolver.c.orig
++++ contrib/bind9/lib/dns/resolver.c
+@@ -21,6 +21,7 @@
+
+ #include
+
++#include
+ #include
+ #include
+ #include
+@@ -113,6 +114,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.
+ */
+@@ -214,12 +225,13 @@
+ isc_sockaddrlist_t edns;
+ isc_sockaddrlist_t edns512;
+ isc_sockaddrlist_t bad_edns;
+- dns_validator_t *validator;
++ dns_validator_t * validator;
+ ISC_LIST(dns_validator_t) validators;
+ dns_db_t * cache;
+ dns_adb_t * adb;
+ isc_boolean_t ns_ttl_ok;
+ isc_uint32_t ns_ttl;
++ isc_counter_t * qc;
+
+ /*%
+ * The number of events we're waiting for.
+@@ -287,6 +299,7 @@
+ isc_boolean_t timeout;
+ dns_adbaddrinfo_t *addrinfo;
+ isc_sockaddr_t *client;
++ unsigned int depth;
+ };
+
+ #define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!')
+@@ -399,6 +412,8 @@
+ isc_timer_t * spillattimer;
+ isc_boolean_t zero_no_soa_ttl;
+ unsigned int query_timeout;
++ unsigned int maxdepth;
++ unsigned int maxqueries;
+
+ /* Locked by lock. */
+ unsigned int references;
+@@ -1545,6 +1560,7 @@
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_dispatch;
+ }
++
+ fctx->querysent++;
+
+ ISC_LIST_APPEND(fctx->queries, query, link);
+@@ -2186,9 +2202,9 @@
+ */
+ 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 {
++ } else {
+ fctx->findfail++;
+ if (fctx->pending == 0) {
+ /*
+@@ -2217,7 +2233,7 @@
+ else if (want_done)
+ fctx_done(fctx, ISC_R_FAILURE, __LINE__);
+ else if (destroy) {
+- fctx_destroy(fctx);
++ fctx_destroy(fctx);
+ if (bucket_empty)
+ empty_bucket(res);
+ }
+@@ -2471,12 +2487,13 @@
+ * 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, fctx->qc, &find);
+ if (result != ISC_R_SUCCESS) {
+ if (result == DNS_R_ALIAS) {
+ /*
+@@ -2584,6 +2601,14 @@
+
+ res = fctx->res;
+
++ if (fctx->depth > res->maxdepth) {
++ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
++ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
++ "too much NS indirection resolving '%s'",
++ fctx->info);
++ return (DNS_R_SERVFAIL);
++ }
++
+ /*
+ * Forwarders.
+ */
+@@ -3059,6 +3084,16 @@
+ }
+ }
+
++ result = isc_counter_increment(fctx->qc);
++ if (result != ISC_R_SUCCESS) {
++ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
++ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
++ "exceeded max queries resolving '%s'",
++ fctx->info);
++ fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
++ return;
++ }
++
+ result = fctx_query(fctx, addrinfo, fctx->options);
+ if (result != ISC_R_SUCCESS)
+ fctx_done(fctx, result, __LINE__);
+@@ -3157,6 +3192,7 @@
+ isc_mem_put(fctx->mctx, sa, sizeof(*sa));
+ }
+
++ isc_counter_detach(&fctx->qc);
+ isc_timer_detach(&fctx->timer);
+ dns_message_destroy(&fctx->rmessage);
+ dns_message_destroy(&fctx->qmessage);
+@@ -3485,7 +3521,8 @@
+ 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,
++ isc_counter_t *qc, fetchctx_t **fctxp)
+ {
+ fetchctx_t *fctx;
+ isc_result_t result;
+@@ -3507,6 +3544,21 @@
+ fctx = isc_mem_get(mctx, sizeof(*fctx));
+ if (fctx == NULL)
+ return (ISC_R_NOMEMORY);
++
++ fctx->qc = NULL;
++ if (qc != NULL) {
++ isc_counter_attach(qc, &fctx->qc);
++ } else {
++ result = isc_counter_create(res->mctx,
++ res->maxqueries, &fctx->qc);
++ if (result != ISC_R_SUCCESS)
++ goto cleanup_fetch;
++ }
++
++ /*
++ * Make fctx->info point to a copy of a formatted string
++ * "name/type".
++ */
+ dns_name_format(name, buf, sizeof(buf));
+ dns_rdatatype_format(type, typebuf, sizeof(typebuf));
+ strcat(buf, "/"); /* checked */
+@@ -3514,7 +3566,7 @@
+ fctx->info = isc_mem_strdup(mctx, buf);
+ if (fctx->info == NULL) {
+ result = ISC_R_NOMEMORY;
+- goto cleanup_fetch;
++ goto cleanup_counter;
+ }
+ FCTXTRACE("create");
+ dns_name_init(&fctx->name, NULL);
+@@ -3537,6 +3589,7 @@
+ 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);
+@@ -3742,6 +3795,9 @@
+ cleanup_info:
+ isc_mem_free(mctx, fctx->info);
+
++ cleanup_counter:
++ isc_counter_detach(&fctx->qc);
++
+ cleanup_fetch:
+ isc_mem_put(mctx, fctx, sizeof(*fctx));
+
+@@ -5453,7 +5509,7 @@
+ char qbuf[DNS_NAME_FORMATSIZE];
+ char nbuf[DNS_NAME_FORMATSIZE];
+ char tbuf[DNS_RDATATYPE_FORMATSIZE];
+- dns_rdatatype_format(fctx->type, tbuf,
++ dns_rdatatype_format(type, tbuf,
+ sizeof(tbuf));
+ dns_name_format(name, nbuf,
+ sizeof(nbuf));
+@@ -5462,7 +5518,7 @@
+ log_formerr(fctx,
+ "unrelated %s %s in "
+ "%s authority section",
+- tbuf, qbuf, nbuf);
++ tbuf, nbuf, qbuf);
+ return (DNS_R_FORMERR);
+ }
+ if (type == dns_rdatatype_ns) {
+@@ -7504,6 +7560,8 @@
+ res->query_timeout = DEFAULT_QUERY_TIMEOUT;
+ res->ndisps = 0;
+ res->nextdisp = 0; /* meaningless at this point, but init it */
++ res->maxdepth = DEFAULT_RECURSION_DEPTH;
++ res->maxqueries = DEFAULT_MAX_QUERIES;
+ res->nbuckets = ntasks;
+ res->activebuckets = ntasks;
+ res->buckets = isc_mem_get(view->mctx,
+@@ -7943,9 +8001,9 @@
+ 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, NULL, task, action, arg,
+ rdataset, sigrdataset, fetchp));
+ }
+
+@@ -7961,6 +8019,25 @@
+ dns_rdataset_t *sigrdataset,
+ dns_fetch_t **fetchp)
+ {
++ return (dns_resolver_createfetch3(res, name, type, domain,
++ nameservers, forwarders, client, id,
++ options, 0, NULL, 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_counter_t *qc, 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;
+@@ -8047,11 +8124,12 @@
+
+ if (fctx == NULL) {
+ result = fctx_create(res, name, type, domain, nameservers,
+- options, bucketnum, &fctx);
++ options, bucketnum, depth, qc, &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);
+@@ -8821,3 +8899,27 @@
+
+ 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);
++}
++
++void
++dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries) {
++ REQUIRE(VALID_RESOLVER(resolver));
++ resolver->maxqueries = queries;
++}
++
++unsigned int
++dns_resolver_getmaxqueries(dns_resolver_t *resolver) {
++ REQUIRE(VALID_RESOLVER(resolver));
++ return (resolver->maxqueries);
++}
+Index: contrib/bind9/lib/export/isc/Makefile.in
+===================================================================
+--- contrib/bind9/lib/export/isc/Makefile.in.orig
++++ contrib/bind9/lib/export/isc/Makefile.in
+@@ -63,7 +63,7 @@
+ # Alphabetically
+ OBJS = @ISC_EXTRA_OBJS@ \
+ assertions.@O@ backtrace.@O@ backtrace-emptytbl.@O@ base32.@O@ \
+- base64.@O@ buffer.@O@ bufferlist.@O@ \
++ base64.@O@ buffer.@O@ bufferlist.@O@ counter.@O@ \
+ error.@O@ event.@O@ \
+ hash.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \
+ inet_aton.@O@ iterated_hash.@O@ lex.@O@ lfsr.@O@ log.@O@ \
+@@ -86,7 +86,7 @@
+
+ SRCS = @ISC_EXTRA_SRCS@ \
+ assertions.c backtrace.c backtrace-emptytbl.c base32.c \
+- base64.c buffer.c bufferlist.c \
++ base64.c buffer.c bufferlist.c counter.c \
+ error.c event.c \
+ hash.c hex.c hmacmd5.c hmacsha.c \
+ inet_aton.c iterated_hash.c lex.c log.c lfsr.c \
+Index: contrib/bind9/lib/isc/Makefile.in
+===================================================================
+--- contrib/bind9/lib/isc/Makefile.in.orig
++++ contrib/bind9/lib/isc/Makefile.in
+@@ -13,8 +13,6 @@
+ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ # PERFORMANCE OF THIS SOFTWARE.
+
+-# $Id$
+-
+ srcdir = @srcdir@
+ VPATH = @srcdir@
+ top_srcdir = @top_srcdir@
+@@ -53,7 +51,7 @@
+ OBJS = @ISC_EXTRA_OBJS@ \
+ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \
+ bitstring.@O@ buffer.@O@ bufferlist.@O@ commandline.@O@ \
+- error.@O@ event.@O@ \
++ counter.@O@ error.@O@ event.@O@ \
+ hash.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \
+ httpd.@O@ inet_aton.@O@ iterated_hash.@O@ \
+ lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \
+@@ -69,8 +67,8 @@
+ # Alphabetically
+ SRCS = @ISC_EXTRA_SRCS@ \
+ assertions.c backtrace.c base32.c base64.c bitstring.c \
+- buffer.c bufferlist.c commandline.c error.c event.c \
+- heap.c hex.c hmacmd5.c hmacsha.c \
++ buffer.c bufferlist.c commandline.c counter.c \
++ error.c event.c heap.c hex.c hmacmd5.c hmacsha.c \
+ httpd.c inet_aton.c iterated_hash.c \
+ lex.c lfsr.c lib.c log.c \
+ md5.c mem.c mutexblock.c \
+Index: contrib/bind9/lib/isc/counter.c
+===================================================================
+--- contrib/bind9/lib/isc/counter.c.orig
++++ contrib/bind9/lib/isc/counter.c
+@@ -0,0 +1,138 @@
++/*
++ * 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.
++ */
++
++/*! \file */
++
++#include
++
++#include
++
++#include
++#include
++#include
++#include
++
++#define COUNTER_MAGIC ISC_MAGIC('C', 'n', 't', 'r')
++#define VALID_COUNTER(r) ISC_MAGIC_VALID(r, COUNTER_MAGIC)
++
++struct isc_counter {
++ unsigned int magic;
++ isc_mem_t *mctx;
++ isc_mutex_t lock;
++ unsigned int references;
++ unsigned int limit;
++ unsigned int used;
++};
++
++isc_result_t
++isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp) {
++ isc_result_t result;
++ isc_counter_t *counter;
++
++ REQUIRE(counterp != NULL && *counterp == NULL);
++
++ counter = isc_mem_get(mctx, sizeof(*counter));
++ if (counter == NULL)
++ return (ISC_R_NOMEMORY);
++
++ result = isc_mutex_init(&counter->lock);
++ if (result != ISC_R_SUCCESS) {
++ isc_mem_put(mctx, counter, sizeof(*counter));
++ return (result);
++ }
++
++ counter->mctx = NULL;
++ isc_mem_attach(mctx, &counter->mctx);
++
++ counter->references = 1;
++ counter->limit = limit;
++ counter->used = 0;
++
++ counter->magic = COUNTER_MAGIC;
++ *counterp = counter;
++ return (ISC_R_SUCCESS);
++}
++
++isc_result_t
++isc_counter_increment(isc_counter_t *counter) {
++ isc_result_t result = ISC_R_SUCCESS;
++
++ LOCK(&counter->lock);
++ counter->used++;
++ if (counter->limit != 0 && counter->used >= counter->limit)
++ result = ISC_R_QUOTA;
++ UNLOCK(&counter->lock);
++
++ return (result);
++}
++
++unsigned int
++isc_counter_used(isc_counter_t *counter) {
++ REQUIRE(VALID_COUNTER(counter));
++
++ return (counter->used);
++}
++
++void
++isc_counter_setlimit(isc_counter_t *counter, int limit) {
++ REQUIRE(VALID_COUNTER(counter));
++
++ LOCK(&counter->lock);
++ counter->limit = limit;
++ UNLOCK(&counter->lock);
++}
++
++void
++isc_counter_attach(isc_counter_t *source, isc_counter_t **targetp) {
++ REQUIRE(VALID_COUNTER(source));
++ REQUIRE(targetp != NULL && *targetp == NULL);
++
++ LOCK(&source->lock);
++ source->references++;
++ INSIST(source->references > 0);
++ UNLOCK(&source->lock);
++
++ *targetp = source;
++}
++
++static void
++destroy(isc_counter_t *counter) {
++ counter->magic = 0;
++ isc_mutex_destroy(&counter->lock);
++ isc_mem_putanddetach(&counter->mctx, counter, sizeof(*counter));
++}
++
++void
++isc_counter_detach(isc_counter_t **counterp) {
++ isc_counter_t *counter;
++ isc_boolean_t want_destroy = ISC_FALSE;
++
++ REQUIRE(counterp != NULL && *counterp != NULL);
++ counter = *counterp;
++ REQUIRE(VALID_COUNTER(counter));
++
++ *counterp = NULL;
++
++ LOCK(&counter->lock);
++ INSIST(counter->references > 0);
++ counter->references--;
++ if (counter->references == 0)
++ want_destroy = ISC_TRUE;
++ UNLOCK(&counter->lock);
++
++ if (want_destroy)
++ destroy(counter);
++}
+Index: contrib/bind9/lib/isc/include/isc/Makefile.in
+===================================================================
+--- contrib/bind9/lib/isc/include/isc/Makefile.in.orig
++++ contrib/bind9/lib/isc/include/isc/Makefile.in
+@@ -13,8 +13,6 @@
+ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ # PERFORMANCE OF THIS SOFTWARE.
+
+-# $Id$
+-
+ srcdir = @srcdir@
+ VPATH = @srcdir@
+ top_srcdir = @top_srcdir@
+@@ -27,7 +25,8 @@
+ # install target below.
+ #
+ HEADERS = app.h assertions.h base64.h bind9.h bitstring.h boolean.h \
+- buffer.h bufferlist.h commandline.h entropy.h error.h event.h \
++ buffer.h bufferlist.h \
++ commandline.h counter.h entropy.h error.h event.h \
+ eventclass.h file.h formatcheck.h fsaccess.h \
+ hash.h heap.h hex.h hmacmd5.h hmacsha.h \
+ httpd.h \
+Index: contrib/bind9/lib/isc/include/isc/counter.h
+===================================================================
+--- contrib/bind9/lib/isc/include/isc/counter.h.orig
++++ contrib/bind9/lib/isc/include/isc/counter.h
+@@ -0,0 +1,90 @@
++/*
++ * 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.
++ */
++
++#ifndef ISC_COUNTER_H
++#define ISC_COUNTER_H 1
++
++/*****
++ ***** Module Info
++ *****/
++
++/*! \file isc/counter.h
++ *
++ * \brief The isc_counter_t object is a simplified version of the
++ * isc_quota_t object; it tracks the consumption of limited
++ * resources, returning an error condition when the quota is
++ * exceeded. However, unlike isc_quota_t, attaching and detaching
++ * from a counter object does not increment or decrement the counter.
++ */
++
++/***
++ *** Imports.
++ ***/
++
++#include
++#include
++#include
++
++/*****
++ ***** Types.
++ *****/
++
++ISC_LANG_BEGINDECLS
++
++isc_result_t
++isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp);
++/*%<
++ * Allocate and initialize a counter object.
++ */
++
++isc_result_t
++isc_counter_increment(isc_counter_t *counter);
++/*%<
++ * Increment the counter.
++ *
++ * If the counter limit is nonzero and has been reached, then
++ * return ISC_R_QUOTA, otherwise ISC_R_SUCCESS. (The counter is
++ * incremented regardless of return value.)
++ */
++
++unsigned int
++isc_counter_used(isc_counter_t *counter);
++/*%<
++ * Return the current counter value.
++ */
++
++void
++isc_counter_setlimit(isc_counter_t *counter, int limit);
++/*%<
++ * Set the counter limit.
++ */
++
++void
++isc_counter_attach(isc_counter_t *source, isc_counter_t **targetp);
++/*%<
++ * Attach to a counter object, increasing its reference counter.
++ */
++
++void
++isc_counter_detach(isc_counter_t **counterp);
++/*%<
++ * Detach (and destroy if reference counter has dropped to zero)
++ * a counter object.
++ */
++
++ISC_LANG_ENDDECLS
++
++#endif /* ISC_COUNTER_H */
+Index: contrib/bind9/lib/isc/include/isc/types.h
+===================================================================
+--- contrib/bind9/lib/isc/include/isc/types.h.orig
++++ contrib/bind9/lib/isc/include/isc/types.h
+@@ -50,6 +50,7 @@
+ typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t; /*%< Buffer List */
+ typedef struct isc_constregion isc_constregion_t; /*%< Const region */
+ typedef struct isc_consttextregion isc_consttextregion_t; /*%< Const Text Region */
++typedef struct isc_counter isc_counter_t; /*%< Counter */
+ typedef struct isc_entropy isc_entropy_t; /*%< Entropy */
+ typedef struct isc_entropysource isc_entropysource_t; /*%< Entropy Source */
+ typedef struct isc_event isc_event_t; /*%< Event */
+Index: contrib/bind9/lib/isccfg/namedconf.c
+===================================================================
+--- contrib/bind9/lib/isccfg/namedconf.c.orig
++++ contrib/bind9/lib/isccfg/namedconf.c
+@@ -15,8 +15,6 @@
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+-/* $Id$ */
+-
+ /*! \file */
+
+ #include
+@@ -1244,6 +1242,8 @@
+ { "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-recursion-queries", &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 },
+Index: lib/bind/isc/Makefile
+===================================================================
+--- lib/bind/isc/Makefile.orig
++++ lib/bind/isc/Makefile
+@@ -28,7 +28,7 @@
+ .PATH: ${SRCDIR}
+ SRCS+= inet_pton.c \
+ assertions.c backtrace.c base32.c base64.c bitstring.c \
+- buffer.c bufferlist.c commandline.c error.c event.c \
++ buffer.c bufferlist.c commandline.c counter.c error.c event.c \
+ fsaccess.c hash.c \
+ heap.c hex.c hmacmd5.c hmacsha.c \
+ httpd.c inet_aton.c \
+@@ -65,6 +65,7 @@
+ ${SRCDIR}/include/isc/buffer.h \
+ ${SRCDIR}/include/isc/bufferlist.h \
+ ${SRCDIR}/include/isc/commandline.h \
++ ${SRCDIR}/include/isc/counter.h \
+ ${SRCDIR}/include/isc/entropy.h \
+ ${SRCDIR}/include/isc/error.h \
+ ${SRCDIR}/include/isc/event.h \
diff --git a/share/security/patches/SA-14:29/bind983.patch.asc b/share/security/patches/SA-14:29/bind983.patch.asc
new file mode 100644
index 0000000000..54972d7fef
--- /dev/null
+++ b/share/security/patches/SA-14:29/bind983.patch.asc
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIcBAABCgAGBQJUiA2RAAoJEO1n7NZdz2rnLB0P/iDqii0FWCXAGG8aareyo79v
+1YxfXKRnWINNEUJGpe6jfOzoThMq6NCuy4Eh7a3r0ourcSTyCPs/fRGch/g/xBG/
+CtMtAb4ApXhlipOSXVCzz/wLXbjkg8OXfJ0Pb1kS3FDDfeC0eVlZmC/nJkQ5pUoS
+5ITFCCPA4hXjIcvujaCv+GeC4m8Bde63ktR3vT8A91n7XYOS/WLl2cUzFx3kH9sR
+Kz6XArnTfN3ou7fPTjodf3yKLKNzCRwijyQACbuJsaEejYqUHN2ek0DZCRJb5C8X
+0dYao1CPmcIQa0732YXHeFvYMmeth7rmb9F+kVPrGxv4Dnc4yaPRxRcXK1yETDNA
+pALEnceF3kYJWEfvU9EeY+3Ku7dSDKW8sPipd5OGDNuyKbUoZLneurZW9Hz0TgCO
+brliFnA++GN87npMBC/Nrrn832MSLtVEznb7PT9ykWFvgrxx+VQolsr2LQy4ek7i
+2ZjRzPR7tNj5Ost6+o7iDhYLoqZRMQ9G0SZSeC+hxoenqMj0Zt5CXm/SyvI/qPNL
+C2N5SB+vTqwbCVmNh51h2QtB2mbwT/1EjTa/5lVWbwwDPtyJekyl9klj14wVTqyv
+ryRcLd/yV4OywVoUxYazSYqM/zRUMEVUEL1/VZWbhvdMWkN+6KcmZbiYn++AEZyX
+t/sNj1W4f0/tjmBvMEL4
+=4PXV
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/SA-14:29/bind984.patch b/share/security/patches/SA-14:29/bind984.patch
new file mode 100644
index 0000000000..af9d6b66b7
--- /dev/null
+++ b/share/security/patches/SA-14:29/bind984.patch
@@ -0,0 +1,956 @@
+Index: contrib/bind9/CHANGES
+===================================================================
+--- contrib/bind9/CHANGES.orig
++++ contrib/bind9/CHANGES
+@@ -1,3 +1,15 @@
++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, and the query limit
++ via the "max-recursion-queries" option. [RT #37580]
++
+ --- 9.8.4-P2 released ---
+
+ 3516. [security] Removed the check for regex.h in configure in order
+Index: contrib/bind9/bin/named/config.c
+===================================================================
+--- contrib/bind9/bin/named/config.c.orig
++++ contrib/bind9/bin/named/config.c
+@@ -15,8 +15,6 @@
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+-/* $Id: config.c,v 1.113.16.2 2011/02/28 01:19:58 tbox Exp $ */
+-
+ /*! \file */
+
+ #include
+@@ -158,6 +156,8 @@
+ dnssec-accept-expired no;\n\
+ clients-per-query 10;\n\
+ max-clients-per-query 100;\n\
++ max-recursion-depth 7;\n\
++ max-recursion-queries 50;\n\
+ zero-no-soa-ttl-cache no;\n\
+ nsec3-test-zone no;\n\
+ allow-new-zones no;\n\
+Index: contrib/bind9/bin/named/query.c
+===================================================================
+--- contrib/bind9/bin/named/query.c.orig
++++ contrib/bind9/bin/named/query.c
+@@ -3755,12 +3755,11 @@
+ 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, NULL,
++ client->task, query_resume, client,
+ rdataset, sigrdataset,
+ &client->query.fetch);
+
+Index: contrib/bind9/bin/named/server.c
+===================================================================
+--- contrib/bind9/bin/named/server.c.orig
++++ contrib/bind9/bin/named/server.c
+@@ -2580,6 +2580,16 @@
+ 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));
++
++ obj = NULL;
++ result = ns_config_get(maps, "max-recursion-queries", &obj);
++ INSIST(result == ISC_R_SUCCESS);
++ dns_resolver_setmaxqueries(view->resolver, cfg_obj_asuint32(obj));
++
+ #ifdef ALLOW_FILTER_AAAA_ON_V4
+ obj = NULL;
+ result = ns_config_get(maps, "filter-aaaa-on-v4", &obj);
+Index: contrib/bind9/lib/dns/adb.c
+===================================================================
+--- contrib/bind9/lib/dns/adb.c.orig
++++ contrib/bind9/lib/dns/adb.c
+@@ -201,6 +201,7 @@
+ unsigned int magic;
+ dns_fetch_t *fetch;
+ dns_rdataset_t rdataset;
++ unsigned int depth;
+ };
+
+ /*%
+@@ -300,8 +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);
++static void clean_finds_at_name(dns_adbname_t *, isc_eventtype_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);
+@@ -309,6 +309,7 @@
+ 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,
++ unsigned int, isc_counter_t *qc,
+ dns_rdatatype_t);
+ static inline void check_exit(dns_adb_t *);
+ static void destroy(dns_adb_t *);
+@@ -2760,6 +2761,19 @@
+ 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, NULL, 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, isc_counter_t *qc,
++ dns_adbfind_t **findp)
++{
+ dns_adbfind_t *find;
+ dns_adbname_t *adbname;
+ int bucket;
+@@ -2990,7 +3004,7 @@
+ * Start V4.
+ */
+ if (WANT_INET(wanted_fetches) &&
+- fetch_name(adbname, start_at_zone,
++ fetch_name(adbname, start_at_zone, depth, qc,
+ dns_rdatatype_a) == ISC_R_SUCCESS) {
+ DP(DEF_LEVEL,
+ "dns_adb_createfind: started A fetch for name %p",
+@@ -3001,7 +3015,7 @@
+ * Start V6.
+ */
+ if (WANT_INET6(wanted_fetches) &&
+- fetch_name(adbname, start_at_zone,
++ fetch_name(adbname, start_at_zone, depth, qc,
+ dns_rdatatype_aaaa) == ISC_R_SUCCESS) {
+ DP(DEF_LEVEL,
+ "dns_adb_createfind: "
+@@ -3744,6 +3758,12 @@
+ 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);
+@@ -3781,9 +3801,8 @@
+ }
+
+ 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, isc_counter_t *qc, dns_rdatatype_t type)
+ {
+ isc_result_t result;
+ dns_adbfetch_t *fetch = NULL;
+@@ -3828,12 +3847,14 @@
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
++ fetch->depth = depth;
+
+- result = dns_resolver_createfetch(adb->view->resolver, &adbname->name,
+- type, name, nameservers, NULL,
+- options, adb->task, fetch_callback,
+- adbname, &fetch->rdataset, NULL,
+- &fetch->fetch);
++ result = dns_resolver_createfetch3(adb->view->resolver, &adbname->name,
++ type, name, nameservers, NULL,
++ NULL, 0, options, depth, qc,
++ adb->task, fetch_callback, adbname,
++ &fetch->rdataset, NULL,
++ &fetch->fetch);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+Index: contrib/bind9/lib/dns/include/dns/adb.h
+===================================================================
+--- contrib/bind9/lib/dns/include/dns/adb.h.orig
++++ contrib/bind9/lib/dns/include/dns/adb.h
+@@ -334,6 +334,13 @@
+ 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, isc_counter_t *qc,
++ 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
+Index: contrib/bind9/lib/dns/include/dns/resolver.h
+===================================================================
+--- contrib/bind9/lib/dns/include/dns/resolver.h.orig
++++ contrib/bind9/lib/dns/include/dns/resolver.h
+@@ -271,6 +271,18 @@
+ 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_counter_t *qc, 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.
+ *
+@@ -572,6 +584,30 @@
+ * \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.
++ */
++
++void
++dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries);
++unsigned int
++dns_resolver_getmaxqueries(dns_resolver_t *resolver);
++/*%
++ * Get and set how many iterative queries will be allowed before
++ * terminating a recursive query.
++ *
++ * Requires:
++ * \li resolver to be valid.
++ */
++
+ ISC_LANG_ENDDECLS
+
+ #endif /* DNS_RESOLVER_H */
+Index: contrib/bind9/lib/dns/resolver.c
+===================================================================
+--- contrib/bind9/lib/dns/resolver.c.orig
++++ contrib/bind9/lib/dns/resolver.c
+@@ -21,6 +21,7 @@
+
+ #include
+
++#include
+ #include
+ #include
+ #include
+@@ -126,6 +127,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.
+ */
+@@ -227,12 +238,13 @@
+ isc_sockaddrlist_t edns;
+ isc_sockaddrlist_t edns512;
+ isc_sockaddrlist_t bad_edns;
+- dns_validator_t *validator;
++ dns_validator_t * validator;
+ ISC_LIST(dns_validator_t) validators;
+ dns_db_t * cache;
+ dns_adb_t * adb;
+ isc_boolean_t ns_ttl_ok;
+ isc_uint32_t ns_ttl;
++ isc_counter_t * qc;
+
+ /*%
+ * The number of events we're waiting for.
+@@ -300,6 +312,7 @@
+ isc_boolean_t timeout;
+ dns_adbaddrinfo_t *addrinfo;
+ isc_sockaddr_t *client;
++ unsigned int depth;
+ };
+
+ #define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!')
+@@ -412,6 +425,8 @@
+ isc_timer_t * spillattimer;
+ isc_boolean_t zero_no_soa_ttl;
+ unsigned int query_timeout;
++ unsigned int maxdepth;
++ unsigned int maxqueries;
+
+ /* Locked by lock. */
+ unsigned int references;
+@@ -1569,6 +1584,7 @@
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_dispatch;
+ }
++
+ fctx->querysent++;
+
+ ISC_LIST_APPEND(fctx->queries, query, link);
+@@ -2210,9 +2226,9 @@
+ */
+ 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 {
++ } else {
+ fctx->findfail++;
+ if (fctx->pending == 0) {
+ /*
+@@ -2241,7 +2257,7 @@
+ else if (want_done)
+ fctx_done(fctx, ISC_R_FAILURE, __LINE__);
+ else if (destroy) {
+- fctx_destroy(fctx);
++ fctx_destroy(fctx);
+ if (bucket_empty)
+ empty_bucket(res);
+ }
+@@ -2495,12 +2511,13 @@
+ * 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, fctx->qc, &find);
+ if (result != ISC_R_SUCCESS) {
+ if (result == DNS_R_ALIAS) {
+ /*
+@@ -2608,6 +2625,14 @@
+
+ res = fctx->res;
+
++ if (fctx->depth > res->maxdepth) {
++ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
++ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
++ "too much NS indirection resolving '%s'",
++ fctx->info);
++ return (DNS_R_SERVFAIL);
++ }
++
+ /*
+ * Forwarders.
+ */
+@@ -3083,6 +3108,16 @@
+ }
+ }
+
++ result = isc_counter_increment(fctx->qc);
++ if (result != ISC_R_SUCCESS) {
++ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
++ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
++ "exceeded max queries resolving '%s'",
++ fctx->info);
++ fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
++ return;
++ }
++
+ result = fctx_query(fctx, addrinfo, fctx->options);
+ if (result != ISC_R_SUCCESS)
+ fctx_done(fctx, result, __LINE__);
+@@ -3181,6 +3216,7 @@
+ isc_mem_put(fctx->mctx, sa, sizeof(*sa));
+ }
+
++ isc_counter_detach(&fctx->qc);
+ isc_timer_detach(&fctx->timer);
+ dns_message_destroy(&fctx->rmessage);
+ dns_message_destroy(&fctx->qmessage);
+@@ -3509,7 +3545,8 @@
+ 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,
++ isc_counter_t *qc, fetchctx_t **fctxp)
+ {
+ fetchctx_t *fctx;
+ isc_result_t result;
+@@ -3531,6 +3568,21 @@
+ fctx = isc_mem_get(mctx, sizeof(*fctx));
+ if (fctx == NULL)
+ return (ISC_R_NOMEMORY);
++
++ fctx->qc = NULL;
++ if (qc != NULL) {
++ isc_counter_attach(qc, &fctx->qc);
++ } else {
++ result = isc_counter_create(res->mctx,
++ res->maxqueries, &fctx->qc);
++ if (result != ISC_R_SUCCESS)
++ goto cleanup_fetch;
++ }
++
++ /*
++ * Make fctx->info point to a copy of a formatted string
++ * "name/type".
++ */
+ dns_name_format(name, buf, sizeof(buf));
+ dns_rdatatype_format(type, typebuf, sizeof(typebuf));
+ strcat(buf, "/"); /* checked */
+@@ -3538,7 +3590,7 @@
+ fctx->info = isc_mem_strdup(mctx, buf);
+ if (fctx->info == NULL) {
+ result = ISC_R_NOMEMORY;
+- goto cleanup_fetch;
++ goto cleanup_counter;
+ }
+ FCTXTRACE("create");
+ dns_name_init(&fctx->name, NULL);
+@@ -3561,6 +3613,7 @@
+ 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);
+@@ -3766,6 +3819,9 @@
+ cleanup_info:
+ isc_mem_free(mctx, fctx->info);
+
++ cleanup_counter:
++ isc_counter_detach(&fctx->qc);
++
+ cleanup_fetch:
+ isc_mem_put(mctx, fctx, sizeof(*fctx));
+
+@@ -5477,7 +5533,7 @@
+ char qbuf[DNS_NAME_FORMATSIZE];
+ char nbuf[DNS_NAME_FORMATSIZE];
+ char tbuf[DNS_RDATATYPE_FORMATSIZE];
+- dns_rdatatype_format(fctx->type, tbuf,
++ dns_rdatatype_format(type, tbuf,
+ sizeof(tbuf));
+ dns_name_format(name, nbuf,
+ sizeof(nbuf));
+@@ -5486,7 +5542,7 @@
+ log_formerr(fctx,
+ "unrelated %s %s in "
+ "%s authority section",
+- tbuf, qbuf, nbuf);
++ tbuf, nbuf, qbuf);
+ return (DNS_R_FORMERR);
+ }
+ if (type == dns_rdatatype_ns) {
+@@ -7528,6 +7584,8 @@
+ res->query_timeout = DEFAULT_QUERY_TIMEOUT;
+ res->ndisps = 0;
+ res->nextdisp = 0; /* meaningless at this point, but init it */
++ res->maxdepth = DEFAULT_RECURSION_DEPTH;
++ res->maxqueries = DEFAULT_MAX_QUERIES;
+ res->nbuckets = ntasks;
+ res->activebuckets = ntasks;
+ res->buckets = isc_mem_get(view->mctx,
+@@ -7967,9 +8025,9 @@
+ 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, NULL, task, action, arg,
+ rdataset, sigrdataset, fetchp));
+ }
+
+@@ -7985,6 +8043,25 @@
+ dns_rdataset_t *sigrdataset,
+ dns_fetch_t **fetchp)
+ {
++ return (dns_resolver_createfetch3(res, name, type, domain,
++ nameservers, forwarders, client, id,
++ options, 0, NULL, 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_counter_t *qc, 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;
+@@ -8071,11 +8148,12 @@
+
+ if (fctx == NULL) {
+ result = fctx_create(res, name, type, domain, nameservers,
+- options, bucketnum, &fctx);
++ options, bucketnum, depth, qc, &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);
+@@ -8847,3 +8925,27 @@
+
+ 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);
++}
++
++void
++dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries) {
++ REQUIRE(VALID_RESOLVER(resolver));
++ resolver->maxqueries = queries;
++}
++
++unsigned int
++dns_resolver_getmaxqueries(dns_resolver_t *resolver) {
++ REQUIRE(VALID_RESOLVER(resolver));
++ return (resolver->maxqueries);
++}
+Index: contrib/bind9/lib/export/isc/Makefile.in
+===================================================================
+--- contrib/bind9/lib/export/isc/Makefile.in.orig
++++ contrib/bind9/lib/export/isc/Makefile.in
+@@ -63,7 +63,7 @@
+ # Alphabetically
+ OBJS = @ISC_EXTRA_OBJS@ \
+ assertions.@O@ backtrace.@O@ backtrace-emptytbl.@O@ base32.@O@ \
+- base64.@O@ buffer.@O@ bufferlist.@O@ \
++ base64.@O@ buffer.@O@ bufferlist.@O@ counter.@O@ \
+ error.@O@ event.@O@ \
+ hash.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \
+ inet_aton.@O@ iterated_hash.@O@ lex.@O@ lfsr.@O@ log.@O@ \
+@@ -86,7 +86,7 @@
+
+ SRCS = @ISC_EXTRA_SRCS@ \
+ assertions.c backtrace.c backtrace-emptytbl.c base32.c \
+- base64.c buffer.c bufferlist.c \
++ base64.c buffer.c bufferlist.c counter.c \
+ error.c event.c \
+ hash.c hex.c hmacmd5.c hmacsha.c \
+ inet_aton.c iterated_hash.c lex.c log.c lfsr.c \
+Index: contrib/bind9/lib/isc/Makefile.in
+===================================================================
+--- contrib/bind9/lib/isc/Makefile.in.orig
++++ contrib/bind9/lib/isc/Makefile.in
+@@ -13,8 +13,6 @@
+ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ # PERFORMANCE OF THIS SOFTWARE.
+
+-# $Id$
+-
+ srcdir = @srcdir@
+ VPATH = @srcdir@
+ top_srcdir = @top_srcdir@
+@@ -53,7 +51,7 @@
+ OBJS = @ISC_EXTRA_OBJS@ \
+ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \
+ bitstring.@O@ buffer.@O@ bufferlist.@O@ commandline.@O@ \
+- error.@O@ event.@O@ \
++ counter.@O@ error.@O@ event.@O@ \
+ hash.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \
+ httpd.@O@ inet_aton.@O@ iterated_hash.@O@ \
+ lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \
+@@ -69,8 +67,8 @@
+ # Alphabetically
+ SRCS = @ISC_EXTRA_SRCS@ \
+ assertions.c backtrace.c base32.c base64.c bitstring.c \
+- buffer.c bufferlist.c commandline.c error.c event.c \
+- heap.c hex.c hmacmd5.c hmacsha.c \
++ buffer.c bufferlist.c commandline.c counter.c \
++ error.c event.c heap.c hex.c hmacmd5.c hmacsha.c \
+ httpd.c inet_aton.c iterated_hash.c \
+ lex.c lfsr.c lib.c log.c \
+ md5.c mem.c mutexblock.c \
+Index: contrib/bind9/lib/isc/counter.c
+===================================================================
+--- contrib/bind9/lib/isc/counter.c.orig
++++ contrib/bind9/lib/isc/counter.c
+@@ -0,0 +1,138 @@
++/*
++ * 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.
++ */
++
++/*! \file */
++
++#include
++
++#include
++
++#include
++#include
++#include
++#include
++
++#define COUNTER_MAGIC ISC_MAGIC('C', 'n', 't', 'r')
++#define VALID_COUNTER(r) ISC_MAGIC_VALID(r, COUNTER_MAGIC)
++
++struct isc_counter {
++ unsigned int magic;
++ isc_mem_t *mctx;
++ isc_mutex_t lock;
++ unsigned int references;
++ unsigned int limit;
++ unsigned int used;
++};
++
++isc_result_t
++isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp) {
++ isc_result_t result;
++ isc_counter_t *counter;
++
++ REQUIRE(counterp != NULL && *counterp == NULL);
++
++ counter = isc_mem_get(mctx, sizeof(*counter));
++ if (counter == NULL)
++ return (ISC_R_NOMEMORY);
++
++ result = isc_mutex_init(&counter->lock);
++ if (result != ISC_R_SUCCESS) {
++ isc_mem_put(mctx, counter, sizeof(*counter));
++ return (result);
++ }
++
++ counter->mctx = NULL;
++ isc_mem_attach(mctx, &counter->mctx);
++
++ counter->references = 1;
++ counter->limit = limit;
++ counter->used = 0;
++
++ counter->magic = COUNTER_MAGIC;
++ *counterp = counter;
++ return (ISC_R_SUCCESS);
++}
++
++isc_result_t
++isc_counter_increment(isc_counter_t *counter) {
++ isc_result_t result = ISC_R_SUCCESS;
++
++ LOCK(&counter->lock);
++ counter->used++;
++ if (counter->limit != 0 && counter->used >= counter->limit)
++ result = ISC_R_QUOTA;
++ UNLOCK(&counter->lock);
++
++ return (result);
++}
++
++unsigned int
++isc_counter_used(isc_counter_t *counter) {
++ REQUIRE(VALID_COUNTER(counter));
++
++ return (counter->used);
++}
++
++void
++isc_counter_setlimit(isc_counter_t *counter, int limit) {
++ REQUIRE(VALID_COUNTER(counter));
++
++ LOCK(&counter->lock);
++ counter->limit = limit;
++ UNLOCK(&counter->lock);
++}
++
++void
++isc_counter_attach(isc_counter_t *source, isc_counter_t **targetp) {
++ REQUIRE(VALID_COUNTER(source));
++ REQUIRE(targetp != NULL && *targetp == NULL);
++
++ LOCK(&source->lock);
++ source->references++;
++ INSIST(source->references > 0);
++ UNLOCK(&source->lock);
++
++ *targetp = source;
++}
++
++static void
++destroy(isc_counter_t *counter) {
++ counter->magic = 0;
++ isc_mutex_destroy(&counter->lock);
++ isc_mem_putanddetach(&counter->mctx, counter, sizeof(*counter));
++}
++
++void
++isc_counter_detach(isc_counter_t **counterp) {
++ isc_counter_t *counter;
++ isc_boolean_t want_destroy = ISC_FALSE;
++
++ REQUIRE(counterp != NULL && *counterp != NULL);
++ counter = *counterp;
++ REQUIRE(VALID_COUNTER(counter));
++
++ *counterp = NULL;
++
++ LOCK(&counter->lock);
++ INSIST(counter->references > 0);
++ counter->references--;
++ if (counter->references == 0)
++ want_destroy = ISC_TRUE;
++ UNLOCK(&counter->lock);
++
++ if (want_destroy)
++ destroy(counter);
++}
+Index: contrib/bind9/lib/isc/include/isc/Makefile.in
+===================================================================
+--- contrib/bind9/lib/isc/include/isc/Makefile.in.orig
++++ contrib/bind9/lib/isc/include/isc/Makefile.in
+@@ -13,8 +13,6 @@
+ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ # PERFORMANCE OF THIS SOFTWARE.
+
+-# $Id$
+-
+ srcdir = @srcdir@
+ VPATH = @srcdir@
+ top_srcdir = @top_srcdir@
+@@ -27,7 +25,8 @@
+ # install target below.
+ #
+ HEADERS = app.h assertions.h base64.h bind9.h bitstring.h boolean.h \
+- buffer.h bufferlist.h commandline.h entropy.h error.h event.h \
++ buffer.h bufferlist.h \
++ commandline.h counter.h entropy.h error.h event.h \
+ eventclass.h file.h formatcheck.h fsaccess.h \
+ hash.h heap.h hex.h hmacmd5.h hmacsha.h \
+ httpd.h \
+Index: contrib/bind9/lib/isc/include/isc/counter.h
+===================================================================
+--- contrib/bind9/lib/isc/include/isc/counter.h.orig
++++ contrib/bind9/lib/isc/include/isc/counter.h
+@@ -0,0 +1,90 @@
++/*
++ * 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.
++ */
++
++#ifndef ISC_COUNTER_H
++#define ISC_COUNTER_H 1
++
++/*****
++ ***** Module Info
++ *****/
++
++/*! \file isc/counter.h
++ *
++ * \brief The isc_counter_t object is a simplified version of the
++ * isc_quota_t object; it tracks the consumption of limited
++ * resources, returning an error condition when the quota is
++ * exceeded. However, unlike isc_quota_t, attaching and detaching
++ * from a counter object does not increment or decrement the counter.
++ */
++
++/***
++ *** Imports.
++ ***/
++
++#include
++#include
++#include
++
++/*****
++ ***** Types.
++ *****/
++
++ISC_LANG_BEGINDECLS
++
++isc_result_t
++isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp);
++/*%<
++ * Allocate and initialize a counter object.
++ */
++
++isc_result_t
++isc_counter_increment(isc_counter_t *counter);
++/*%<
++ * Increment the counter.
++ *
++ * If the counter limit is nonzero and has been reached, then
++ * return ISC_R_QUOTA, otherwise ISC_R_SUCCESS. (The counter is
++ * incremented regardless of return value.)
++ */
++
++unsigned int
++isc_counter_used(isc_counter_t *counter);
++/*%<
++ * Return the current counter value.
++ */
++
++void
++isc_counter_setlimit(isc_counter_t *counter, int limit);
++/*%<
++ * Set the counter limit.
++ */
++
++void
++isc_counter_attach(isc_counter_t *source, isc_counter_t **targetp);
++/*%<
++ * Attach to a counter object, increasing its reference counter.
++ */
++
++void
++isc_counter_detach(isc_counter_t **counterp);
++/*%<
++ * Detach (and destroy if reference counter has dropped to zero)
++ * a counter object.
++ */
++
++ISC_LANG_ENDDECLS
++
++#endif /* ISC_COUNTER_H */
+Index: contrib/bind9/lib/isc/include/isc/types.h
+===================================================================
+--- contrib/bind9/lib/isc/include/isc/types.h.orig
++++ contrib/bind9/lib/isc/include/isc/types.h
+@@ -50,6 +50,7 @@
+ typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t; /*%< Buffer List */
+ typedef struct isc_constregion isc_constregion_t; /*%< Const region */
+ typedef struct isc_consttextregion isc_consttextregion_t; /*%< Const Text Region */
++typedef struct isc_counter isc_counter_t; /*%< Counter */
+ typedef struct isc_entropy isc_entropy_t; /*%< Entropy */
+ typedef struct isc_entropysource isc_entropysource_t; /*%< Entropy Source */
+ typedef struct isc_event isc_event_t; /*%< Event */
+Index: contrib/bind9/lib/isccfg/namedconf.c
+===================================================================
+--- contrib/bind9/lib/isccfg/namedconf.c.orig
++++ contrib/bind9/lib/isccfg/namedconf.c
+@@ -15,8 +15,6 @@
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+-/* $Id$ */
+-
+ /*! \file */
+
+ #include
+@@ -1348,6 +1346,8 @@
+ { "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-recursion-queries", &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 },
+Index: lib/bind/isc/Makefile
+===================================================================
+--- lib/bind/isc/Makefile.orig
++++ lib/bind/isc/Makefile
+@@ -28,7 +28,7 @@
+ .PATH: ${SRCDIR}
+ SRCS+= inet_pton.c \
+ assertions.c backtrace.c base32.c base64.c bitstring.c \
+- buffer.c bufferlist.c commandline.c error.c event.c \
++ buffer.c bufferlist.c commandline.c counter.c error.c event.c \
+ fsaccess.c hash.c \
+ heap.c hex.c hmacmd5.c hmacsha.c \
+ httpd.c inet_aton.c \
+@@ -65,6 +65,7 @@
+ ${SRCDIR}/include/isc/buffer.h \
+ ${SRCDIR}/include/isc/bufferlist.h \
+ ${SRCDIR}/include/isc/commandline.h \
++ ${SRCDIR}/include/isc/counter.h \
+ ${SRCDIR}/include/isc/entropy.h \
+ ${SRCDIR}/include/isc/error.h \
+ ${SRCDIR}/include/isc/event.h \
diff --git a/share/security/patches/SA-14:29/bind984.patch.asc b/share/security/patches/SA-14:29/bind984.patch.asc
new file mode 100644
index 0000000000..79861cd730
--- /dev/null
+++ b/share/security/patches/SA-14:29/bind984.patch.asc
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIcBAABCgAGBQJUiA2RAAoJEO1n7NZdz2rn4HgQAOookP9oIbPnYVRpgAoqoa9x
+aRrOju3+P8lDKCoQDrdTaFEIwbMwGjANbUOM91zG9NaZLAX/qdGFrFEPIx4hI74c
+034Byt/gBUsZxeXF4kAzdvV4LDqOOt38bcph6SX869gxF+BXvPLdXOKOvIKJ8ZWx
+J0Yg5FcBEpg0pgQR+LqHo6G0fOVI3BqOLgoj/o1JGq3SkuYwtJink8fd/Ejgtd/F
+OsK5mHnsCmDhG/aMnPP0rM1aycgRoTjlVIi4apRYyS3ZN31yQeKgEgqHBfmsfzwz
+7NBjwKaF8hu5YwfBKv1h13mlNgghPDBttSzFmhB4Cf6ScP53AZ23zErI78gNTVIe
+RKtPns5BmntVDaX8g+0sO1DPch7SujM3hSRfwWV/bHY864EOf3hvIV8yXBThXP00
+9Fd27JEqDFEaEHGIEf2ATxLVm6d+QH4hwPVHKiSAvONQs0uBr0/4mliZv1HFdT3M
+6wAdvgPT3OV8hCqmqRUt1GyUxB6GVBEZd7lcvekNowYi+AT4Jo0gojkU22E7+Dlt
+FNCqOpahZrBlS613ywZ4qZQegeVvvR23z7s1iYYmpAnn9NlkauPib2HHTpGRmgBl
+huD1GmqvvZxT3jsW2cxHdMvYZg4HkBQO4wX9icoSO2nLrV9pYWtlMimI1CcjF9Ah
+AirWWyKBuzyceh4qsL/U
+=MvL5
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/SA-14:29/bind987.patch b/share/security/patches/SA-14:29/bind987.patch
new file mode 100644
index 0000000000..f6e3b6b9f4
--- /dev/null
+++ b/share/security/patches/SA-14:29/bind987.patch
@@ -0,0 +1,956 @@
+Index: contrib/bind9/CHANGES
+===================================================================
+--- contrib/bind9/CHANGES.orig
++++ contrib/bind9/CHANGES
+@@ -1,3 +1,15 @@
++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, and the query limit
++ via the "max-recursion-queries" option. [RT #37580]
++
+ --- 9.8.7 released ---
+
+ --- 9.8.7rc2 released ---
+Index: contrib/bind9/bin/named/config.c
+===================================================================
+--- contrib/bind9/bin/named/config.c.orig
++++ contrib/bind9/bin/named/config.c
+@@ -15,8 +15,6 @@
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+-/* $Id: config.c,v 1.113.16.2 2011/02/28 01:19:58 tbox Exp $ */
+-
+ /*! \file */
+
+ #include
+@@ -159,6 +157,8 @@
+ dnssec-accept-expired no;\n\
+ clients-per-query 10;\n\
+ max-clients-per-query 100;\n\
++ max-recursion-depth 7;\n\
++ max-recursion-queries 50;\n\
+ zero-no-soa-ttl-cache no;\n\
+ nsec3-test-zone no;\n\
+ allow-new-zones no;\n\
+Index: contrib/bind9/bin/named/query.c
+===================================================================
+--- contrib/bind9/bin/named/query.c.orig
++++ contrib/bind9/bin/named/query.c
+@@ -3802,12 +3802,11 @@
+ 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, NULL,
++ client->task, query_resume, client,
+ rdataset, sigrdataset,
+ &client->query.fetch);
+
+Index: contrib/bind9/bin/named/server.c
+===================================================================
+--- contrib/bind9/bin/named/server.c.orig
++++ contrib/bind9/bin/named/server.c
+@@ -2949,6 +2949,16 @@
+ 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));
++
++ obj = NULL;
++ result = ns_config_get(maps, "max-recursion-queries", &obj);
++ INSIST(result == ISC_R_SUCCESS);
++ dns_resolver_setmaxqueries(view->resolver, cfg_obj_asuint32(obj));
++
+ #ifdef ALLOW_FILTER_AAAA_ON_V4
+ obj = NULL;
+ result = ns_config_get(maps, "filter-aaaa-on-v4", &obj);
+Index: contrib/bind9/lib/dns/adb.c
+===================================================================
+--- contrib/bind9/lib/dns/adb.c.orig
++++ contrib/bind9/lib/dns/adb.c
+@@ -201,6 +201,7 @@
+ unsigned int magic;
+ dns_fetch_t *fetch;
+ dns_rdataset_t rdataset;
++ unsigned int depth;
+ };
+
+ /*%
+@@ -300,8 +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);
++static void clean_finds_at_name(dns_adbname_t *, isc_eventtype_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);
+@@ -309,6 +309,7 @@
+ 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,
++ unsigned int, isc_counter_t *qc,
+ dns_rdatatype_t);
+ static inline void check_exit(dns_adb_t *);
+ static void destroy(dns_adb_t *);
+@@ -2770,6 +2771,19 @@
+ 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, NULL, 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, isc_counter_t *qc,
++ dns_adbfind_t **findp)
++{
+ dns_adbfind_t *find;
+ dns_adbname_t *adbname;
+ int bucket;
+@@ -3000,7 +3014,7 @@
+ * Start V4.
+ */
+ if (WANT_INET(wanted_fetches) &&
+- fetch_name(adbname, start_at_zone,
++ fetch_name(adbname, start_at_zone, depth, qc,
+ dns_rdatatype_a) == ISC_R_SUCCESS) {
+ DP(DEF_LEVEL,
+ "dns_adb_createfind: started A fetch for name %p",
+@@ -3011,7 +3025,7 @@
+ * Start V6.
+ */
+ if (WANT_INET6(wanted_fetches) &&
+- fetch_name(adbname, start_at_zone,
++ fetch_name(adbname, start_at_zone, depth, qc,
+ dns_rdatatype_aaaa) == ISC_R_SUCCESS) {
+ DP(DEF_LEVEL,
+ "dns_adb_createfind: "
+@@ -3754,6 +3768,12 @@
+ 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);
+@@ -3791,9 +3811,8 @@
+ }
+
+ 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, isc_counter_t *qc, dns_rdatatype_t type)
+ {
+ isc_result_t result;
+ dns_adbfetch_t *fetch = NULL;
+@@ -3838,12 +3857,14 @@
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
++ fetch->depth = depth;
+
+- result = dns_resolver_createfetch(adb->view->resolver, &adbname->name,
+- type, name, nameservers, NULL,
+- options, adb->task, fetch_callback,
+- adbname, &fetch->rdataset, NULL,
+- &fetch->fetch);
++ result = dns_resolver_createfetch3(adb->view->resolver, &adbname->name,
++ type, name, nameservers, NULL,
++ NULL, 0, options, depth, qc,
++ adb->task, fetch_callback, adbname,
++ &fetch->rdataset, NULL,
++ &fetch->fetch);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+Index: contrib/bind9/lib/dns/include/dns/adb.h
+===================================================================
+--- contrib/bind9/lib/dns/include/dns/adb.h.orig
++++ contrib/bind9/lib/dns/include/dns/adb.h
+@@ -334,6 +334,13 @@
+ 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, isc_counter_t *qc,
++ 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
+Index: contrib/bind9/lib/dns/include/dns/resolver.h
+===================================================================
+--- contrib/bind9/lib/dns/include/dns/resolver.h.orig
++++ contrib/bind9/lib/dns/include/dns/resolver.h
+@@ -271,6 +271,18 @@
+ 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_counter_t *qc, 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.
+ *
+@@ -572,6 +584,30 @@
+ * \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.
++ */
++
++void
++dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries);
++unsigned int
++dns_resolver_getmaxqueries(dns_resolver_t *resolver);
++/*%
++ * Get and set how many iterative queries will be allowed before
++ * terminating a recursive query.
++ *
++ * Requires:
++ * \li resolver to be valid.
++ */
++
+ ISC_LANG_ENDDECLS
+
+ #endif /* DNS_RESOLVER_H */
+Index: contrib/bind9/lib/dns/resolver.c
+===================================================================
+--- contrib/bind9/lib/dns/resolver.c.orig
++++ contrib/bind9/lib/dns/resolver.c
+@@ -22,6 +22,7 @@
+ #include
+
+ #include
++#include
+ #include
+ #include
+ #include
+@@ -130,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.
+ */
+@@ -232,12 +243,13 @@
+ isc_sockaddrlist_t edns;
+ isc_sockaddrlist_t edns512;
+ isc_sockaddrlist_t bad_edns;
+- dns_validator_t *validator;
++ dns_validator_t * validator;
+ ISC_LIST(dns_validator_t) validators;
+ dns_db_t * cache;
+ dns_adb_t * adb;
+ isc_boolean_t ns_ttl_ok;
+ isc_uint32_t ns_ttl;
++ isc_counter_t * qc;
+
+ /*%
+ * The number of events we're waiting for.
+@@ -305,6 +317,7 @@
+ isc_boolean_t timeout;
+ dns_adbaddrinfo_t *addrinfo;
+ isc_sockaddr_t *client;
++ unsigned int depth;
+ };
+
+ #define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!')
+@@ -417,6 +430,8 @@
+ isc_timer_t * spillattimer;
+ isc_boolean_t zero_no_soa_ttl;
+ unsigned int query_timeout;
++ unsigned int maxdepth;
++ unsigned int maxqueries;
+
+ /* Locked by lock. */
+ unsigned int references;
+@@ -1530,6 +1545,7 @@
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_dispatch;
+ }
++
+ fctx->querysent++;
+
+ ISC_LIST_APPEND(fctx->queries, query, link);
+@@ -2180,9 +2196,9 @@
+ */
+ 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 {
++ } else {
+ fctx->findfail++;
+ if (fctx->pending == 0) {
+ /*
+@@ -2211,7 +2227,7 @@
+ else if (want_done)
+ fctx_done(fctx, ISC_R_FAILURE, __LINE__);
+ else if (destroy) {
+- fctx_destroy(fctx);
++ fctx_destroy(fctx);
+ if (bucket_empty)
+ empty_bucket(res);
+ }
+@@ -2465,12 +2481,13 @@
+ * 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, fctx->qc, &find);
+ if (result != ISC_R_SUCCESS) {
+ if (result == DNS_R_ALIAS) {
+ /*
+@@ -2578,6 +2595,14 @@
+
+ res = fctx->res;
+
++ if (fctx->depth > res->maxdepth) {
++ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
++ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
++ "too much NS indirection resolving '%s'",
++ fctx->info);
++ return (DNS_R_SERVFAIL);
++ }
++
+ /*
+ * Forwarders.
+ */
+@@ -3053,6 +3078,16 @@
+ }
+ }
+
++ result = isc_counter_increment(fctx->qc);
++ if (result != ISC_R_SUCCESS) {
++ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
++ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
++ "exceeded max queries resolving '%s'",
++ fctx->info);
++ fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
++ return;
++ }
++
+ result = fctx_query(fctx, addrinfo, fctx->options);
+ if (result != ISC_R_SUCCESS)
+ fctx_done(fctx, result, __LINE__);
+@@ -3151,6 +3186,7 @@
+ isc_mem_put(fctx->mctx, sa, sizeof(*sa));
+ }
+
++ isc_counter_detach(&fctx->qc);
+ isc_timer_detach(&fctx->timer);
+ dns_message_destroy(&fctx->rmessage);
+ dns_message_destroy(&fctx->qmessage);
+@@ -3479,7 +3515,8 @@
+ 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,
++ isc_counter_t *qc, fetchctx_t **fctxp)
+ {
+ fetchctx_t *fctx;
+ isc_result_t result;
+@@ -3501,6 +3538,21 @@
+ fctx = isc_mem_get(mctx, sizeof(*fctx));
+ if (fctx == NULL)
+ return (ISC_R_NOMEMORY);
++
++ fctx->qc = NULL;
++ if (qc != NULL) {
++ isc_counter_attach(qc, &fctx->qc);
++ } else {
++ result = isc_counter_create(res->mctx,
++ res->maxqueries, &fctx->qc);
++ if (result != ISC_R_SUCCESS)
++ goto cleanup_fetch;
++ }
++
++ /*
++ * Make fctx->info point to a copy of a formatted string
++ * "name/type".
++ */
+ dns_name_format(name, buf, sizeof(buf));
+ dns_rdatatype_format(type, typebuf, sizeof(typebuf));
+ strcat(buf, "/"); /* checked */
+@@ -3508,7 +3560,7 @@
+ fctx->info = isc_mem_strdup(mctx, buf);
+ if (fctx->info == NULL) {
+ result = ISC_R_NOMEMORY;
+- goto cleanup_fetch;
++ goto cleanup_counter;
+ }
+ FCTXTRACE("create");
+ dns_name_init(&fctx->name, NULL);
+@@ -3531,6 +3583,7 @@
+ 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);
+@@ -3738,6 +3791,9 @@
+ cleanup_info:
+ isc_mem_free(mctx, fctx->info);
+
++ cleanup_counter:
++ isc_counter_detach(&fctx->qc);
++
+ cleanup_fetch:
+ isc_mem_put(mctx, fctx, sizeof(*fctx));
+
+@@ -5651,7 +5707,7 @@
+ char qbuf[DNS_NAME_FORMATSIZE];
+ char nbuf[DNS_NAME_FORMATSIZE];
+ char tbuf[DNS_RDATATYPE_FORMATSIZE];
+- dns_rdatatype_format(fctx->type, tbuf,
++ dns_rdatatype_format(type, tbuf,
+ sizeof(tbuf));
+ dns_name_format(name, nbuf,
+ sizeof(nbuf));
+@@ -5660,7 +5716,7 @@
+ log_formerr(fctx,
+ "unrelated %s %s in "
+ "%s authority section",
+- tbuf, qbuf, nbuf);
++ tbuf, nbuf, qbuf);
+ return (DNS_R_FORMERR);
+ }
+ if (type == dns_rdatatype_ns) {
+@@ -7725,6 +7781,8 @@
+ res->query_timeout = DEFAULT_QUERY_TIMEOUT;
+ res->ndisps = 0;
+ res->nextdisp = 0; /* meaningless at this point, but init it */
++ res->maxdepth = DEFAULT_RECURSION_DEPTH;
++ res->maxqueries = DEFAULT_MAX_QUERIES;
+ res->nbuckets = ntasks;
+ res->activebuckets = ntasks;
+ res->buckets = isc_mem_get(view->mctx,
+@@ -8164,9 +8222,9 @@
+ 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, NULL, task, action, arg,
+ rdataset, sigrdataset, fetchp));
+ }
+
+@@ -8182,6 +8240,25 @@
+ dns_rdataset_t *sigrdataset,
+ dns_fetch_t **fetchp)
+ {
++ return (dns_resolver_createfetch3(res, name, type, domain,
++ nameservers, forwarders, client, id,
++ options, 0, NULL, 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_counter_t *qc, 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;
+@@ -8268,11 +8345,12 @@
+
+ if (fctx == NULL) {
+ result = fctx_create(res, name, type, domain, nameservers,
+- options, bucketnum, &fctx);
++ options, bucketnum, depth, qc, &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);
+@@ -9044,3 +9122,27 @@
+
+ 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);
++}
++
++void
++dns_resolver_setmaxqueries(dns_resolver_t *resolver, unsigned int queries) {
++ REQUIRE(VALID_RESOLVER(resolver));
++ resolver->maxqueries = queries;
++}
++
++unsigned int
++dns_resolver_getmaxqueries(dns_resolver_t *resolver) {
++ REQUIRE(VALID_RESOLVER(resolver));
++ return (resolver->maxqueries);
++}
+Index: contrib/bind9/lib/export/isc/Makefile.in
+===================================================================
+--- contrib/bind9/lib/export/isc/Makefile.in.orig
++++ contrib/bind9/lib/export/isc/Makefile.in
+@@ -63,7 +63,7 @@
+ # Alphabetically
+ OBJS = @ISC_EXTRA_OBJS@ \
+ assertions.@O@ backtrace.@O@ backtrace-emptytbl.@O@ base32.@O@ \
+- base64.@O@ buffer.@O@ bufferlist.@O@ \
++ base64.@O@ buffer.@O@ bufferlist.@O@ counter.@O@ \
+ error.@O@ event.@O@ \
+ hash.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \
+ inet_aton.@O@ iterated_hash.@O@ lex.@O@ lfsr.@O@ log.@O@ \
+@@ -85,7 +85,7 @@
+
+ SRCS = @ISC_EXTRA_SRCS@ \
+ assertions.c backtrace.c backtrace-emptytbl.c base32.c \
+- base64.c buffer.c bufferlist.c \
++ base64.c buffer.c bufferlist.c counter.c \
+ error.c event.c \
+ hash.c hex.c hmacmd5.c hmacsha.c \
+ inet_aton.c iterated_hash.c lex.c log.c lfsr.c \
+Index: contrib/bind9/lib/isc/Makefile.in
+===================================================================
+--- contrib/bind9/lib/isc/Makefile.in.orig
++++ contrib/bind9/lib/isc/Makefile.in
+@@ -13,8 +13,6 @@
+ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ # PERFORMANCE OF THIS SOFTWARE.
+
+-# $Id$
+-
+ srcdir = @srcdir@
+ VPATH = @srcdir@
+ top_srcdir = @top_srcdir@
+@@ -53,7 +51,7 @@
+ OBJS = @ISC_EXTRA_OBJS@ \
+ assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \
+ bitstring.@O@ buffer.@O@ bufferlist.@O@ commandline.@O@ \
+- error.@O@ event.@O@ \
++ counter.@O@ error.@O@ event.@O@ \
+ hash.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \
+ httpd.@O@ inet_aton.@O@ iterated_hash.@O@ \
+ lex.@O@ lfsr.@O@ lib.@O@ log.@O@ \
+@@ -70,8 +68,8 @@
+ # Alphabetically
+ SRCS = @ISC_EXTRA_SRCS@ \
+ assertions.c backtrace.c base32.c base64.c bitstring.c \
+- buffer.c bufferlist.c commandline.c error.c event.c \
+- heap.c hex.c hmacmd5.c hmacsha.c \
++ buffer.c bufferlist.c commandline.c counter.c \
++ error.c event.c heap.c hex.c hmacmd5.c hmacsha.c \
+ httpd.c inet_aton.c iterated_hash.c \
+ lex.c lfsr.c lib.c log.c \
+ md5.c mem.c mutexblock.c \
+Index: contrib/bind9/lib/isc/counter.c
+===================================================================
+--- contrib/bind9/lib/isc/counter.c.orig
++++ contrib/bind9/lib/isc/counter.c
+@@ -0,0 +1,138 @@
++/*
++ * 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.
++ */
++
++/*! \file */
++
++#include
++
++#include
++
++#include
++#include
++#include
++#include
++
++#define COUNTER_MAGIC ISC_MAGIC('C', 'n', 't', 'r')
++#define VALID_COUNTER(r) ISC_MAGIC_VALID(r, COUNTER_MAGIC)
++
++struct isc_counter {
++ unsigned int magic;
++ isc_mem_t *mctx;
++ isc_mutex_t lock;
++ unsigned int references;
++ unsigned int limit;
++ unsigned int used;
++};
++
++isc_result_t
++isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp) {
++ isc_result_t result;
++ isc_counter_t *counter;
++
++ REQUIRE(counterp != NULL && *counterp == NULL);
++
++ counter = isc_mem_get(mctx, sizeof(*counter));
++ if (counter == NULL)
++ return (ISC_R_NOMEMORY);
++
++ result = isc_mutex_init(&counter->lock);
++ if (result != ISC_R_SUCCESS) {
++ isc_mem_put(mctx, counter, sizeof(*counter));
++ return (result);
++ }
++
++ counter->mctx = NULL;
++ isc_mem_attach(mctx, &counter->mctx);
++
++ counter->references = 1;
++ counter->limit = limit;
++ counter->used = 0;
++
++ counter->magic = COUNTER_MAGIC;
++ *counterp = counter;
++ return (ISC_R_SUCCESS);
++}
++
++isc_result_t
++isc_counter_increment(isc_counter_t *counter) {
++ isc_result_t result = ISC_R_SUCCESS;
++
++ LOCK(&counter->lock);
++ counter->used++;
++ if (counter->limit != 0 && counter->used >= counter->limit)
++ result = ISC_R_QUOTA;
++ UNLOCK(&counter->lock);
++
++ return (result);
++}
++
++unsigned int
++isc_counter_used(isc_counter_t *counter) {
++ REQUIRE(VALID_COUNTER(counter));
++
++ return (counter->used);
++}
++
++void
++isc_counter_setlimit(isc_counter_t *counter, int limit) {
++ REQUIRE(VALID_COUNTER(counter));
++
++ LOCK(&counter->lock);
++ counter->limit = limit;
++ UNLOCK(&counter->lock);
++}
++
++void
++isc_counter_attach(isc_counter_t *source, isc_counter_t **targetp) {
++ REQUIRE(VALID_COUNTER(source));
++ REQUIRE(targetp != NULL && *targetp == NULL);
++
++ LOCK(&source->lock);
++ source->references++;
++ INSIST(source->references > 0);
++ UNLOCK(&source->lock);
++
++ *targetp = source;
++}
++
++static void
++destroy(isc_counter_t *counter) {
++ counter->magic = 0;
++ isc_mutex_destroy(&counter->lock);
++ isc_mem_putanddetach(&counter->mctx, counter, sizeof(*counter));
++}
++
++void
++isc_counter_detach(isc_counter_t **counterp) {
++ isc_counter_t *counter;
++ isc_boolean_t want_destroy = ISC_FALSE;
++
++ REQUIRE(counterp != NULL && *counterp != NULL);
++ counter = *counterp;
++ REQUIRE(VALID_COUNTER(counter));
++
++ *counterp = NULL;
++
++ LOCK(&counter->lock);
++ INSIST(counter->references > 0);
++ counter->references--;
++ if (counter->references == 0)
++ want_destroy = ISC_TRUE;
++ UNLOCK(&counter->lock);
++
++ if (want_destroy)
++ destroy(counter);
++}
+Index: contrib/bind9/lib/isc/include/isc/Makefile.in
+===================================================================
+--- contrib/bind9/lib/isc/include/isc/Makefile.in.orig
++++ contrib/bind9/lib/isc/include/isc/Makefile.in
+@@ -13,8 +13,6 @@
+ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ # PERFORMANCE OF THIS SOFTWARE.
+
+-# $Id$
+-
+ srcdir = @srcdir@
+ VPATH = @srcdir@
+ top_srcdir = @top_srcdir@
+@@ -27,7 +25,8 @@
+ # install target below.
+ #
+ HEADERS = app.h assertions.h base64.h bind9.h bitstring.h boolean.h \
+- buffer.h bufferlist.h commandline.h entropy.h error.h event.h \
++ buffer.h bufferlist.h \
++ commandline.h counter.h entropy.h error.h event.h \
+ eventclass.h file.h formatcheck.h fsaccess.h \
+ hash.h heap.h hex.h hmacmd5.h hmacsha.h \
+ httpd.h \
+Index: contrib/bind9/lib/isc/include/isc/counter.h
+===================================================================
+--- contrib/bind9/lib/isc/include/isc/counter.h.orig
++++ contrib/bind9/lib/isc/include/isc/counter.h
+@@ -0,0 +1,90 @@
++/*
++ * 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.
++ */
++
++#ifndef ISC_COUNTER_H
++#define ISC_COUNTER_H 1
++
++/*****
++ ***** Module Info
++ *****/
++
++/*! \file isc/counter.h
++ *
++ * \brief The isc_counter_t object is a simplified version of the
++ * isc_quota_t object; it tracks the consumption of limited
++ * resources, returning an error condition when the quota is
++ * exceeded. However, unlike isc_quota_t, attaching and detaching
++ * from a counter object does not increment or decrement the counter.
++ */
++
++/***
++ *** Imports.
++ ***/
++
++#include
++#include
++#include
++
++/*****
++ ***** Types.
++ *****/
++
++ISC_LANG_BEGINDECLS
++
++isc_result_t
++isc_counter_create(isc_mem_t *mctx, int limit, isc_counter_t **counterp);
++/*%<
++ * Allocate and initialize a counter object.
++ */
++
++isc_result_t
++isc_counter_increment(isc_counter_t *counter);
++/*%<
++ * Increment the counter.
++ *
++ * If the counter limit is nonzero and has been reached, then
++ * return ISC_R_QUOTA, otherwise ISC_R_SUCCESS. (The counter is
++ * incremented regardless of return value.)
++ */
++
++unsigned int
++isc_counter_used(isc_counter_t *counter);
++/*%<
++ * Return the current counter value.
++ */
++
++void
++isc_counter_setlimit(isc_counter_t *counter, int limit);
++/*%<
++ * Set the counter limit.
++ */
++
++void
++isc_counter_attach(isc_counter_t *source, isc_counter_t **targetp);
++/*%<
++ * Attach to a counter object, increasing its reference counter.
++ */
++
++void
++isc_counter_detach(isc_counter_t **counterp);
++/*%<
++ * Detach (and destroy if reference counter has dropped to zero)
++ * a counter object.
++ */
++
++ISC_LANG_ENDDECLS
++
++#endif /* ISC_COUNTER_H */
+Index: contrib/bind9/lib/isc/include/isc/types.h
+===================================================================
+--- contrib/bind9/lib/isc/include/isc/types.h.orig
++++ contrib/bind9/lib/isc/include/isc/types.h
+@@ -50,6 +50,7 @@
+ typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t; /*%< Buffer List */
+ typedef struct isc_constregion isc_constregion_t; /*%< Const region */
+ typedef struct isc_consttextregion isc_consttextregion_t; /*%< Const Text Region */
++typedef struct isc_counter isc_counter_t; /*%< Counter */
+ typedef struct isc_entropy isc_entropy_t; /*%< Entropy */
+ typedef struct isc_entropysource isc_entropysource_t; /*%< Entropy Source */
+ typedef struct isc_event isc_event_t; /*%< Event */
+Index: contrib/bind9/lib/isccfg/namedconf.c
+===================================================================
+--- contrib/bind9/lib/isccfg/namedconf.c.orig
++++ contrib/bind9/lib/isccfg/namedconf.c
+@@ -15,8 +15,6 @@
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+-/* $Id$ */
+-
+ /*! \file */
+
+ #include
+@@ -1354,6 +1352,8 @@
+ { "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-recursion-queries", &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 },
+Index: lib/bind/isc/Makefile
+===================================================================
+--- lib/bind/isc/Makefile.orig
++++ lib/bind/isc/Makefile
+@@ -28,7 +28,7 @@
+ .PATH: ${SRCDIR}
+ SRCS+= inet_pton.c \
+ assertions.c backtrace.c base32.c base64.c bitstring.c \
+- buffer.c bufferlist.c commandline.c error.c event.c \
++ buffer.c bufferlist.c commandline.c counter.c error.c event.c \
+ fsaccess.c hash.c \
+ heap.c hex.c hmacmd5.c hmacsha.c \
+ httpd.c inet_aton.c \
+@@ -66,6 +66,7 @@
+ ${SRCDIR}/include/isc/buffer.h \
+ ${SRCDIR}/include/isc/bufferlist.h \
+ ${SRCDIR}/include/isc/commandline.h \
++ ${SRCDIR}/include/isc/counter.h \
+ ${SRCDIR}/include/isc/entropy.h \
+ ${SRCDIR}/include/isc/error.h \
+ ${SRCDIR}/include/isc/event.h \
diff --git a/share/security/patches/SA-14:29/bind987.patch.asc b/share/security/patches/SA-14:29/bind987.patch.asc
new file mode 100644
index 0000000000..04bb31ceab
--- /dev/null
+++ b/share/security/patches/SA-14:29/bind987.patch.asc
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIcBAABCgAGBQJUiA2RAAoJEO1n7NZdz2rnRBwP+wfGcF6e7O1QZN2kUpCRa1Vv
+VMJGGTxAwG+j61tAa1ZaCo007VHTaUi+EO1OSNLKHKeCM6AzynonPJxeQ01IGHrt
+kNWyMmGiw4ySsBAsEo3UdzN9tZsSv04FgTqlimrfqZPZq99VN4uhXM8EhOfJnzqq
+6zeo8mwnw+5Lp3QijTU3bc+DzMvvAo44EWIIUmhZ6VCa0Vi8ZwBImKrDwR4sliYA
+UhYsCqx3mNHYlvxjVX6WqfwA0ChsMRS6noWWDMrjG5e9de2ShjNlUAkpKaoOCqhh
+ymTVLLJePd+zNCLWv65oS9VT4VI13JRIcX3ExTezUFJFuYT4PohhFzzhTbKttdxs
+fveuWAOH26tEMOmSMsQWiBZRkugoLgiCPfYFupP92T2nEwFqWpSrNYw/SBAWonoH
+SkGMElDc+Inlzg2tr8UhJLyuH4b/JhhGtb9nZWjOZ9SzCNbeMo0lIiRGpJMJxD56
+Hbvz10OsZzrR8TvNW8tmj6mNJObraGLA9Uhnyh4moNTitRptKjGTNtyfATstZkqB
+4K9xYfb8aA52+zmiuXdfFKyqTXCFcqZVO2JzGMOriDFlyQ5LuGEhdEW4GlYO/E4g
+OW8o1vLbg7o5rlh9pLeov6+RrzVntoajMHJWxrCLCrGOPkxNSVYVENhrtuz7c1VA
+ieVo2x0nmiao1jjdxGzn
+=KPoG
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/SA-14:29/bind995.patch b/share/security/patches/SA-14:29/bind995.patch
new file mode 100644
index 0000000000..5068a8381f
--- /dev/null
+++ b/share/security/patches/SA-14:29/bind995.patch
@@ -0,0 +1,572 @@
+Index: contrib/bind9/CHANGES
+===================================================================
+--- contrib/bind9/CHANGES.orig
++++ contrib/bind9/CHANGES
+@@ -1,3 +1,14 @@
++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]
++
+ --- 9.9.5 released ---
+
+ --- 9.9.5rc2 released ---
+Index: contrib/bind9/bin/named/config.c
+===================================================================
+--- contrib/bind9/bin/named/config.c.orig
++++ contrib/bind9/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 @@
+ 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\
+Index: contrib/bind9/bin/named/query.c
+===================================================================
+--- contrib/bind9/bin/named/query.c.orig
++++ contrib/bind9/bin/named/query.c
+@@ -3872,12 +3872,11 @@
+ 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);
+
+Index: contrib/bind9/bin/named/server.c
+===================================================================
+--- contrib/bind9/bin/named/server.c.orig
++++ contrib/bind9/bin/named/server.c
+@@ -3141,6 +3141,11 @@
+ 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);
+Index: contrib/bind9/lib/dns/adb.c
+===================================================================
+--- contrib/bind9/lib/dns/adb.c.orig
++++ contrib/bind9/lib/dns/adb.c
+@@ -201,6 +201,7 @@
+ unsigned int magic;
+ dns_fetch_t *fetch;
+ dns_rdataset_t rdataset;
++ unsigned int depth;
+ };
+
+ /*%
+@@ -301,7 +302,7 @@
+ 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);
+@@ -309,7 +310,7 @@
+ 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 *);
+@@ -982,7 +983,7 @@
+ * 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);
+@@ -1407,7 +1408,7 @@
+ */
+ 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;
+@@ -1467,6 +1468,7 @@
+ 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;
+@@ -1821,6 +1823,7 @@
+ 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);
+@@ -2770,6 +2773,19 @@
+ 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;
+@@ -3000,7 +3016,7 @@
+ * 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",
+@@ -3011,7 +3027,7 @@
+ * 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: "
+@@ -3627,6 +3643,7 @@
+ isc_result_t result;
+ unsigned int address_type;
+ isc_boolean_t want_check_exit = ISC_FALSE;
++ isc_uint32_t qtotal = 0;
+
+ UNUSED(task);
+
+@@ -3637,6 +3654,8 @@
+ adb = name->adb;
+ INSIST(DNS_ADB_VALID(adb));
+
++ qtotal = dev->qtotal;
++
+ bucket = name->lock_bucket;
+ LOCK(&adb->namelocks[bucket]);
+
+@@ -3754,6 +3773,12 @@
+ 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);
+@@ -3785,15 +3810,14 @@
+ 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;
+@@ -3838,12 +3862,14 @@
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
++ fetch->depth = depth;
+
+- result = dns_resolver_createfetch(adb->view->resolver, &adbname->name,
+- type, name, nameservers, NULL,
+- options, adb->task, fetch_callback,
+- adbname, &fetch->rdataset, NULL,
+- &fetch->fetch);
++ 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;
+
+Index: contrib/bind9/lib/dns/include/dns/adb.h
+===================================================================
+--- contrib/bind9/lib/dns/include/dns/adb.h.orig
++++ contrib/bind9/lib/dns/include/dns/adb.h
+@@ -118,6 +118,8 @@
+ 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_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
+Index: contrib/bind9/lib/dns/include/dns/resolver.h
+===================================================================
+--- contrib/bind9/lib/dns/include/dns/resolver.h.orig
++++ contrib/bind9/lib/dns/include/dns/resolver.h
+@@ -82,6 +82,7 @@
+ isc_sockaddr_t * client;
+ dns_messageid_t id;
+ isc_result_t vresult;
++ isc_uint32_t qtotal;
+ } dns_fetchevent_t;
+
+ /*
+@@ -274,6 +275,18 @@
+ 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.
+ *
+@@ -575,6 +588,18 @@
+ * \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 */
+Index: contrib/bind9/lib/dns/resolver.c
+===================================================================
+--- contrib/bind9/lib/dns/resolver.c.orig
++++ contrib/bind9/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 @@
+ 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 @@
+ isc_boolean_t timeout;
+ dns_adbaddrinfo_t *addrinfo;
+ isc_sockaddr_t *client;
++ unsigned int depth;
+ };
+
+ #define FCTX_MAGIC ISC_MAGIC('F', '!', '!', '!')
+@@ -418,6 +430,7 @@
+ isc_timer_t * spillattimer;
+ isc_boolean_t zero_no_soa_ttl;
+ unsigned int query_timeout;
++ unsigned int maxdepth;
+
+ /* Locked by lock. */
+ unsigned int references;
+@@ -1093,6 +1106,7 @@
+ event->result == DNS_R_NCACHENXRRSET);
+ }
+
++ event->qtotal = fctx->totalqueries;
+ isc_task_sendanddetach(&task, ISC_EVENT_PTR(&event));
+ count++;
+ }
+@@ -1533,7 +1547,9 @@
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_dispatch;
+ }
++
+ fctx->querysent++;
++ fctx->totalqueries++;
+
+ ISC_LIST_APPEND(fctx->queries, query, link);
+ query->fctx->nqueries++;
+@@ -2186,9 +2202,10 @@
+ */
+ 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) {
+ /*
+@@ -2471,12 +2488,13 @@
+ * 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) {
+ /*
+@@ -2584,6 +2602,11 @@
+
+ res = fctx->res;
+
++ if (fctx->depth > res->maxdepth) {
++ FCTXTRACE("too much NS indirection");
++ return (DNS_R_SERVFAIL);
++ }
++
+ /*
+ * Forwarders.
+ */
+@@ -3022,6 +3045,9 @@
+
+ REQUIRE(!ADDRWAIT(fctx));
+
++ if (fctx->totalqueries > DEFAULT_MAX_QUERIES)
++ fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
++
+ addrinfo = fctx_nextaddress(fctx);
+ if (addrinfo == NULL) {
+ /*
+@@ -3380,6 +3406,7 @@
+ * Normal fctx startup.
+ */
+ fctx->state = fetchstate_active;
++ fctx->totalqueries = 0;
+ /*
+ * Reset the control event for later use in shutting down
+ * the fctx.
+@@ -3449,6 +3476,7 @@
+ event->fetch = fetch;
+ event->client = client;
+ event->id = id;
++ event->qtotal = 0;
+ dns_fixedname_init(&event->foundname);
+
+ /*
+@@ -3485,7 +3513,8 @@
+ 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;
+@@ -3537,6 +3566,7 @@
+ 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);
+@@ -3555,6 +3585,7 @@
+ fctx->pending = 0;
+ fctx->restarts = 0;
+ fctx->querysent = 0;
++ fctx->totalqueries = 0;
+ fctx->referrals = 0;
+ TIME_NOW(&fctx->start);
+ fctx->timeouts = 0;
+@@ -7731,6 +7762,7 @@
+ 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,
+@@ -8169,9 +8201,9 @@
+ 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));
+ }
+
+@@ -8187,6 +8219,25 @@
+ 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;
+@@ -8273,11 +8324,12 @@
+
+ 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);
+@@ -9049,3 +9101,15 @@
+
+ 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);
++}
+Index: contrib/bind9/lib/isccfg/namedconf.c
+===================================================================
+--- contrib/bind9/lib/isccfg/namedconf.c.orig
++++ contrib/bind9/lib/isccfg/namedconf.c
+@@ -1419,6 +1419,7 @@
+ { "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 },
diff --git a/share/security/patches/SA-14:29/bind995.patch.asc b/share/security/patches/SA-14:29/bind995.patch.asc
new file mode 100644
index 0000000000..dfeebec0ed
--- /dev/null
+++ b/share/security/patches/SA-14:29/bind995.patch.asc
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIcBAABCgAGBQJUiA2RAAoJEO1n7NZdz2rnykkQAK0R3c2Y8DFGI8Fjk6GWoRZF
+gVvoJ3m/q3y4sGrDrG2A7NlhVnwHJGT90xw6EUmmmRHDKf2bTA4iexc4KoZ1uS1g
+0sVc/4my2CbyNl6eMJF98nXN4lon0pi873Dv37jp64kL+NEiFYB18sipPKu1gJ0h
+Q6j7EdZbt8ShBZUth2IGljyN57sH3qkud+xDTD8kvh+ysQ6VavPP8wEcPMHOn8MZ
+UvtOa01wyR4W9kOzzGp+Ai0IVQLnJnI7NkYGT4wFNY4L5xP63F3Ct2H1AuDHKGiT
+s48tKR/pKm5S3oJuDO792g+P3u2RMXffuHg1swPmQs8WN7GmRX/3PhxjxpiE9m0P
+nZ8eHhmSsH4M4AlS7pTfS4lNl5N8c33VLqgzA/10q9nYM1v6DDQMCG6tvJZk9gW9
+KZ0Ubj0qAjETxoZj8R2/e8O8W6s6t8r7tocXJC/iSFDjzn7//cE2Zlvvg2/6XXah
+/lxQp631w3Q3z/Y/6KMAosRUp9Lt00dH4Stol4uzcyCzFLGFSVbYM4Lo5dyQvY81
+TvYX8kXWNjrCwjals2+ERz3w0PyCx3ZMyvKKETeCtZCpbJjH3WfCT1fsQtgWEIv2
+EYuOMi4nZPEm7zeqkhwslgZC4yGp7bKBi9TOK8Yv7arqcIl+cPmc2v9Lx6rrOGJM
+7BFQcixJreATnbms3rnw
+=89Sx
+-----END PGP SIGNATURE-----
diff --git a/share/xml/advisories.xml b/share/xml/advisories.xml
index f6413f5946..e2b3a65fbb 100644
--- a/share/xml/advisories.xml
+++ b/share/xml/advisories.xml
@@ -7,6 +7,26 @@
2014
+
+ 12
+
+
+ 10
+
+
+ FreeBSD-SA-14:29.bind
+
+
+
+ FreeBSD-SA-14:28.file
+
+
+
+ FreeBSD-SA-14:27.stdio
+
+
+
+
11