diff --git a/SOURCES/bind99-CVE-2015-8000.patch b/SOURCES/bind99-CVE-2015-8000.patch new file mode 100644 index 0000000..c7247f5 --- /dev/null +++ b/SOURCES/bind99-CVE-2015-8000.patch @@ -0,0 +1,179 @@ +diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h +index a6862fa..d999e75 100644 +--- a/lib/dns/include/dns/message.h ++++ b/lib/dns/include/dns/message.h +@@ -210,6 +210,8 @@ struct dns_message { + unsigned int verify_attempted : 1; + unsigned int free_query : 1; + unsigned int free_saved : 1; ++ unsigned int tkey : 1; ++ unsigned int rdclass_set : 1; + + unsigned int opt_reserved; + unsigned int sig_reserved; +@@ -1374,6 +1376,15 @@ dns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt, + * \li other. + */ + ++void ++dns_message_setclass(dns_message_t *msg, dns_rdataclass_t rdclass); ++/*%< ++ * Set the expected class of records in the response. ++ * ++ * Requires: ++ * \li msg be a valid message with parsing intent. ++ */ ++ + ISC_LANG_ENDDECLS + + #endif /* DNS_MESSAGE_H */ +diff --git a/lib/dns/message.c b/lib/dns/message.c +index 53efc5a..73def73 100644 +--- a/lib/dns/message.c ++++ b/lib/dns/message.c +@@ -436,6 +436,8 @@ msginit(dns_message_t *m) { + m->saved.base = NULL; + m->saved.length = 0; + m->free_saved = 0; ++ m->tkey = 0; ++ m->rdclass_set = 0; + m->querytsig = NULL; + } + +@@ -1086,13 +1088,19 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, + * If this class is different than the one we already read, + * this is an error. + */ +- if (msg->state == DNS_SECTION_ANY) { +- msg->state = DNS_SECTION_QUESTION; ++ if (msg->rdclass_set == 0) { + msg->rdclass = rdclass; ++ msg->rdclass_set = 1; + } else if (msg->rdclass != rdclass) + DO_FORMERR; + + /* ++ * Is this a TKEY query? ++ */ ++ if (rdtype == dns_rdatatype_tkey) ++ msg->tkey = 1; ++ ++ /* + * Can't ask the same question twice. + */ + result = dns_message_find(name, rdclass, rdtype, 0, NULL); +@@ -1236,12 +1244,12 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, + * If there was no question section, we may not yet have + * established a class. Do so now. + */ +- if (msg->state == DNS_SECTION_ANY && ++ if (msg->rdclass_set == 0 && + rdtype != dns_rdatatype_opt && /* class is UDP SIZE */ + rdtype != dns_rdatatype_tsig && /* class is ANY */ + rdtype != dns_rdatatype_tkey) { /* class is undefined */ + msg->rdclass = rdclass; +- msg->state = DNS_SECTION_QUESTION; ++ msg->rdclass_set = 1; + } + + /* +@@ -1251,7 +1259,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, + if (msg->opcode != dns_opcode_update + && rdtype != dns_rdatatype_tsig + && rdtype != dns_rdatatype_opt +- && rdtype != dns_rdatatype_dnskey /* in a TKEY query */ ++ && rdtype != dns_rdatatype_key /* in a TKEY query */ + && rdtype != dns_rdatatype_sig /* SIG(0) */ + && rdtype != dns_rdatatype_tkey /* Win2000 TKEY */ + && msg->rdclass != dns_rdataclass_any +@@ -1259,6 +1267,16 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, + DO_FORMERR; + + /* ++ * If this is not a TKEY query/response then the KEY ++ * record's class needs to match. ++ */ ++ if (msg->opcode != dns_opcode_update && !msg->tkey && ++ rdtype == dns_rdatatype_key && ++ msg->rdclass != dns_rdataclass_any && ++ msg->rdclass != rdclass) ++ DO_FORMERR; ++ ++ /* + * Special type handling for TSIG, OPT, and TKEY. + */ + if (rdtype == dns_rdatatype_tsig) { +@@ -1372,6 +1390,10 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, + skip_name_search = ISC_TRUE; + skip_type_search = ISC_TRUE; + issigzero = ISC_TRUE; ++ } else { ++ if (msg->rdclass != dns_rdataclass_any && ++ msg->rdclass != rdclass) ++ DO_FORMERR; + } + } else + covers = 0; +@@ -1610,6 +1632,7 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source, + msg->counts[DNS_SECTION_ADDITIONAL] = isc_buffer_getuint16(source); + + msg->header_ok = 1; ++ msg->state = DNS_SECTION_QUESTION; + + /* + * -1 means no EDNS. +@@ -3550,3 +3573,15 @@ dns_message_buildopt(dns_message_t *message, dns_rdataset_t **rdatasetp, + dns_message_puttemprdatalist(message, &rdatalist); + return (result); + } ++ ++void ++dns_message_setclass(dns_message_t *msg, dns_rdataclass_t rdclass) { ++ ++ REQUIRE(DNS_MESSAGE_VALID(msg)); ++ REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE); ++ REQUIRE(msg->state == DNS_SECTION_ANY); ++ REQUIRE(msg->rdclass_set == 0); ++ ++ msg->rdclass = rdclass; ++ msg->rdclass_set = 1; ++} +diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c +index aa23b11..d220986 100644 +--- a/lib/dns/resolver.c ++++ b/lib/dns/resolver.c +@@ -6964,6 +6964,8 @@ resquery_response(isc_task_t *task, isc_event_t *event) { + goto done; + } + ++ dns_message_setclass(message, fctx->res->rdclass); ++ + result = dns_message_parse(message, &devent->buffer, 0); + if (result != ISC_R_SUCCESS) { + switch (result) { +@@ -7036,6 +7038,12 @@ resquery_response(isc_task_t *task, isc_event_t *event) { + */ + log_packet(message, ISC_LOG_DEBUG(10), fctx->res->mctx); + ++ if (message->rdclass != fctx->res->rdclass) { ++ resend = ISC_TRUE; ++ FCTXTRACE("bad class"); ++ goto done; ++ } ++ + /* + * Process receive opt record. + */ +diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c +index 9ad8960..938373a 100644 +--- a/lib/dns/xfrin.c ++++ b/lib/dns/xfrin.c +@@ -1241,6 +1241,8 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) { + msg->tsigctx = xfr->tsigctx; + xfr->tsigctx = NULL; + ++ dns_message_setclass(msg, xfr->rdclass); ++ + if (xfr->nmsg > 0) + msg->tcp_continuation = 1; + diff --git a/SPECS/bind.spec b/SPECS/bind.spec index de75c45..c58e297 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: 29%{?PATCHVER}%{?PREVER}%{?dist} +Release: 29%{?PATCHVER}%{?PREVER}%{?dist}.1 Epoch: 32 Url: http://www.isc.org/products/BIND/ Buildroot:%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -101,6 +101,7 @@ Patch156:bind99-CVE-2015-4620.patch Patch157:bind99-CVE-2015-5477.patch Patch158:bind-99-socket-maxevents.patch Patch159:bind99-CVE-2015-5722.patch +Patch160:bind99-CVE-2015-8000.patch # Native PKCS#11 functionality from 9.10 Patch150:bind-9.9-allow_external_dnskey.patch @@ -375,6 +376,7 @@ popd %patch157 -p1 -b .CVE-2015-5477 %patch158 -p1 -b .sock-maxevents %patch159 -p1 -b .CVE-2015-5722 +%patch160 -p1 -b .CVE-2015-8000 %if %{PKCS11} cp -r bin/named{,-pkcs11} @@ -1055,6 +1057,9 @@ rm -rf ${RPM_BUILD_ROOT} %endif %changelog +* Mon Dec 14 2015 Tomas Hozza - 32:9.9.4-29.1 +- Fix CVE-2015-8000 + * Wed Sep 02 2015 Tomas Hozza - 32:9.9.4-29 - Fix CVE-2015-5722