diff --git a/SOURCES/bind99-CVE-2016-9131.patch b/SOURCES/bind99-CVE-2016-9131.patch
new file mode 100644
index 0000000..29e381c
--- /dev/null
+++ b/SOURCES/bind99-CVE-2016-9131.patch
@@ -0,0 +1,37 @@
+diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
+index 2bc4461..d9de369 100644
+--- a/lib/dns/resolver.c
++++ b/lib/dns/resolver.c
+@@ -6533,6 +6533,19 @@ answer_response(fetchctx_t *fctx) {
+ 					log_formerr(fctx, "NSEC3 in answer");
+ 					return (DNS_R_FORMERR);
+ 				}
++				if (rdataset->type == dns_rdatatype_tkey) {
++					/*
++					 * TKEY is not a valid record in a
++					 * response to any query we can make.
++					 */
++					log_formerr(fctx, "TKEY in answer");
++					return (DNS_R_FORMERR);
++				}
++				if (rdataset->rdclass != fctx->res->rdclass) {
++					log_formerr(fctx, "Mismatched class "
++						    "in answer");
++					return (DNS_R_FORMERR);
++				}
+ 
+ 				/*
+ 				 * Apply filters, if given, on answers to reject
+@@ -6719,6 +6732,12 @@ answer_response(fetchctx_t *fctx) {
+ 			     rdataset != NULL;
+ 			     rdataset = ISC_LIST_NEXT(rdataset, link))
+ 			{
++				if (rdataset->rdclass != fctx->res->rdclass) {
++					log_formerr(fctx, "Mismatched class "
++						    "in answer");
++					return (DNS_R_FORMERR);
++				}
++
+ 				/*
+ 				 * Only pass DNAME or RRSIG(DNAME).
+ 				 */
diff --git a/SOURCES/bind99-CVE-2016-9147.patch b/SOURCES/bind99-CVE-2016-9147.patch
new file mode 100644
index 0000000..221ff94
--- /dev/null
+++ b/SOURCES/bind99-CVE-2016-9147.patch
@@ -0,0 +1,31 @@
+diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
+index 9ad5f81..ffdde5e 100644
+--- a/lib/dns/resolver.c
++++ b/lib/dns/resolver.c
+@@ -6229,15 +6229,19 @@ answer_response(fetchctx_t *fctx) {
+ 						 * a CNAME or DNAME).
+ 						 */
+ 						INSIST(!external);
+-						if ((rdataset->type !=
+-						     dns_rdatatype_cname) ||
+-						    !found_dname ||
+-						    (aflag ==
+-						     DNS_RDATASETATTR_ANSWER))
++						/*
++						 * Don't use found_cname here
++						 * as we have just set it
++						 * above.
++						 */
++						if (cname == NULL &&
++						    !found_dname &&
++						    aflag ==
++						     DNS_RDATASETATTR_ANSWER)
+ 						{
+ 							have_answer = ISC_TRUE;
+-							if (rdataset->type ==
+-							    dns_rdatatype_cname)
++							if (found_cname &&
++							    cname == NULL)
+ 								cname = name;
+ 							name->attributes |=
+ 								DNS_NAMEATTR_ANSWER;
diff --git a/SOURCES/bind99-CVE-2016-9444.patch b/SOURCES/bind99-CVE-2016-9444.patch
new file mode 100644
index 0000000..17ee09f
--- /dev/null
+++ b/SOURCES/bind99-CVE-2016-9444.patch
@@ -0,0 +1,147 @@
+diff --git a/lib/dns/message.c b/lib/dns/message.c
+index 869d258..c1f9498 100644
+--- a/lib/dns/message.c
++++ b/lib/dns/message.c
+@@ -1150,6 +1150,63 @@ update(dns_section_t section, dns_rdataclass_t rdclass) {
+ 	return (ISC_FALSE);
+ }
+ 
++/*
++ * Check to confirm that all DNSSEC records (DS, NSEC, NSEC3) have
++ * covering RRSIGs.
++ */
++static isc_boolean_t
++auth_signed(dns_namelist_t *section) {
++	dns_name_t *name;
++
++	for (name = ISC_LIST_HEAD(*section);
++	     name != NULL;
++	     name = ISC_LIST_NEXT(name, link))
++	{
++		int auth_dnssec = 0, auth_rrsig = 0;
++		dns_rdataset_t *rds;
++
++		for (rds = ISC_LIST_HEAD(name->list);
++		     rds != NULL;
++		     rds = ISC_LIST_NEXT(rds, link))
++		{
++			switch (rds->type) {
++			case dns_rdatatype_ds:
++				auth_dnssec |= 0x1;
++				break;
++			case dns_rdatatype_nsec:
++				auth_dnssec |= 0x2;
++				break;
++			case dns_rdatatype_nsec3:
++				auth_dnssec |= 0x4;
++				break;
++			case dns_rdatatype_rrsig:
++				break;
++			default:
++				continue;
++			}
++
++			switch (rds->covers) {
++			case dns_rdatatype_ds:
++				auth_rrsig |= 0x1;
++				break;
++			case dns_rdatatype_nsec:
++				auth_rrsig |= 0x2;
++				break;
++			case dns_rdatatype_nsec3:
++				auth_rrsig |= 0x4;
++				break;
++			default:
++				break;
++			}
++		}
++
++		if (auth_dnssec != auth_rrsig)
++			return (ISC_FALSE);
++	}
++
++	return (ISC_TRUE);
++}
++
+ static isc_result_t
+ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
+ 	   dns_section_t sectionid, unsigned int options)
+@@ -1175,12 +1232,12 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
+ 	best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
+ 	seen_problem = ISC_FALSE;
+ 
++	section = &msg->sections[sectionid];
++
+ 	for (count = 0; count < msg->counts[sectionid]; count++) {
+ 		int recstart = source->current;
+ 		isc_boolean_t skip_name_search, skip_type_search;
+ 
+-		section = &msg->sections[sectionid];
+-
+ 		skip_name_search = ISC_FALSE;
+ 		skip_type_search = ISC_FALSE;
+ 		free_rdataset = ISC_FALSE;
+@@ -1354,7 +1411,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
+ 			goto cleanup;
+ 		rdata->rdclass = rdclass;
+ 		issigzero = ISC_FALSE;
+-		if (rdtype == dns_rdatatype_rrsig  &&
++		if (rdtype == dns_rdatatype_rrsig &&
+ 		    rdata->flags == 0) {
+ 			covers = dns_rdata_covers(rdata);
+ 			if (covers == 0)
+@@ -1565,6 +1622,19 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
+ 		INSIST(free_rdataset == ISC_FALSE);
+ 	}
+ 
++	/*
++	 * If any of DS, NSEC or NSEC3 appeared in the
++	 * authority section of a query response without
++	 * a covering RRSIG, FORMERR
++	 */
++	if (sectionid == DNS_SECTION_AUTHORITY &&
++	    msg->opcode == dns_opcode_query &&
++	    ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) &&
++	    ((msg->flags & DNS_MESSAGEFLAG_TC) == 0) &&
++	    !preserve_order &&
++	    !auth_signed(section))
++		DO_FORMERR;
++
+ 	if (seen_problem)
+ 		return (DNS_R_RECOVERABLE);
+ 	return (ISC_R_SUCCESS);
+diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
+index 2bc4461..e5600a3 100644
+--- a/lib/dns/resolver.c
++++ b/lib/dns/resolver.c
+@@ -5194,13 +5194,9 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
+ 							      rdataset->type,
+ 							      &noqname);
+ 					if (tresult == ISC_R_SUCCESS &&
+-					    noqname != NULL) {
+-						tresult =
+-						     dns_rdataset_addnoqname(
++					    noqname != NULL)
++						(void) dns_rdataset_addnoqname(
+ 							    rdataset, noqname);
+-						RUNTIME_CHECK(tresult ==
+-							      ISC_R_SUCCESS);
+-					}
+ 				}
+ 				addedrdataset = ardataset;
+ 				result = dns_db_addrdataset(fctx->cache, node,
+@@ -5330,11 +5326,9 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
+ 				tresult = findnoqname(fctx, name,
+ 						      rdataset->type, &noqname);
+ 				if (tresult == ISC_R_SUCCESS &&
+-				    noqname != NULL) {
+-					tresult = dns_rdataset_addnoqname(
+-							    rdataset, noqname);
+-					RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
+-				}
++				    noqname != NULL)
++					(void) dns_rdataset_addnoqname(
++						       rdataset, noqname);
+ 			}
+ 
+ 			/*
diff --git a/SOURCES/bind99-rt43779.patch b/SOURCES/bind99-rt43779.patch
new file mode 100644
index 0000000..fa6b6ec
--- /dev/null
+++ b/SOURCES/bind99-rt43779.patch
@@ -0,0 +1,159 @@
+commit 524f5c0d8fa5bd55c98243be889528f48437a2f7
+Author: Mark Andrews <marka@isc.org>
+Date:   Fri Dec 9 12:50:18 2016 +1100
+
+    4530.   [bug]           Change 4489 broke the handling of CNAME -> DNAME
+                            in responses resulting in SERVFAIL being returned.
+                            [RT #43779]
+    
+    (cherry picked from commit 60cb462c56536f307fac4db8bdebf1247e2b5f66)
+
+diff --git a/bin/tests/system/dname/ns2/example.db b/bin/tests/system/dname/ns2/example.db
+index ece3506..4289134 100644
+--- a/bin/tests/system/dname/ns2/example.db
++++ b/bin/tests/system/dname/ns2/example.db
+@@ -29,4 +29,6 @@ a.short			A	10.0.0.1
+ short-dname		DNAME	short
+ a.longlonglonglonglonglonglonglonglonglonglonglonglong	A 10.0.0.2
+ long-dname		DNAME	longlonglonglonglonglonglonglonglonglonglonglonglong
+-;
++cname			CNAME	a.cnamedname
++cnamedname		DNAME	target
++a.target		A	10.0.0.3
+diff --git a/bin/tests/system/dname/tests.sh b/bin/tests/system/dname/tests.sh
+index d22f54b..04bfcb2 100644
+--- a/bin/tests/system/dname/tests.sh
++++ b/bin/tests/system/dname/tests.sh
+@@ -63,6 +63,24 @@ grep "status: YXDOMAIN" dig.out.ns4.toolong > /dev/null || ret=1
+ if [ $ret != 0 ]; then echo "I:failed"; fi
+ status=`expr $status + $ret`
+ 
++echo "I:checking cname to dname from authoritative"
++ret=0
++$DIG cname.example @10.53.0.2 a -p 5300 > dig.out.ns2.cname
++grep "status: NOERROR" dig.out.ns2.cname > /dev/null || ret=1
++if [ $ret != 0 ]; then echo "I:failed"; fi
++status=`expr $status + $ret`
++
++echo "I:checking cname to dname from recursive"
++ret=0
++$DIG cname.example @10.53.0.4 a -p 5300 > dig.out.ns4.cname
++grep "status: NOERROR" dig.out.ns4.cname > /dev/null || ret=1
++grep '^cname.example.' dig.out.ns4.cname > /dev/null || ret=1
++grep '^cnamedname.example.' dig.out.ns4.cname > /dev/null || ret=1
++grep '^a.cnamedname.example.' dig.out.ns4.cname > /dev/null || ret=1
++grep '^a.target.example.' dig.out.ns4.cname > /dev/null || ret=1
++if [ $ret != 0 ]; then echo "I:failed"; fi
++status=`expr $status + $ret`
++
+ echo "I:exit status: $status"
+ 
+ exit $status
+diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
+index 4bef072..de80928 100644
+--- a/lib/dns/resolver.c
++++ b/lib/dns/resolver.c
+@@ -6463,7 +6463,7 @@ static isc_result_t
+ answer_response(fetchctx_t *fctx) {
+ 	isc_result_t result;
+ 	dns_message_t *message;
+-	dns_name_t *name, *dname = NULL, *qname, *dqname, tname, *ns_name;
++	dns_name_t *name, *dname = NULL, *qname, tname, *ns_name;
+ 	dns_name_t *cname = NULL;
+ 	dns_rdataset_t *rdataset, *ns_rdataset;
+ 	isc_boolean_t done, external, chaining, aa, found, want_chaining;
+@@ -6471,7 +6471,7 @@ answer_response(fetchctx_t *fctx) {
+ 	isc_boolean_t wanted_chaining;
+ 	unsigned int aflag;
+ 	dns_rdatatype_t type;
+-	dns_fixedname_t fdname, fqname, fqdname;
++	dns_fixedname_t fdname, fqname;
+ 	dns_view_t *view;
+ 
+ 	FCTXTRACE("answer_response");
+@@ -6495,13 +6495,12 @@ answer_response(fetchctx_t *fctx) {
+ 		aa = ISC_TRUE;
+ 	else
+ 		aa = ISC_FALSE;
+-	dqname = qname = &fctx->name;
++	qname = &fctx->name;
+ 	type = fctx->type;
+ 	view = fctx->res->view;
+-	dns_fixedname_init(&fqdname);
+ 	result = dns_message_firstname(message, DNS_SECTION_ANSWER);
+ 	while (!done && result == ISC_R_SUCCESS) {
+-		dns_namereln_t namereln, dnamereln;
++		dns_namereln_t namereln;
+ 		int order;
+ 		unsigned int nlabels;
+ 
+@@ -6509,8 +6508,6 @@ answer_response(fetchctx_t *fctx) {
+ 		dns_message_currentname(message, DNS_SECTION_ANSWER, &name);
+ 		external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
+ 		namereln = dns_name_fullcompare(qname, name, &order, &nlabels);
+-		dnamereln = dns_name_fullcompare(dqname, name, &order,
+-						 &nlabels);
+ 		if (namereln == dns_namereln_equal) {
+ 			wanted_chaining = ISC_FALSE;
+ 			for (rdataset = ISC_LIST_HEAD(name->list);
+@@ -6763,11 +6760,24 @@ answer_response(fetchctx_t *fctx) {
+ 					return (DNS_R_FORMERR);
+ 				}
+ 
+-				if (dnamereln != dns_namereln_subdomain) {
++				/*
++				 * If DNAME + synthetic CNAME then the
++				 * namereln is dns_namereln_subdomain.
++				 *
++				 * If synthetic CNAME + DNAME then the
++				 * namereln is dns_namereln_commonancestor
++				 * and the number of label must match the
++				 * DNAME.  This order is not RFC compliant.
++				 */
++
++				if (namereln != dns_namereln_subdomain &&
++				    (namereln != dns_namereln_commonancestor ||
++				     nlabels != dns_name_countlabels(name)))
++				{
+ 					char qbuf[DNS_NAME_FORMATSIZE];
+ 					char obuf[DNS_NAME_FORMATSIZE];
+ 
+-					dns_name_format(dqname, qbuf,
++					dns_name_format(qname, qbuf,
+ 							sizeof(qbuf));
+ 					dns_name_format(name, obuf,
+ 							sizeof(obuf));
+@@ -6782,7 +6792,7 @@ answer_response(fetchctx_t *fctx) {
+ 					want_chaining = ISC_TRUE;
+ 					POST(want_chaining);
+ 					aflag = DNS_RDATASETATTR_ANSWER;
+-					result = dname_target(rdataset, dqname,
++					result = dname_target(rdataset, qname,
+ 							      nlabels, &fdname);
+ 					if (result == ISC_R_NOSPACE) {
+ 						/*
+@@ -6799,13 +6809,11 @@ answer_response(fetchctx_t *fctx) {
+ 
+ 					dname = dns_fixedname_name(&fdname);
+ 					if (!is_answertarget_allowed(view,
+-						     dqname, rdataset->type,
++						     qname, rdataset->type,
+ 						     dname, &fctx->domain))
+ 					{
+ 						return (DNS_R_SERVFAIL);
+ 					}
+-					dqname = dns_fixedname_name(&fqdname);
+-					dns_name_copy(dname, dqname, NULL);
+ 				} else {
+ 					/*
+ 					 * We've found a signature that
+@@ -6951,7 +6959,8 @@ answer_response(fetchctx_t *fctx) {
+ 						rdataset->trust =
+ 						    dns_trust_additional;
+ 
+-					if (rdataset->type == dns_rdatatype_ns) {
++					if (rdataset->type == dns_rdatatype_ns)
++					{
+ 						ns_name = name;
+ 						ns_rdataset = rdataset;
+ 					}
diff --git a/SPECS/bind.spec b/SPECS/bind.spec
index 801e469..f66d909 100644
--- a/SPECS/bind.spec
+++ b/SPECS/bind.spec
@@ -25,7 +25,7 @@ Summary:  The Berkeley Internet Name Domain (BIND) DNS (Domain Name System) serv
 Name:     bind
 License:  ISC
 Version:  9.9.4
-Release:  38%{?PATCHVER}%{?PREVER}%{?dist}
+Release:  38%{?PATCHVER}%{?PREVER}%{?dist}.1
 Epoch:    32
 Url:      http://www.isc.org/products/BIND/
 Buildroot:%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -113,6 +113,10 @@ Patch166:bind99-rh1220594-geoip.patch
 Patch167:bind99-automatic-interface-scanning-rh1294506.patch
 patch168:bind99-CVE-2016-2776.patch
 patch169:bind99-CVE-2016-8864.patch
+patch170:bind99-CVE-2016-9131.patch
+patch171:bind99-CVE-2016-9147.patch
+Patch172:bind99-CVE-2016-9444.patch
+Patch173:bind99-rt43779.patch
 
 # Native PKCS#11 functionality from 9.10
 Patch150:bind-9.9-allow_external_dnskey.patch
@@ -402,6 +406,10 @@ tar -xf %{SOURCE48} -C bin/tests/system/geoip/data
 %patch167 -p1 -b .rh1294506
 %patch168 -p1 -b .CVE-2016-2776
 %patch169 -p1 -b .CVE-2016-8864
+%patch170 -p1 -b .CVE-2016-9131
+%patch171 -p1 -b .CVE-2016-9147
+%patch172 -p1 -b .CVE-2016-9444
+%patch173 -p1 -b .rt43779
 
 %if %{PKCS11}
 cp -r bin/named{,-pkcs11}
@@ -1081,6 +1089,12 @@ rm -rf ${RPM_BUILD_ROOT}
 %endif
 
 %changelog
+* Mon Jan 09 2017 Petr Menšík <pemensik@redhat.com> - 32:9.9.4-38.1
+- Fix CVE-2016-9131 (ISC change 4508)
+- Fix CVE-2016-9147 (ISC change 4510)
+- Fix regression introduced by CVE-2016-8864 (ISC change 4530)
+- Fix CVE-2016-9444 (ISC change 4517)
+
 * Mon Oct 31 2016 Tomas Hozza <thozza@redhat.com> - 32:9.9.4-38
 - Fix CVE-2016-8864