Hi,

Attached is proposed debdiff for the unstable upload (not yet uploaded
to any delayed queue, just want to check I do not interfere with your
work on it already).

Regards,
Salvatore
diff -u bind9-9.9.5.dfsg/debian/changelog bind9-9.9.5.dfsg/debian/changelog
--- bind9-9.9.5.dfsg/debian/changelog
+++ bind9-9.9.5.dfsg/debian/changelog
@@ -1,3 +1,13 @@
+bind9 (1:9.9.5.dfsg-12.1) unstable; urgency=high
+
+  * Non-maintainer upload.
+  * Add patch to fix CVE-2015-8000.
+    CVE-2015-8000: Insufficient testing when parsing a message allowed
+    records with an incorrect class to be accepted, triggering a REQUIRE
+    failure when those records were subsequently cached. (Closes: #808081)
+
+ -- Salvatore Bonaccorso <car...@debian.org>  Wed, 16 Dec 2015 15:01:39 +0100
+
 bind9 (1:9.9.5.dfsg-12) unstable; urgency=high
 
   * Fix CVE-2015-5722: maliciously crafted DNSSEC key can cause named to crash.
diff -u bind9-9.9.5.dfsg/lib/dns/resolver.c bind9-9.9.5.dfsg/lib/dns/resolver.c
--- bind9-9.9.5.dfsg/lib/dns/resolver.c
+++ bind9-9.9.5.dfsg/lib/dns/resolver.c
@@ -6974,6 +6974,8 @@
                        goto done;
        }
 
+    dns_message_setclass(message, fctx->res->rdclass);
+
        result = dns_message_parse(message, &devent->buffer, 0);
        if (result != ISC_R_SUCCESS) {
                switch (result) {
@@ -7046,6 +7048,12 @@
         */
        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.
         */
only in patch2:
unchanged:
--- bind9-9.9.5.dfsg.orig/lib/dns/include/dns/message.h
+++ bind9-9.9.5.dfsg/lib/dns/include/dns/message.h
@@ -211,6 +211,8 @@
        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;
@@ -1375,6 +1377,15 @@
  * \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 */
only in patch2:
unchanged:
--- bind9-9.9.5.dfsg.orig/lib/dns/message.c
+++ bind9-9.9.5.dfsg/lib/dns/message.c
@@ -436,6 +436,8 @@
        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 @@
                 * 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 @@
                 * 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 @@
                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 @@
                        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 @@
                                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 @@
        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_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;
+}
only in patch2:
unchanged:
--- bind9-9.9.5.dfsg.orig/lib/dns/xfrin.c
+++ bind9-9.9.5.dfsg/lib/dns/xfrin.c
@@ -1211,6 +1211,8 @@
        msg->tsigctx = xfr->tsigctx;
        xfr->tsigctx = NULL;
 
+       dns_message_setclass(msg, xfr->rdclass);
+
        if (xfr->nmsg > 0)
                msg->tcp_continuation = 1;
 

Reply via email to