summaryrefslogtreecommitdiffstats
path: root/meta/recipes-connectivity/bind/bind/CVE-2015-8000.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-connectivity/bind/bind/CVE-2015-8000.patch')
-rw-r--r--meta/recipes-connectivity/bind/bind/CVE-2015-8000.patch194
1 files changed, 194 insertions, 0 deletions
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 0000000..b8d8412
--- /dev/null
+++ b/meta/recipes-connectivity/bind/bind/CVE-2015-8000.patch
@@ -0,0 +1,194 @@
1responses with a malformed class attribute can trigger an
2assertion failure in db.c
3
4[security]
5Insufficient testing when parsing a message allowed records with
6an incorrect class to be be accepted, triggering a REQUIRE failure
7when those records were subsequently cached. (CVE-2015-8000) [RT#4098]
8
9Upstream-Status: Backport
10
11[The patch is taken from BIND 9.9.4:
12https://bugzilla.redhat.com/attachment.cgi?id=1105581]
13
14Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
15---
16diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h
17index a6862fa..d999e75 100644
18--- a/lib/dns/include/dns/message.h
19+++ b/lib/dns/include/dns/message.h
20@@ -210,6 +210,8 @@ struct dns_message {
21 unsigned int verify_attempted : 1;
22 unsigned int free_query : 1;
23 unsigned int free_saved : 1;
24+ unsigned int tkey : 1;
25+ unsigned int rdclass_set : 1;
26
27 unsigned int opt_reserved;
28 unsigned int sig_reserved;
29@@ -1374,6 +1376,15 @@ dns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt,
30 * \li other.
31 */
32
33+void
34+dns_message_setclass(dns_message_t *msg, dns_rdataclass_t rdclass);
35+/*%<
36+ * Set the expected class of records in the response.
37+ *
38+ * Requires:
39+ * \li msg be a valid message with parsing intent.
40+ */
41+
42 ISC_LANG_ENDDECLS
43
44 #endif /* DNS_MESSAGE_H */
45diff --git a/lib/dns/message.c b/lib/dns/message.c
46index 53efc5a..73def73 100644
47--- a/lib/dns/message.c
48+++ b/lib/dns/message.c
49@@ -436,6 +436,8 @@ msginit(dns_message_t *m) {
50 m->saved.base = NULL;
51 m->saved.length = 0;
52 m->free_saved = 0;
53+ m->tkey = 0;
54+ m->rdclass_set = 0;
55 m->querytsig = NULL;
56 }
57
58@@ -1086,13 +1088,19 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
59 * If this class is different than the one we already read,
60 * this is an error.
61 */
62- if (msg->state == DNS_SECTION_ANY) {
63- msg->state = DNS_SECTION_QUESTION;
64+ if (msg->rdclass_set == 0) {
65 msg->rdclass = rdclass;
66+ msg->rdclass_set = 1;
67 } else if (msg->rdclass != rdclass)
68 DO_FORMERR;
69
70 /*
71+ * Is this a TKEY query?
72+ */
73+ if (rdtype == dns_rdatatype_tkey)
74+ msg->tkey = 1;
75+
76+ /*
77 * Can't ask the same question twice.
78 */
79 result = dns_message_find(name, rdclass, rdtype, 0, NULL);
80@@ -1236,12 +1244,12 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
81 * If there was no question section, we may not yet have
82 * established a class. Do so now.
83 */
84- if (msg->state == DNS_SECTION_ANY &&
85+ if (msg->rdclass_set == 0 &&
86 rdtype != dns_rdatatype_opt && /* class is UDP SIZE */
87 rdtype != dns_rdatatype_tsig && /* class is ANY */
88 rdtype != dns_rdatatype_tkey) { /* class is undefined */
89 msg->rdclass = rdclass;
90- msg->state = DNS_SECTION_QUESTION;
91+ msg->rdclass_set = 1;
92 }
93
94 /*
95@@ -1251,7 +1259,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
96 if (msg->opcode != dns_opcode_update
97 && rdtype != dns_rdatatype_tsig
98 && rdtype != dns_rdatatype_opt
99- && rdtype != dns_rdatatype_dnskey /* in a TKEY query */
100+ && rdtype != dns_rdatatype_key /* in a TKEY query */
101 && rdtype != dns_rdatatype_sig /* SIG(0) */
102 && rdtype != dns_rdatatype_tkey /* Win2000 TKEY */
103 && msg->rdclass != dns_rdataclass_any
104@@ -1259,6 +1267,16 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
105 DO_FORMERR;
106
107 /*
108+ * If this is not a TKEY query/response then the KEY
109+ * record's class needs to match.
110+ */
111+ if (msg->opcode != dns_opcode_update && !msg->tkey &&
112+ rdtype == dns_rdatatype_key &&
113+ msg->rdclass != dns_rdataclass_any &&
114+ msg->rdclass != rdclass)
115+ DO_FORMERR;
116+
117+ /*
118 * Special type handling for TSIG, OPT, and TKEY.
119 */
120 if (rdtype == dns_rdatatype_tsig) {
121@@ -1372,6 +1390,10 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
122 skip_name_search = ISC_TRUE;
123 skip_type_search = ISC_TRUE;
124 issigzero = ISC_TRUE;
125+ } else {
126+ if (msg->rdclass != dns_rdataclass_any &&
127+ msg->rdclass != rdclass)
128+ DO_FORMERR;
129 }
130 } else
131 covers = 0;
132@@ -1610,6 +1632,7 @@ dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
133 msg->counts[DNS_SECTION_ADDITIONAL] = isc_buffer_getuint16(source);
134
135 msg->header_ok = 1;
136+ msg->state = DNS_SECTION_QUESTION;
137
138 /*
139 * -1 means no EDNS.
140@@ -3550,3 +3573,15 @@ dns_message_buildopt(dns_message_t *message, dns_rdataset_t **rdatasetp,
141 dns_message_puttemprdatalist(message, &rdatalist);
142 return (result);
143 }
144+
145+void
146+dns_message_setclass(dns_message_t *msg, dns_rdataclass_t rdclass) {
147+
148+ REQUIRE(DNS_MESSAGE_VALID(msg));
149+ REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
150+ REQUIRE(msg->state == DNS_SECTION_ANY);
151+ REQUIRE(msg->rdclass_set == 0);
152+
153+ msg->rdclass = rdclass;
154+ msg->rdclass_set = 1;
155+}
156diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
157index aa23b11..d220986 100644
158--- a/lib/dns/resolver.c
159+++ b/lib/dns/resolver.c
160@@ -6964,6 +6964,8 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
161 goto done;
162 }
163
164+ dns_message_setclass(message, fctx->res->rdclass);
165+
166 result = dns_message_parse(message, &devent->buffer, 0);
167 if (result != ISC_R_SUCCESS) {
168 switch (result) {
169@@ -7036,6 +7038,12 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
170 */
171 log_packet(message, ISC_LOG_DEBUG(10), fctx->res->mctx);
172
173+ if (message->rdclass != fctx->res->rdclass) {
174+ resend = ISC_TRUE;
175+ FCTXTRACE("bad class");
176+ goto done;
177+ }
178+
179 /*
180 * Process receive opt record.
181 */
182diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c
183index 9ad8960..938373a 100644
184--- a/lib/dns/xfrin.c
185+++ b/lib/dns/xfrin.c
186@@ -1241,6 +1241,8 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
187 msg->tsigctx = xfr->tsigctx;
188 xfr->tsigctx = NULL;
189
190+ dns_message_setclass(msg, xfr->rdclass);
191+
192 if (xfr->nmsg > 0)
193 msg->tcp_continuation = 1;
194