From a159f9dcf3806f2c3677775d6fb131dab17a5a17 Mon Sep 17 00:00:00 2001 From: Armin Kuster Date: Sat, 30 Jan 2016 18:55:39 -0800 Subject: bind: Security fix CVE-2015-8000 CVE-2015-8000 bind: responses with a malformed class attribute can trigger an assertion failure in db.c Signed-off-by: Armin Kuster --- .../bind/bind/CVE-2015-8000.patch | 278 +++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100644 meta/recipes-connectivity/bind/bind/CVE-2015-8000.patch (limited to 'meta/recipes-connectivity/bind/bind/CVE-2015-8000.patch') diff --git a/meta/recipes-connectivity/bind/bind/CVE-2015-8000.patch b/meta/recipes-connectivity/bind/bind/CVE-2015-8000.patch new file mode 100644 index 0000000000..e1c8052578 --- /dev/null +++ b/meta/recipes-connectivity/bind/bind/CVE-2015-8000.patch @@ -0,0 +1,278 @@ +From 8259daad7242ab2af8731681177ef7e948a15ece Mon Sep 17 00:00:00 2001 +From: Mark Andrews +Date: Mon, 16 Nov 2015 13:12:20 +1100 +Subject: [PATCH] 4260. [security] Insufficient testing when parsing a + message allowed records with an incorrect class to be + be accepted, triggering a REQUIRE failure when those + records were subsequently cached. (CVE-2015-8000) [RT + #4098] + +(cherry picked from commit c8821d124c532e0a65752b378f924d4259499fd3) +(cherry picked from commit 3a4c24c4a52d4a2d21d2decbde3d4e514e27d51c) + + +Upstream-Status: Backport + +https://source.isc.org/cgi-bin/gitweb.cgi?p=bind9.git;a=commit;h=8259daad7242ab2af8731681177ef7e948a15ece + +CVE: CVE-2015-8000 + +Signed-off-by: Armin Kuster + +--- + CHANGES | 5 +++++ + bin/tests/system/start.pl | 5 ++++- + doc/arm/notes.xml | 9 +++++++++ + lib/dns/include/dns/message.h | 13 +++++++++++-- + lib/dns/message.c | 45 ++++++++++++++++++++++++++++++++++++++----- + lib/dns/resolver.c | 9 +++++++++ + lib/dns/xfrin.c | 2 ++ + 7 files changed, 80 insertions(+), 8 deletions(-) + +Index: bind-9.10.2-P4/bin/tests/system/start.pl +=================================================================== +--- bind-9.10.2-P4.orig/bin/tests/system/start.pl ++++ bind-9.10.2-P4/bin/tests/system/start.pl +@@ -68,6 +68,7 @@ my $NAMED = $ENV{'NAMED'}; + my $LWRESD = $ENV{'LWRESD'}; + my $DIG = $ENV{'DIG'}; + my $PERL = $ENV{'PERL'}; ++my $PYTHON = $ENV{'PYTHON'}; + + # Start the server(s) + +@@ -213,7 +214,9 @@ sub start_server { + $pid_file = "lwresd.pid"; + } elsif ($server =~ /^ans/) { + $cleanup_files = "{ans.run}"; +- if (-e "$testdir/$server/ans.pl") { ++ if (-e "$testdir/$server/ans.py") { ++ $command = "$PYTHON ans.py 10.53.0.$' 5300"; ++ } elsif (-e "$testdir/$server/ans.pl") { + $command = "$PERL ans.pl"; + } else { + $command = "$PERL $topdir/ans.pl 10.53.0.$'"; +Index: bind-9.10.2-P4/doc/arm/notes.xml +=================================================================== +--- bind-9.10.2-P4.orig/doc/arm/notes.xml ++++ bind-9.10.2-P4/doc/arm/notes.xml +@@ -62,6 +62,15 @@ + + + ++ Insufficient testing when parsing a message allowed ++ records with an incorrect class to be be accepted, ++ triggering a REQUIRE failure when those records ++ were subsequently cached. This flaw is disclosed ++ in CVE-2015-8000. [RT #4098] ++ ++ ++ ++ + An incorrect boundary check in the OPENPGPKEY rdatatype + could trigger an assertion failure. This flaw is disclosed + in CVE-2015-5986. [RT #40286] +Index: bind-9.10.2-P4/lib/dns/include/dns/message.h +=================================================================== +--- bind-9.10.2-P4.orig/lib/dns/include/dns/message.h ++++ bind-9.10.2-P4/lib/dns/include/dns/message.h +@@ -15,8 +15,6 @@ + * PERFORMANCE OF THIS SOFTWARE. + */ + +-/* $Id$ */ +- + #ifndef DNS_MESSAGE_H + #define DNS_MESSAGE_H 1 + +@@ -221,6 +219,8 @@ struct dns_message { + unsigned int free_saved : 1; + unsigned int sitok : 1; + unsigned int sitbad : 1; ++ unsigned int tkey : 1; ++ unsigned int rdclass_set : 1; + + unsigned int opt_reserved; + unsigned int sig_reserved; +@@ -1400,6 +1400,15 @@ dns_message_buildopt(dns_message_t *msg, + * \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 */ +Index: bind-9.10.2-P4/lib/dns/message.c +=================================================================== +--- bind-9.10.2-P4.orig/lib/dns/message.c ++++ bind-9.10.2-P4/lib/dns/message.c +@@ -439,6 +439,8 @@ msginit(dns_message_t *m) { + m->free_saved = 0; + m->sitok = 0; + m->sitbad = 0; ++ m->tkey = 0; ++ m->rdclass_set = 0; + m->querytsig = NULL; + } + +@@ -1091,13 +1093,19 @@ getquestions(isc_buffer_t *source, dns_m + * 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); +@@ -1241,12 +1249,12 @@ getsection(isc_buffer_t *source, dns_mes + * 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; + } + + /* +@@ -1256,7 +1264,7 @@ getsection(isc_buffer_t *source, dns_mes + 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 +@@ -1264,6 +1272,16 @@ getsection(isc_buffer_t *source, dns_mes + 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) { +@@ -1377,6 +1395,10 @@ getsection(isc_buffer_t *source, dns_mes + 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; +@@ -1625,6 +1647,7 @@ dns_message_parse(dns_message_t *msg, is + msg->counts[DNS_SECTION_ADDITIONAL] = isc_buffer_getuint16(source); + + msg->header_ok = 1; ++ msg->state = DNS_SECTION_QUESTION; + + /* + * -1 means no EDNS. +@@ -3706,3 +3729,15 @@ dns_message_buildopt(dns_message_t *mess + 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; ++} +Index: bind-9.10.2-P4/lib/dns/resolver.c +=================================================================== +--- bind-9.10.2-P4.orig/lib/dns/resolver.c ++++ bind-9.10.2-P4/lib/dns/resolver.c +@@ -7309,6 +7309,8 @@ resquery_response(isc_task_t *task, isc_ + goto done; + } + ++ dns_message_setclass(message, fctx->res->rdclass); ++ + if ((options & DNS_FETCHOPT_TCP) == 0) { + if ((options & DNS_FETCHOPT_NOEDNS0) == 0) + dns_adb_setudpsize(fctx->adb, query->addrinfo, +@@ -7391,6 +7393,13 @@ resquery_response(isc_task_t *task, isc_ + &dns_master_style_comment, + 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. + */ +Index: bind-9.10.2-P4/lib/dns/xfrin.c +=================================================================== +--- bind-9.10.2-P4.orig/lib/dns/xfrin.c ++++ bind-9.10.2-P4/lib/dns/xfrin.c +@@ -1225,6 +1225,8 @@ xfrin_recv_done(isc_task_t *task, isc_ev + msg->tsigctx = xfr->tsigctx; + xfr->tsigctx = NULL; + ++ dns_message_setclass(msg, xfr->rdclass); ++ + if (xfr->nmsg > 0) + msg->tcp_continuation = 1; + +Index: bind-9.10.2-P4/CHANGES +=================================================================== +--- bind-9.10.2-P4.orig/CHANGES ++++ bind-9.10.2-P4/CHANGES +@@ -1,4 +1,9 @@ +- --- 9.10.2-P4 released --- ++4260. [security] Insufficient testing when parsing a message allowed ++ records with an incorrect class to be be accepted, ++ triggering a REQUIRE failure when those records ++ were subsequently cached. (CVE-2015-8000) [RT #4098] ++ ++ --- 9.10.2-P4 released --- + + 4170. [security] An incorrect boundary check in the OPENPGPKEY + rdatatype could trigger an assertion failure. -- cgit 1.2.3-korg