aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-connectivity/bind/bind/CVE-2015-8000.patch
blob: e1c8052578ecdd06738723bedbc31cf9c31f00d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
From 8259daad7242ab2af8731681177ef7e948a15ece Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
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 <akuster@mvista.com>

---
 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 @@
     <itemizedlist>
       <listitem>
 	<para>
+	  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]
+	</para>
+      </listitem>
+      <listitem>
+	<para>
 	  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.