diff options
Diffstat (limited to 'meta/recipes-core/glibc/glibc/CVE-2015-9761_2.patch')
-rw-r--r-- | meta/recipes-core/glibc/glibc/CVE-2015-9761_2.patch | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/meta/recipes-core/glibc/glibc/CVE-2015-9761_2.patch b/meta/recipes-core/glibc/glibc/CVE-2015-9761_2.patch new file mode 100644 index 0000000000..0df5e5071c --- /dev/null +++ b/meta/recipes-core/glibc/glibc/CVE-2015-9761_2.patch | |||
@@ -0,0 +1,388 @@ | |||
1 | From 8f5e8b01a1da2a207228f2072c934fa5918554b8 Mon Sep 17 00:00:00 2001 | ||
2 | From: Joseph Myers <joseph@codesourcery.com> | ||
3 | Date: Fri, 4 Dec 2015 20:36:28 +0000 | ||
4 | Subject: [PATCH] Fix nan functions handling of payload strings (bug 16961, bug | ||
5 | 16962). | ||
6 | |||
7 | The nan, nanf and nanl functions handle payload strings by doing e.g.: | ||
8 | |||
9 | if (tagp[0] != '\0') | ||
10 | { | ||
11 | char buf[6 + strlen (tagp)]; | ||
12 | sprintf (buf, "NAN(%s)", tagp); | ||
13 | return strtod (buf, NULL); | ||
14 | } | ||
15 | |||
16 | This is an unbounded stack allocation based on the length of the | ||
17 | argument. Furthermore, if the argument starts with an n-char-sequence | ||
18 | followed by ')', that n-char-sequence is wrongly treated as | ||
19 | significant for determining the payload of the resulting NaN, when ISO | ||
20 | C says the call should be equivalent to strtod ("NAN", NULL), without | ||
21 | being affected by that initial n-char-sequence. This patch fixes both | ||
22 | those problems by using the __strtod_nan etc. functions recently | ||
23 | factored out of strtod etc. for that purpose, with those functions | ||
24 | being exported from libc at version GLIBC_PRIVATE. | ||
25 | |||
26 | Tested for x86_64, x86, mips64 and powerpc. | ||
27 | |||
28 | [BZ #16961] | ||
29 | [BZ #16962] | ||
30 | * math/s_nan.c (__nan): Use __strtod_nan instead of constructing a | ||
31 | string on the stack for strtod. | ||
32 | * math/s_nanf.c (__nanf): Use __strtof_nan instead of constructing | ||
33 | a string on the stack for strtof. | ||
34 | * math/s_nanl.c (__nanl): Use __strtold_nan instead of | ||
35 | constructing a string on the stack for strtold. | ||
36 | * stdlib/Versions (libc): Add __strtof_nan, __strtod_nan and | ||
37 | __strtold_nan to GLIBC_PRIVATE. | ||
38 | * math/test-nan-overflow.c: New file. | ||
39 | * math/test-nan-payload.c: Likewise. | ||
40 | * math/Makefile (tests): Add test-nan-overflow and | ||
41 | test-nan-payload. | ||
42 | |||
43 | Upstream-Status: Backport | ||
44 | CVE: CVE-2015-9761 patch #2 | ||
45 | [Yocto # 8980] | ||
46 | |||
47 | https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=8f5e8b01a1da2a207228f2072c934fa5918554b8 | ||
48 | |||
49 | Signed-off-by: Armin Kuster <akuster@mvista.com> | ||
50 | |||
51 | --- | ||
52 | ChangeLog | 17 +++++++ | ||
53 | NEWS | 6 +++ | ||
54 | math/Makefile | 3 +- | ||
55 | math/s_nan.c | 9 +--- | ||
56 | math/s_nanf.c | 9 +--- | ||
57 | math/s_nanl.c | 9 +--- | ||
58 | math/test-nan-overflow.c | 66 +++++++++++++++++++++++++ | ||
59 | math/test-nan-payload.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++ | ||
60 | stdlib/Versions | 1 + | ||
61 | 9 files changed, 217 insertions(+), 25 deletions(-) | ||
62 | create mode 100644 math/test-nan-overflow.c | ||
63 | create mode 100644 math/test-nan-payload.c | ||
64 | |||
65 | Index: git/ChangeLog | ||
66 | =================================================================== | ||
67 | --- git.orig/ChangeLog | ||
68 | +++ git/ChangeLog | ||
69 | @@ -1,3 +1,20 @@ | ||
70 | +2015-12-04 Joseph Myers <joseph@codesourcery.com> | ||
71 | + | ||
72 | + [BZ #16961] | ||
73 | + [BZ #16962] | ||
74 | + * math/s_nan.c (__nan): Use __strtod_nan instead of constructing a | ||
75 | + string on the stack for strtod. | ||
76 | + * math/s_nanf.c (__nanf): Use __strtof_nan instead of constructing | ||
77 | + a string on the stack for strtof. | ||
78 | + * math/s_nanl.c (__nanl): Use __strtold_nan instead of | ||
79 | + constructing a string on the stack for strtold. | ||
80 | + * stdlib/Versions (libc): Add __strtof_nan, __strtod_nan and | ||
81 | + __strtold_nan to GLIBC_PRIVATE. | ||
82 | + * math/test-nan-overflow.c: New file. | ||
83 | + * math/test-nan-payload.c: Likewise. | ||
84 | + * math/Makefile (tests): Add test-nan-overflow and | ||
85 | + test-nan-payload. | ||
86 | + | ||
87 | 2015-11-24 Joseph Myers <joseph@codesourcery.com> | ||
88 | |||
89 | * stdlib/strtod_nan.c: New file. | ||
90 | Index: git/NEWS | ||
91 | =================================================================== | ||
92 | --- git.orig/NEWS | ||
93 | +++ git/NEWS | ||
94 | @@ -7,6 +7,12 @@ using `glibc' in the "product" field. | ||
95 | |||
96 | Version 2.21 | ||
97 | |||
98 | +Security related changes: | ||
99 | + | ||
100 | +* The nan, nanf and nanl functions no longer have unbounded stack usage | ||
101 | + depending on the length of the string passed as an argument to the | ||
102 | + functions. Reported by Joseph Myers. | ||
103 | + | ||
104 | * The following bugs are resolved with this release: | ||
105 | |||
106 | 6652, 10672, 12674, 12847, 12926, 13862, 14132, 14138, 14171, 14498, | ||
107 | Index: git/math/s_nan.c | ||
108 | =================================================================== | ||
109 | --- git.orig/math/s_nan.c | ||
110 | +++ git/math/s_nan.c | ||
111 | @@ -28,14 +28,7 @@ | ||
112 | double | ||
113 | __nan (const char *tagp) | ||
114 | { | ||
115 | - if (tagp[0] != '\0') | ||
116 | - { | ||
117 | - char buf[6 + strlen (tagp)]; | ||
118 | - sprintf (buf, "NAN(%s)", tagp); | ||
119 | - return strtod (buf, NULL); | ||
120 | - } | ||
121 | - | ||
122 | - return NAN; | ||
123 | + return __strtod_nan (tagp, NULL, 0); | ||
124 | } | ||
125 | weak_alias (__nan, nan) | ||
126 | #ifdef NO_LONG_DOUBLE | ||
127 | Index: git/math/s_nanf.c | ||
128 | =================================================================== | ||
129 | --- git.orig/math/s_nanf.c | ||
130 | +++ git/math/s_nanf.c | ||
131 | @@ -28,13 +28,6 @@ | ||
132 | float | ||
133 | __nanf (const char *tagp) | ||
134 | { | ||
135 | - if (tagp[0] != '\0') | ||
136 | - { | ||
137 | - char buf[6 + strlen (tagp)]; | ||
138 | - sprintf (buf, "NAN(%s)", tagp); | ||
139 | - return strtof (buf, NULL); | ||
140 | - } | ||
141 | - | ||
142 | - return NAN; | ||
143 | + return __strtof_nan (tagp, NULL, 0); | ||
144 | } | ||
145 | weak_alias (__nanf, nanf) | ||
146 | Index: git/math/s_nanl.c | ||
147 | =================================================================== | ||
148 | --- git.orig/math/s_nanl.c | ||
149 | +++ git/math/s_nanl.c | ||
150 | @@ -28,13 +28,6 @@ | ||
151 | long double | ||
152 | __nanl (const char *tagp) | ||
153 | { | ||
154 | - if (tagp[0] != '\0') | ||
155 | - { | ||
156 | - char buf[6 + strlen (tagp)]; | ||
157 | - sprintf (buf, "NAN(%s)", tagp); | ||
158 | - return strtold (buf, NULL); | ||
159 | - } | ||
160 | - | ||
161 | - return NAN; | ||
162 | + return __strtold_nan (tagp, NULL, 0); | ||
163 | } | ||
164 | weak_alias (__nanl, nanl) | ||
165 | Index: git/math/test-nan-overflow.c | ||
166 | =================================================================== | ||
167 | --- /dev/null | ||
168 | +++ git/math/test-nan-overflow.c | ||
169 | @@ -0,0 +1,66 @@ | ||
170 | +/* Test nan functions stack overflow (bug 16962). | ||
171 | + Copyright (C) 2015 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 <math.h> | ||
189 | +#include <stdio.h> | ||
190 | +#include <string.h> | ||
191 | +#include <sys/resource.h> | ||
192 | + | ||
193 | +#define STACK_LIM 1048576 | ||
194 | +#define STRING_SIZE (2 * STACK_LIM) | ||
195 | + | ||
196 | +static int | ||
197 | +do_test (void) | ||
198 | +{ | ||
199 | + int result = 0; | ||
200 | + struct rlimit lim; | ||
201 | + getrlimit (RLIMIT_STACK, &lim); | ||
202 | + lim.rlim_cur = STACK_LIM; | ||
203 | + setrlimit (RLIMIT_STACK, &lim); | ||
204 | + char *nanstr = malloc (STRING_SIZE); | ||
205 | + if (nanstr == NULL) | ||
206 | + { | ||
207 | + puts ("malloc failed, cannot test"); | ||
208 | + return 77; | ||
209 | + } | ||
210 | + memset (nanstr, '0', STRING_SIZE - 1); | ||
211 | + nanstr[STRING_SIZE - 1] = 0; | ||
212 | +#define NAN_TEST(TYPE, FUNC) \ | ||
213 | + do \ | ||
214 | + { \ | ||
215 | + char *volatile p = nanstr; \ | ||
216 | + volatile TYPE v = FUNC (p); \ | ||
217 | + if (isnan (v)) \ | ||
218 | + puts ("PASS: " #FUNC); \ | ||
219 | + else \ | ||
220 | + { \ | ||
221 | + puts ("FAIL: " #FUNC); \ | ||
222 | + result = 1; \ | ||
223 | + } \ | ||
224 | + } \ | ||
225 | + while (0) | ||
226 | + NAN_TEST (float, nanf); | ||
227 | + NAN_TEST (double, nan); | ||
228 | +#ifndef NO_LONG_DOUBLE | ||
229 | + NAN_TEST (long double, nanl); | ||
230 | +#endif | ||
231 | + return result; | ||
232 | +} | ||
233 | + | ||
234 | +#define TEST_FUNCTION do_test () | ||
235 | +#include "../test-skeleton.c" | ||
236 | Index: git/math/test-nan-payload.c | ||
237 | =================================================================== | ||
238 | --- /dev/null | ||
239 | +++ git/math/test-nan-payload.c | ||
240 | @@ -0,0 +1,122 @@ | ||
241 | +/* Test nan functions payload handling (bug 16961). | ||
242 | + Copyright (C) 2015 Free Software Foundation, Inc. | ||
243 | + This file is part of the GNU C Library. | ||
244 | + | ||
245 | + The GNU C Library is free software; you can redistribute it and/or | ||
246 | + modify it under the terms of the GNU Lesser General Public | ||
247 | + License as published by the Free Software Foundation; either | ||
248 | + version 2.1 of the License, or (at your option) any later version. | ||
249 | + | ||
250 | + The GNU C Library is distributed in the hope that it will be useful, | ||
251 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
252 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
253 | + Lesser General Public License for more details. | ||
254 | + | ||
255 | + You should have received a copy of the GNU Lesser General Public | ||
256 | + License along with the GNU C Library; if not, see | ||
257 | + <http://www.gnu.org/licenses/>. */ | ||
258 | + | ||
259 | +#include <float.h> | ||
260 | +#include <math.h> | ||
261 | +#include <stdio.h> | ||
262 | +#include <stdlib.h> | ||
263 | +#include <string.h> | ||
264 | + | ||
265 | +/* Avoid built-in functions. */ | ||
266 | +#define WRAP_NAN(FUNC, STR) \ | ||
267 | + ({ const char *volatile wns = (STR); FUNC (wns); }) | ||
268 | +#define WRAP_STRTO(FUNC, STR) \ | ||
269 | + ({ const char *volatile wss = (STR); FUNC (wss, NULL); }) | ||
270 | + | ||
271 | +#define CHECK_IS_NAN(TYPE, A) \ | ||
272 | + do \ | ||
273 | + { \ | ||
274 | + if (isnan (A)) \ | ||
275 | + puts ("PASS: " #TYPE " " #A); \ | ||
276 | + else \ | ||
277 | + { \ | ||
278 | + puts ("FAIL: " #TYPE " " #A); \ | ||
279 | + result = 1; \ | ||
280 | + } \ | ||
281 | + } \ | ||
282 | + while (0) | ||
283 | + | ||
284 | +#define CHECK_SAME_NAN(TYPE, A, B) \ | ||
285 | + do \ | ||
286 | + { \ | ||
287 | + if (memcmp (&(A), &(B), sizeof (A)) == 0) \ | ||
288 | + puts ("PASS: " #TYPE " " #A " = " #B); \ | ||
289 | + else \ | ||
290 | + { \ | ||
291 | + puts ("FAIL: " #TYPE " " #A " = " #B); \ | ||
292 | + result = 1; \ | ||
293 | + } \ | ||
294 | + } \ | ||
295 | + while (0) | ||
296 | + | ||
297 | +#define CHECK_DIFF_NAN(TYPE, A, B) \ | ||
298 | + do \ | ||
299 | + { \ | ||
300 | + if (memcmp (&(A), &(B), sizeof (A)) != 0) \ | ||
301 | + puts ("PASS: " #TYPE " " #A " != " #B); \ | ||
302 | + else \ | ||
303 | + { \ | ||
304 | + puts ("FAIL: " #TYPE " " #A " != " #B); \ | ||
305 | + result = 1; \ | ||
306 | + } \ | ||
307 | + } \ | ||
308 | + while (0) | ||
309 | + | ||
310 | +/* Cannot test payloads by memcmp for formats where NaNs have padding | ||
311 | + bits. */ | ||
312 | +#define CAN_TEST_EQ(MANT_DIG) ((MANT_DIG) != 64 && (MANT_DIG) != 106) | ||
313 | + | ||
314 | +#define RUN_TESTS(TYPE, SFUNC, FUNC, MANT_DIG) \ | ||
315 | + do \ | ||
316 | + { \ | ||
317 | + TYPE n123 = WRAP_NAN (FUNC, "123"); \ | ||
318 | + CHECK_IS_NAN (TYPE, n123); \ | ||
319 | + TYPE s123 = WRAP_STRTO (SFUNC, "NAN(123)"); \ | ||
320 | + CHECK_IS_NAN (TYPE, s123); \ | ||
321 | + TYPE n456 = WRAP_NAN (FUNC, "456"); \ | ||
322 | + CHECK_IS_NAN (TYPE, n456); \ | ||
323 | + TYPE s456 = WRAP_STRTO (SFUNC, "NAN(456)"); \ | ||
324 | + CHECK_IS_NAN (TYPE, s456); \ | ||
325 | + TYPE n123x = WRAP_NAN (FUNC, "123)"); \ | ||
326 | + CHECK_IS_NAN (TYPE, n123x); \ | ||
327 | + TYPE nemp = WRAP_NAN (FUNC, ""); \ | ||
328 | + CHECK_IS_NAN (TYPE, nemp); \ | ||
329 | + TYPE semp = WRAP_STRTO (SFUNC, "NAN()"); \ | ||
330 | + CHECK_IS_NAN (TYPE, semp); \ | ||
331 | + TYPE sx = WRAP_STRTO (SFUNC, "NAN"); \ | ||
332 | + CHECK_IS_NAN (TYPE, sx); \ | ||
333 | + if (CAN_TEST_EQ (MANT_DIG)) \ | ||
334 | + CHECK_SAME_NAN (TYPE, n123, s123); \ | ||
335 | + if (CAN_TEST_EQ (MANT_DIG)) \ | ||
336 | + CHECK_SAME_NAN (TYPE, n456, s456); \ | ||
337 | + if (CAN_TEST_EQ (MANT_DIG)) \ | ||
338 | + CHECK_SAME_NAN (TYPE, nemp, semp); \ | ||
339 | + if (CAN_TEST_EQ (MANT_DIG)) \ | ||
340 | + CHECK_SAME_NAN (TYPE, n123x, sx); \ | ||
341 | + CHECK_DIFF_NAN (TYPE, n123, n456); \ | ||
342 | + CHECK_DIFF_NAN (TYPE, n123, nemp); \ | ||
343 | + CHECK_DIFF_NAN (TYPE, n123, n123x); \ | ||
344 | + CHECK_DIFF_NAN (TYPE, n456, nemp); \ | ||
345 | + CHECK_DIFF_NAN (TYPE, n456, n123x); \ | ||
346 | + } \ | ||
347 | + while (0) | ||
348 | + | ||
349 | +static int | ||
350 | +do_test (void) | ||
351 | +{ | ||
352 | + int result = 0; | ||
353 | + RUN_TESTS (float, strtof, nanf, FLT_MANT_DIG); | ||
354 | + RUN_TESTS (double, strtod, nan, DBL_MANT_DIG); | ||
355 | +#ifndef NO_LONG_DOUBLE | ||
356 | + RUN_TESTS (long double, strtold, nanl, LDBL_MANT_DIG); | ||
357 | +#endif | ||
358 | + return result; | ||
359 | +} | ||
360 | + | ||
361 | +#define TEST_FUNCTION do_test () | ||
362 | +#include "../test-skeleton.c" | ||
363 | Index: git/stdlib/Versions | ||
364 | =================================================================== | ||
365 | --- git.orig/stdlib/Versions | ||
366 | +++ git/stdlib/Versions | ||
367 | @@ -118,5 +118,6 @@ libc { | ||
368 | # Used from other libraries | ||
369 | __libc_secure_getenv; | ||
370 | __call_tls_dtors; | ||
371 | + __strtof_nan; __strtod_nan; __strtold_nan; | ||
372 | } | ||
373 | } | ||
374 | Index: git/math/Makefile | ||
375 | =================================================================== | ||
376 | --- git.orig/math/Makefile | ||
377 | +++ git/math/Makefile | ||
378 | @@ -92,7 +92,9 @@ tests = test-matherr test-fenv atest-exp | ||
379 | test-misc test-fpucw test-fpucw-ieee tst-definitions test-tgmath \ | ||
380 | test-tgmath-ret bug-nextafter bug-nexttoward bug-tgmath1 \ | ||
381 | test-tgmath-int test-tgmath2 test-powl tst-CMPLX tst-CMPLX2 test-snan \ | ||
382 | - test-fenv-tls test-fenv-preserve test-fenv-return $(tests-static) | ||
383 | + test-fenv-tls test-fenv-preserve test-fenv-return \ | ||
384 | + test-nan-overflow test-nan-payload \ | ||
385 | + $(tests-static) | ||
386 | tests-static = test-fpucw-static test-fpucw-ieee-static | ||
387 | # We do the `long double' tests only if this data type is available and | ||
388 | # distinct from `double'. | ||