summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorArmin Kuster <akuster@mvista.com>2016-07-09 10:05:24 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-07-27 08:33:36 +0100
commit22198f07af771d2841ffb97859574b4dc6e14d57 (patch)
tree2916328678cc75dabc44bdcb400e099d7059c8c5 /meta
parent03d9d8e7d356dae222f33f2d3dafd1d7c60af93d (diff)
downloadpoky-22198f07af771d2841ffb97859574b4dc6e14d57.tar.gz
glibc: Security fix for CVE-2016-3706
Master not affected. (From OE-Core rev: 6c5aaa3150e6cf74219e5bcf4819365ae3628102) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2016-3706.patch224
-rw-r--r--meta/recipes-core/glibc/glibc_2.23.bb1
2 files changed, 225 insertions, 0 deletions
diff --git a/meta/recipes-core/glibc/glibc/CVE-2016-3706.patch b/meta/recipes-core/glibc/glibc/CVE-2016-3706.patch
new file mode 100644
index 0000000000..dddabc8dd1
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/CVE-2016-3706.patch
@@ -0,0 +1,224 @@
1From 4ab2ab03d4351914ee53248dc5aef4a8c88ff8b9 Mon Sep 17 00:00:00 2001
2From: Florian Weimer <fweimer@redhat.com>
3Date: Fri, 29 Apr 2016 10:35:34 +0200
4Subject: [PATCH] CVE-2016-3706: getaddrinfo: stack overflow in hostent
5 conversion [BZ #20010]
6
7When converting a struct hostent response to struct gaih_addrtuple, the
8gethosts macro (which is called from gaih_inet) used alloca, without
9malloc fallback for large responses. This commit changes this code to
10use calloc unconditionally.
11
12This commit also consolidated a second hostent-to-gaih_addrtuple
13conversion loop (in gaih_inet) to use the new conversion function.
14
15Upstream-Status: Backport
16CVE: CVE-2016-3706
17
18Signed-off-by: Armin Kuster <akuster@mvista.com>
19
20---
21 ChangeLog | 10 ++++
22 NEWS | 5 +-
23 sysdeps/posix/getaddrinfo.c | 130 +++++++++++++++++++++++---------------------
24 3 files changed, 83 insertions(+), 62 deletions(-)
25
26Index: git/sysdeps/posix/getaddrinfo.c
27===================================================================
28--- git.orig/sysdeps/posix/getaddrinfo.c
29+++ git/sysdeps/posix/getaddrinfo.c
30@@ -168,9 +168,58 @@ gaih_inet_serv (const char *servicename,
31 return 0;
32 }
33
34+/* Convert struct hostent to a list of struct gaih_addrtuple objects.
35+ h_name is not copied, and the struct hostent object must not be
36+ deallocated prematurely. *RESULT must be NULL or a pointer to an
37+ object allocated using malloc, which is freed. */
38+static bool
39+convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
40+ int family,
41+ struct hostent *h,
42+ struct gaih_addrtuple **result)
43+{
44+ free (*result);
45+ *result = NULL;
46+
47+ /* Count the number of addresses in h->h_addr_list. */
48+ size_t count = 0;
49+ for (char **p = h->h_addr_list; *p != NULL; ++p)
50+ ++count;
51+
52+ /* Report no data if no addresses are available, or if the incoming
53+ address size is larger than what we can store. */
54+ if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
55+ return true;
56+
57+ struct gaih_addrtuple *array = calloc (count, sizeof (*array));
58+ if (array == NULL)
59+ return false;
60+
61+ for (size_t i = 0; i < count; ++i)
62+ {
63+ if (family == AF_INET && req->ai_family == AF_INET6)
64+ {
65+ /* Perform address mapping. */
66+ array[i].family = AF_INET6;
67+ memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
68+ array[i].addr[2] = htonl (0xffff);
69+ }
70+ else
71+ {
72+ array[i].family = family;
73+ memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
74+ }
75+ array[i].next = array + i + 1;
76+ }
77+ array[0].name = h->h_name;
78+ array[count - 1].next = NULL;
79+
80+ *result = array;
81+ return true;
82+}
83+
84 #define gethosts(_family, _type) \
85 { \
86- int i; \
87 int herrno; \
88 struct hostent th; \
89 struct hostent *h; \
90@@ -219,36 +268,23 @@ gaih_inet_serv (const char *servicename,
91 } \
92 else if (h != NULL) \
93 { \
94- for (i = 0; h->h_addr_list[i]; i++) \
95+ /* Make sure that addrmem can be freed. */ \
96+ if (!malloc_addrmem) \
97+ addrmem = NULL; \
98+ if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem)) \
99 { \
100- if (*pat == NULL) \
101- { \
102- *pat = __alloca (sizeof (struct gaih_addrtuple)); \
103- (*pat)->scopeid = 0; \
104- } \
105- uint32_t *addr = (*pat)->addr; \
106- (*pat)->next = NULL; \
107- (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \
108- if (_family == AF_INET && req->ai_family == AF_INET6) \
109- { \
110- (*pat)->family = AF_INET6; \
111- addr[3] = *(uint32_t *) h->h_addr_list[i]; \
112- addr[2] = htonl (0xffff); \
113- addr[1] = 0; \
114- addr[0] = 0; \
115- } \
116- else \
117- { \
118- (*pat)->family = _family; \
119- memcpy (addr, h->h_addr_list[i], sizeof(_type)); \
120- } \
121- pat = &((*pat)->next); \
122+ _res.options |= old_res_options & RES_USE_INET6; \
123+ result = -EAI_SYSTEM; \
124+ goto free_and_return; \
125 } \
126+ *pat = addrmem; \
127+ /* The conversion uses malloc unconditionally. */ \
128+ malloc_addrmem = true; \
129 \
130 if (localcanon != NULL && canon == NULL) \
131 canon = strdupa (localcanon); \
132 \
133- if (_family == AF_INET6 && i > 0) \
134+ if (_family == AF_INET6 && *pat != NULL) \
135 got_ipv6 = true; \
136 } \
137 }
138@@ -612,44 +648,16 @@ gaih_inet (const char *name, const struc
139 {
140 if (h != NULL)
141 {
142- int i;
143- /* We found data, count the number of addresses. */
144- for (i = 0; h->h_addr_list[i]; ++i)
145- ;
146- if (i > 0 && *pat != NULL)
147- --i;
148-
149- if (__libc_use_alloca (alloca_used
150- + i * sizeof (struct gaih_addrtuple)))
151- addrmem = alloca_account (i * sizeof (struct gaih_addrtuple),
152- alloca_used);
153- else
154+ /* We found data, convert it. */
155+ if (!convert_hostent_to_gaih_addrtuple
156+ (req, AF_INET, h, &addrmem))
157 {
158- addrmem = malloc (i
159- * sizeof (struct gaih_addrtuple));
160- if (addrmem == NULL)
161- {
162- result = -EAI_MEMORY;
163- goto free_and_return;
164- }
165- malloc_addrmem = true;
166- }
167-
168- /* Now convert it into the list. */
169- struct gaih_addrtuple *addrfree = addrmem;
170- for (i = 0; h->h_addr_list[i]; ++i)
171- {
172- if (*pat == NULL)
173- {
174- *pat = addrfree++;
175- (*pat)->scopeid = 0;
176- }
177- (*pat)->next = NULL;
178- (*pat)->family = AF_INET;
179- memcpy ((*pat)->addr, h->h_addr_list[i],
180- h->h_length);
181- pat = &((*pat)->next);
182+ result = -EAI_MEMORY;
183+ goto free_and_return;
184 }
185+ *pat = addrmem;
186+ /* The conversion uses malloc unconditionally. */
187+ malloc_addrmem = true;
188 }
189 }
190 else
191Index: git/NEWS
192===================================================================
193--- git.orig/NEWS
194+++ git/NEWS
195@@ -2,6 +2,11 @@ GNU C Library NEWS -- history of user-vi
196 Copyright (C) 1992-2016 Free Software Foundation, Inc.
197 See the end for copying conditions.
198
199+* Previously, getaddrinfo copied large amounts of address data to the stack,
200+ even after the fix for CVE-2013-4458 has been applied, potentially
201+ resulting in a stack overflow. getaddrinfo now uses a heap allocation
202+ instead. Reported by Michael Petlan. (CVE-2016-3706)
203+
204 Please send GNU C library bug reports via <http://sourceware.org/bugzilla/>
205 using `glibc' in the "product" field.
206
207Index: git/ChangeLog
208===================================================================
209--- git.orig/ChangeLog
210+++ git/ChangeLog
211@@ -1,3 +1,13 @@
212+2016-04-29 Florian Weimer <fweimer@redhat.com>
213+
214+ [BZ #20010]
215+ CVE-2016-3706
216+ * sysdeps/posix/getaddrinfo.c
217+ (convert_hostent_to_gaih_addrtuple): New function.
218+ (gethosts): Call convert_hostent_to_gaih_addrtuple.
219+ (gaih_inet): Use convert_hostent_to_gaih_addrtuple to convert
220+ AF_INET data.
221+
222 2016-02-18 Adhemerval Zanella <adhemerval.zanella@linaro.org>
223
224 * configure: Regenerated.
diff --git a/meta/recipes-core/glibc/glibc_2.23.bb b/meta/recipes-core/glibc/glibc_2.23.bb
index 18f40660ec..44923797d6 100644
--- a/meta/recipes-core/glibc/glibc_2.23.bb
+++ b/meta/recipes-core/glibc/glibc_2.23.bb
@@ -36,6 +36,7 @@ SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \
36 file://0023-eglibc-Install-PIC-archives.patch \ 36 file://0023-eglibc-Install-PIC-archives.patch \
37 file://0025-eglibc-Forward-port-cross-locale-generation-support.patch \ 37 file://0025-eglibc-Forward-port-cross-locale-generation-support.patch \
38 file://0026-When-disabling-SSE-make-sure-fpmath-is-not-set-to-us.patch \ 38 file://0026-When-disabling-SSE-make-sure-fpmath-is-not-set-to-us.patch \
39 file://CVE-2016-3706.patch \
39" 40"
40 41
41SRC_URI += "\ 42SRC_URI += "\