summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/glibc
diff options
context:
space:
mode:
authorGeorge McCollister <george.mccollister@gmail.com>2017-11-21 14:01:20 -0600
committerRichard Purdie <richard.purdie@linuxfoundation.org>2017-12-09 14:34:35 +0000
commit02ab4bdbf71d0fc9383578aaee5ce641bad9bc81 (patch)
tree3e4c162c4acfbd157e644f71982b89c3a849ae85 /meta/recipes-core/glibc
parent38961fcfcbf958ac4004fe6f048f44728eaf27f0 (diff)
downloadpoky-02ab4bdbf71d0fc9383578aaee5ce641bad9bc81.tar.gz
glibc: Fix CVE-2015-5180
Add backported patch to fix CVE-2015-5180 from the upstream release/2.24/master branch. (From OE-Core rev: e8a6e3894c8aebac4aa6b0ceea021b95e94e6691) Signed-off-by: George McCollister <george.mccollister@gmail.com> Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-core/glibc')
-rw-r--r--meta/recipes-core/glibc/glibc/0001-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch357
-rw-r--r--meta/recipes-core/glibc/glibc_2.24.bb1
2 files changed, 358 insertions, 0 deletions
diff --git a/meta/recipes-core/glibc/glibc/0001-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch b/meta/recipes-core/glibc/glibc/0001-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch
new file mode 100644
index 0000000000..ba0bebe488
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/0001-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch
@@ -0,0 +1,357 @@
1From ff9b7c4fb73295cd2de2d2ccfbbf4f6d50883d47 Mon Sep 17 00:00:00 2001
2From: Florian Weimer <fweimer@redhat.com>
3Date: Sat, 31 Dec 2016 20:22:09 +0100
4Subject: [PATCH] CVE-2015-5180: resolv: Fix crash with internal QTYPE [BZ
5 #18784]
6
7Also rename T_UNSPEC because an upcoming public header file
8update will use that name.
9
10(cherry picked from commit fc82b0a2dfe7dbd35671c10510a8da1043d746a5)
11
12Upstream-Status: Backport
13https://sourceware.org/git/?p=glibc.git;a=patch;h=b3b37f1a5559a7620e31c8053ed1b44f798f2b6d
14
15CVE: CVE-2015-5180
16
17Signed-off-by: George McCollister <george.mccollister@gmail.com>
18---
19 ChangeLog | 14 ++++
20 NEWS | 6 ++
21 include/arpa/nameser_compat.h | 6 +-
22 resolv/Makefile | 5 ++
23 resolv/nss_dns/dns-host.c | 2 +-
24 resolv/res_mkquery.c | 4 +
25 resolv/res_query.c | 6 +-
26 resolv/tst-resolv-qtypes.c | 185 ++++++++++++++++++++++++++++++++++++++++++
27 8 files changed, 221 insertions(+), 7 deletions(-)
28 create mode 100644 resolv/tst-resolv-qtypes.c
29
30diff --git a/ChangeLog b/ChangeLog
31index 893262de11..2bdaf69e43 100644
32--- a/ChangeLog
33+++ b/ChangeLog
34@@ -1,3 +1,17 @@
35+2016-12-31 Florian Weimer <fweimer@redhat.com>
36+
37+ [BZ #18784]
38+ CVE-2015-5180
39+ * include/arpa/nameser_compat.h (T_QUERY_A_AND_AAAA): Rename from
40+ T_UNSPEC. Adjust value.
41+ * resolv/nss_dns/dns-host.c (_nss_dns_gethostbyname4_r): Use it.
42+ * resolv/res_query.c (__libc_res_nquery): Likewise.
43+ * resolv/res_mkquery.c (res_nmkquery): Check for out-of-range
44+ QTYPEs.
45+ * resolv/tst-resolv-qtypes.c: New file.
46+ * resolv/Makefile (xtests): Add tst-resolv-qtypes.
47+ (tst-resolv-qtypes): Link against libresolv and libpthread.
48+
49 2016-10-26 Carlos O'Donell <carlos@redhat.com>
50
51 * include/atomic.h
52diff --git a/NEWS b/NEWS
53index 3002773c16..4b1ca3cb65 100644
54--- a/NEWS
55+++ b/NEWS
56@@ -11,6 +11,12 @@ using `glibc' in the "product" field.
57 printers show various pthread variables in human-readable form when read
58 using the 'print' or 'display' commands in gdb.
59
60+* The DNS stub resolver functions would crash due to a NULL pointer
61+ dereference when processing a query with a valid DNS question type which
62+ was used internally in the implementation. The stub resolver now uses a
63+ question type which is outside the range of valid question type values.
64+ (CVE-2015-5180)
65+
66 Version 2.24
67
68 * The minimum Linux kernel version that this version of the GNU C Library
69diff --git a/include/arpa/nameser_compat.h b/include/arpa/nameser_compat.h
70index 2e735ede4c..7c0deed9ae 100644
71--- a/include/arpa/nameser_compat.h
72+++ b/include/arpa/nameser_compat.h
73@@ -1,8 +1,8 @@
74 #ifndef _ARPA_NAMESER_COMPAT_
75 #include <resolv/arpa/nameser_compat.h>
76
77-/* Picksome unused number to represent lookups of IPv4 and IPv6 (i.e.,
78- T_A and T_AAAA). */
79-#define T_UNSPEC 62321
80+/* The number is outside the 16-bit RR type range and is used
81+ internally by the implementation. */
82+#define T_QUERY_A_AND_AAAA 439963904
83
84 #endif
85diff --git a/resolv/Makefile b/resolv/Makefile
86index 8be41d3ae1..a4c86b9762 100644
87--- a/resolv/Makefile
88+++ b/resolv/Makefile
89@@ -40,6 +40,9 @@ ifeq ($(have-thread-library),yes)
90 extra-libs += libanl
91 routines += gai_sigqueue
92 tests += tst-res_hconf_reorder
93+
94+# This test sends millions of packets and is rather slow.
95+xtests += tst-resolv-qtypes
96 endif
97 extra-libs-others = $(extra-libs)
98 libresolv-routines := gethnamaddr res_comp res_debug \
99@@ -117,3 +120,5 @@ tst-leaks2-ENV = MALLOC_TRACE=$(objpfx)tst-leaks2.mtrace
100 $(objpfx)mtrace-tst-leaks2.out: $(objpfx)tst-leaks2.out
101 $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks2.mtrace > $@; \
102 $(evaluate-test)
103+
104+$(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
105diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
106index 5f9e35701b..d16fa4b8ed 100644
107--- a/resolv/nss_dns/dns-host.c
108+++ b/resolv/nss_dns/dns-host.c
109@@ -323,7 +323,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
110
111 int olderr = errno;
112 enum nss_status status;
113- int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
114+ int n = __libc_res_nsearch (&_res, name, C_IN, T_QUERY_A_AND_AAAA,
115 host_buffer.buf->buf, 2048, &host_buffer.ptr,
116 &ans2p, &nans2p, &resplen2, &ans2p_malloced);
117 if (n >= 0)
118diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c
119index 12f9730199..d80b5318e5 100644
120--- a/resolv/res_mkquery.c
121+++ b/resolv/res_mkquery.c
122@@ -103,6 +103,10 @@ res_nmkquery(res_state statp,
123 int n;
124 u_char *dnptrs[20], **dpp, **lastdnptr;
125
126+ if (class < 0 || class > 65535
127+ || type < 0 || type > 65535)
128+ return -1;
129+
130 #ifdef DEBUG
131 if (statp->options & RES_DEBUG)
132 printf(";; res_nmkquery(%s, %s, %s, %s)\n",
133diff --git a/resolv/res_query.c b/resolv/res_query.c
134index 944d1a90f5..07dc6f6583 100644
135--- a/resolv/res_query.c
136+++ b/resolv/res_query.c
137@@ -122,7 +122,7 @@ __libc_res_nquery(res_state statp,
138 int n, use_malloc = 0;
139 u_int oflags = statp->_flags;
140
141- size_t bufsize = (type == T_UNSPEC ? 2 : 1) * QUERYSIZE;
142+ size_t bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * QUERYSIZE;
143 u_char *buf = alloca (bufsize);
144 u_char *query1 = buf;
145 int nquery1 = -1;
146@@ -137,7 +137,7 @@ __libc_res_nquery(res_state statp,
147 printf(";; res_query(%s, %d, %d)\n", name, class, type);
148 #endif
149
150- if (type == T_UNSPEC)
151+ if (type == T_QUERY_A_AND_AAAA)
152 {
153 n = res_nmkquery(statp, QUERY, name, class, T_A, NULL, 0, NULL,
154 query1, bufsize);
155@@ -190,7 +190,7 @@ __libc_res_nquery(res_state statp,
156 if (__builtin_expect (n <= 0, 0) && !use_malloc) {
157 /* Retry just in case res_nmkquery failed because of too
158 short buffer. Shouldn't happen. */
159- bufsize = (type == T_UNSPEC ? 2 : 1) * MAXPACKET;
160+ bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * MAXPACKET;
161 buf = malloc (bufsize);
162 if (buf != NULL) {
163 query1 = buf;
164diff --git a/resolv/tst-resolv-qtypes.c b/resolv/tst-resolv-qtypes.c
165new file mode 100644
166index 0000000000..b3e60c693b
167--- /dev/null
168+++ b/resolv/tst-resolv-qtypes.c
169@@ -0,0 +1,185 @@
170+/* Exercise low-level query functions with different QTYPEs.
171+ Copyright (C) 2016 Free Software Foundation, Inc.
172+ This file is part of the GNU C Library.
173+
174+ The GNU C Library is free software; you can redistribute it and/or
175+ modify it under the terms of the GNU Lesser General Public
176+ License as published by the Free Software Foundation; either
177+ version 2.1 of the License, or (at your option) any later version.
178+
179+ The GNU C Library is distributed in the hope that it will be useful,
180+ but WITHOUT ANY WARRANTY; without even the implied warranty of
181+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
182+ Lesser General Public License for more details.
183+
184+ You should have received a copy of the GNU Lesser General Public
185+ License along with the GNU C Library; if not, see
186+ <http://www.gnu.org/licenses/>. */
187+
188+#include <resolv.h>
189+#include <string.h>
190+#include <support/check.h>
191+#include <support/check_nss.h>
192+#include <support/resolv_test.h>
193+#include <support/support.h>
194+#include <support/test-driver.h>
195+#include <support/xmemstream.h>
196+
197+/* If ture, the response function will send the actual response packet
198+ over TCP instead of UDP. */
199+static volatile bool force_tcp;
200+
201+/* Send back a fake resource record matching the QTYPE. */
202+static void
203+response (const struct resolv_response_context *ctx,
204+ struct resolv_response_builder *b,
205+ const char *qname, uint16_t qclass, uint16_t qtype)
206+{
207+ if (force_tcp && ctx->tcp)
208+ {
209+ resolv_response_init (b, (struct resolv_response_flags) { .tc = 1 });
210+ resolv_response_add_question (b, qname, qclass, qtype);
211+ return;
212+ }
213+
214+ resolv_response_init (b, (struct resolv_response_flags) { });
215+ resolv_response_add_question (b, qname, qclass, qtype);
216+ resolv_response_section (b, ns_s_an);
217+ resolv_response_open_record (b, qname, qclass, qtype, 0);
218+ resolv_response_add_data (b, &qtype, sizeof (qtype));
219+ resolv_response_close_record (b);
220+}
221+
222+static const const char *domain = "www.example.com";
223+
224+static int
225+wrap_res_query (int type, unsigned char *answer, int answer_length)
226+{
227+ return res_query (domain, C_IN, type, answer, answer_length);
228+}
229+
230+static int
231+wrap_res_search (int type, unsigned char *answer, int answer_length)
232+{
233+ return res_query (domain, C_IN, type, answer, answer_length);
234+}
235+
236+static int
237+wrap_res_querydomain (int type, unsigned char *answer, int answer_length)
238+{
239+ return res_querydomain ("www", "example.com", C_IN, type,
240+ answer, answer_length);
241+}
242+
243+static int
244+wrap_res_send (int type, unsigned char *answer, int answer_length)
245+{
246+ unsigned char buf[512];
247+ int ret = res_mkquery (QUERY, domain, C_IN, type,
248+ (const unsigned char *) "", 0, NULL,
249+ buf, sizeof (buf));
250+ if (type < 0 || type >= 65536)
251+ {
252+ /* res_mkquery fails for out-of-range record types. */
253+ TEST_VERIFY_EXIT (ret == -1);
254+ return -1;
255+ }
256+ TEST_VERIFY_EXIT (ret > 12); /* DNS header length. */
257+ return res_send (buf, ret, answer, answer_length);
258+}
259+
260+static int
261+wrap_res_nquery (int type, unsigned char *answer, int answer_length)
262+{
263+ return res_nquery (&_res, domain, C_IN, type, answer, answer_length);
264+}
265+
266+static int
267+wrap_res_nsearch (int type, unsigned char *answer, int answer_length)
268+{
269+ return res_nquery (&_res, domain, C_IN, type, answer, answer_length);
270+}
271+
272+static int
273+wrap_res_nquerydomain (int type, unsigned char *answer, int answer_length)
274+{
275+ return res_nquerydomain (&_res, "www", "example.com", C_IN, type,
276+ answer, answer_length);
277+}
278+
279+static int
280+wrap_res_nsend (int type, unsigned char *answer, int answer_length)
281+{
282+ unsigned char buf[512];
283+ int ret = res_nmkquery (&_res, QUERY, domain, C_IN, type,
284+ (const unsigned char *) "", 0, NULL,
285+ buf, sizeof (buf));
286+ if (type < 0 || type >= 65536)
287+ {
288+ /* res_mkquery fails for out-of-range record types. */
289+ TEST_VERIFY_EXIT (ret == -1);
290+ return -1;
291+ }
292+ TEST_VERIFY_EXIT (ret > 12); /* DNS header length. */
293+ return res_nsend (&_res, buf, ret, answer, answer_length);
294+}
295+
296+static void
297+test_function (const char *fname,
298+ int (*func) (int type,
299+ unsigned char *answer, int answer_length))
300+{
301+ unsigned char buf[512];
302+ for (int tcp = 0; tcp < 2; ++tcp)
303+ {
304+ force_tcp = tcp;
305+ for (unsigned int type = 1; type <= 65535; ++type)
306+ {
307+ if (test_verbose)
308+ printf ("info: sending QTYPE %d with %s (tcp=%d)\n",
309+ type, fname, tcp);
310+ int ret = func (type, buf, sizeof (buf));
311+ if (ret != 47)
312+ FAIL_EXIT1 ("%s tcp=%d qtype=%d return value %d",
313+ fname,tcp, type, ret);
314+ /* One question, one answer record. */
315+ TEST_VERIFY (memcmp (buf + 4, "\0\1\0\1\0\0\0\0", 8) == 0);
316+ /* Question section. */
317+ static const char qname[] = "\3www\7example\3com";
318+ size_t qname_length = sizeof (qname);
319+ TEST_VERIFY (memcmp (buf + 12, qname, qname_length) == 0);
320+ /* RDATA part of answer. */
321+ uint16_t type16 = type;
322+ TEST_VERIFY (memcmp (buf + ret - 2, &type16, sizeof (type16)) == 0);
323+ }
324+ }
325+
326+ TEST_VERIFY (func (-1, buf, sizeof (buf) == -1));
327+ TEST_VERIFY (func (65536, buf, sizeof (buf) == -1));
328+}
329+
330+static int
331+do_test (void)
332+{
333+ struct resolv_redirect_config config =
334+ {
335+ .response_callback = response,
336+ };
337+ struct resolv_test *obj = resolv_test_start (config);
338+
339+ test_function ("res_query", &wrap_res_query);
340+ test_function ("res_search", &wrap_res_search);
341+ test_function ("res_querydomain", &wrap_res_querydomain);
342+ test_function ("res_send", &wrap_res_send);
343+
344+ test_function ("res_nquery", &wrap_res_nquery);
345+ test_function ("res_nsearch", &wrap_res_nsearch);
346+ test_function ("res_nquerydomain", &wrap_res_nquerydomain);
347+ test_function ("res_nsend", &wrap_res_nsend);
348+
349+ resolv_test_end (obj);
350+ return 0;
351+}
352+
353+#define TIMEOUT 300
354+#include <support/test-driver.c>
355--
3562.15.0
357
diff --git a/meta/recipes-core/glibc/glibc_2.24.bb b/meta/recipes-core/glibc/glibc_2.24.bb
index e723e03dcf..4c7d901149 100644
--- a/meta/recipes-core/glibc/glibc_2.24.bb
+++ b/meta/recipes-core/glibc/glibc_2.24.bb
@@ -45,6 +45,7 @@ SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \
45 file://0004-New-condvar-implementation-that-provides-stronger-or.patch \ 45 file://0004-New-condvar-implementation-that-provides-stronger-or.patch \
46 file://0005-Remove-__ASSUME_REQUEUE_PI.patch \ 46 file://0005-Remove-__ASSUME_REQUEUE_PI.patch \
47 file://0006-Fix-atomic_fetch_xor_release.patch \ 47 file://0006-Fix-atomic_fetch_xor_release.patch \
48 file://0001-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch \
48" 49"
49 50
50SRC_URI += "\ 51SRC_URI += "\