]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/glibc/glibc-rh847932.patch
Merge branch 'next' into fifteen
[people/teissler/ipfire-2.x.git] / src / patches / glibc / glibc-rh847932.patch
1 diff -Nrup a/stdlib/Makefile b/stdlib/Makefile
2 --- a/stdlib/Makefile 2010-05-04 05:27:23.000000000 -0600
3 +++ b/stdlib/Makefile 2012-08-15 09:25:37.812443006 -0600
4 @@ -71,7 +71,7 @@ tests := tst-strtol tst-strtod testmb t
5 tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \
6 tst-makecontext tst-strtod4 tst-strtod5 tst-qsort2 \
7 tst-makecontext2 tst-strtod6 tst-unsetenv1 \
8 - tst-makecontext3
9 + tst-makecontext3 tst-strtod-overflow
10
11 include ../Makeconfig
12
13 diff -Nrup a/stdlib/strtod_l.c b/stdlib/strtod_l.c
14 --- a/stdlib/strtod_l.c 2010-05-04 05:27:23.000000000 -0600
15 +++ b/stdlib/strtod_l.c 2012-08-15 09:34:29.550281346 -0600
16 @@ -62,6 +62,7 @@ extern unsigned long long int ____strtou
17 #include <math.h>
18 #include <stdlib.h>
19 #include <string.h>
20 +#include <stdint.h>
21
22 /* The gmp headers need some configuration frobs. */
23 #define HAVE_ALLOCA 1
24 @@ -176,19 +177,19 @@ extern const mp_limb_t _tens_in_limb[MAX
25 /* Return a floating point number of the needed type according to the given
26 multi-precision number after possible rounding. */
27 static FLOAT
28 -round_and_return (mp_limb_t *retval, int exponent, int negative,
29 +round_and_return (mp_limb_t *retval, intmax_t exponent, int negative,
30 mp_limb_t round_limb, mp_size_t round_bit, int more_bits)
31 {
32 if (exponent < MIN_EXP - 1)
33 {
34 - mp_size_t shift = MIN_EXP - 1 - exponent;
35 -
36 - if (shift > MANT_DIG)
37 + if (exponent < MIN_EXP - 1 - MANT_DIG)
38 {
39 __set_errno (EDOM);
40 return 0.0;
41 }
42
43 + mp_size_t shift = MIN_EXP - 1 - exponent;
44 +
45 more_bits |= (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0;
46 if (shift == MANT_DIG)
47 /* This is a special case to handle the very seldom case where
48 @@ -235,6 +236,9 @@ round_and_return (mp_limb_t *retval, int
49 __set_errno (ERANGE);
50 }
51
52 + if (exponent > MAX_EXP)
53 + goto overflow;
54 +
55 if ((round_limb & (((mp_limb_t) 1) << round_bit)) != 0
56 && (more_bits || (retval[0] & 1) != 0
57 || (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0))
58 @@ -260,6 +264,7 @@ round_and_return (mp_limb_t *retval, int
59 }
60
61 if (exponent > MAX_EXP)
62 + overflow:
63 return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
64
65 return MPN2FLOAT (retval, exponent, negative);
66 @@ -273,7 +278,7 @@ round_and_return (mp_limb_t *retval, int
67 factor for the resulting number (see code) multiply by it. */
68 static const STRING_TYPE *
69 str_to_mpn (const STRING_TYPE *str, int digcnt, mp_limb_t *n, mp_size_t *nsize,
70 - int *exponent
71 + intmax_t *exponent
72 #ifndef USE_WIDE_CHAR
73 , const char *decimal, size_t decimal_len, const char *thousands
74 #endif
75 @@ -337,7 +342,7 @@ str_to_mpn (const STRING_TYPE *str, int
76 }
77 while (--digcnt > 0);
78
79 - if (*exponent > 0 && cnt + *exponent <= MAX_DIG_PER_LIMB)
80 + if (*exponent > 0 && *exponent <= MAX_DIG_PER_LIMB - cnt)
81 {
82 low *= _tens_in_limb[*exponent];
83 start = _tens_in_limb[cnt + *exponent];
84 @@ -415,7 +420,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
85 {
86 int negative; /* The sign of the number. */
87 MPN_VAR (num); /* MP representation of the number. */
88 - int exponent; /* Exponent of the number. */
89 + intmax_t exponent; /* Exponent of the number. */
90
91 /* Numbers starting `0X' or `0x' have to be processed with base 16. */
92 int base = 10;
93 @@ -437,7 +442,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
94 /* Points at the character following the integer and fractional digits. */
95 const STRING_TYPE *expp;
96 /* Total number of digit and number of digits in integer part. */
97 - int dig_no, int_no, lead_zero;
98 + size_t dig_no, int_no, lead_zero;
99 /* Contains the last character read. */
100 CHAR_TYPE c;
101
102 @@ -769,7 +774,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
103 are all or any is really a fractional digit will be decided
104 later. */
105 int_no = dig_no;
106 - lead_zero = int_no == 0 ? -1 : 0;
107 + lead_zero = int_no == 0 ? (size_t) -1 : 0;
108
109 /* Read the fractional digits. A special case are the 'american
110 style' numbers like `16.' i.e. with decimal point but without
111 @@ -791,12 +796,13 @@ ____STRTOF_INTERNAL (nptr, endptr, group
112 (base == 16 && ({ CHAR_TYPE lo = TOLOWER (c);
113 lo >= L_('a') && lo <= L_('f'); })))
114 {
115 - if (c != L_('0') && lead_zero == -1)
116 + if (c != L_('0') && lead_zero == (size_t) -1)
117 lead_zero = dig_no - int_no;
118 ++dig_no;
119 c = *++cp;
120 }
121 }
122 + assert (dig_no <= (uintmax_t) INTMAX_MAX);
123
124 /* Remember start of exponent (if any). */
125 expp = cp;
126 @@ -819,24 +825,80 @@ ____STRTOF_INTERNAL (nptr, endptr, group
127
128 if (c >= L_('0') && c <= L_('9'))
129 {
130 - int exp_limit;
131 + intmax_t exp_limit;
132
133 /* Get the exponent limit. */
134 if (base == 16)
135 - exp_limit = (exp_negative ?
136 - -MIN_EXP + MANT_DIG + 4 * int_no :
137 - MAX_EXP - 4 * int_no + 4 * lead_zero + 3);
138 + {
139 + if (exp_negative)
140 + {
141 + assert (int_no <= (uintmax_t) (INTMAX_MAX
142 + + MIN_EXP - MANT_DIG) / 4);
143 + exp_limit = -MIN_EXP + MANT_DIG + 4 * (intmax_t) int_no;
144 + }
145 + else
146 + {
147 + if (int_no)
148 + {
149 + assert (lead_zero == 0
150 + && int_no <= (uintmax_t) INTMAX_MAX / 4);
151 + exp_limit = MAX_EXP - 4 * (intmax_t) int_no + 3;
152 + }
153 + else if (lead_zero == (size_t) -1)
154 + {
155 + /* The number is zero and this limit is
156 + arbitrary. */
157 + exp_limit = MAX_EXP + 3;
158 + }
159 + else
160 + {
161 + assert (lead_zero
162 + <= (uintmax_t) (INTMAX_MAX - MAX_EXP - 3) / 4);
163 + exp_limit = (MAX_EXP
164 + + 4 * (intmax_t) lead_zero
165 + + 3);
166 + }
167 + }
168 + }
169 else
170 - exp_limit = (exp_negative ?
171 - -MIN_10_EXP + MANT_DIG + int_no :
172 - MAX_10_EXP - int_no + lead_zero + 1);
173 + {
174 + if (exp_negative)
175 + {
176 + assert (int_no
177 + <= (uintmax_t) (INTMAX_MAX + MIN_10_EXP - MANT_DIG));
178 + exp_limit = -MIN_10_EXP + MANT_DIG + (intmax_t) int_no;
179 + }
180 + else
181 + {
182 + if (int_no)
183 + {
184 + assert (lead_zero == 0
185 + && int_no <= (uintmax_t) INTMAX_MAX);
186 + exp_limit = MAX_10_EXP - (intmax_t) int_no + 1;
187 + }
188 + else if (lead_zero == (size_t) -1)
189 + {
190 + /* The number is zero and this limit is
191 + arbitrary. */
192 + exp_limit = MAX_10_EXP + 1;
193 + }
194 + else
195 + {
196 + assert (lead_zero
197 + <= (uintmax_t) (INTMAX_MAX - MAX_10_EXP - 1));
198 + exp_limit = MAX_10_EXP + (intmax_t) lead_zero + 1;
199 + }
200 + }
201 + }
202 +
203 + if (exp_limit < 0)
204 + exp_limit = 0;
205
206 do
207 {
208 - exponent *= 10;
209 - exponent += c - L_('0');
210 -
211 - if (__builtin_expect (exponent > exp_limit, 0))
212 + if (__builtin_expect ((exponent > exp_limit / 10
213 + || (exponent == exp_limit / 10
214 + && c - L_('0') > exp_limit % 10)), 0))
215 /* The exponent is too large/small to represent a valid
216 number. */
217 {
218 @@ -845,7 +907,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
219 /* We have to take care for special situation: a joker
220 might have written "0.0e100000" which is in fact
221 zero. */
222 - if (lead_zero == -1)
223 + if (lead_zero == (size_t) -1)
224 result = negative ? -0.0 : 0.0;
225 else
226 {
227 @@ -864,6 +926,9 @@ ____STRTOF_INTERNAL (nptr, endptr, group
228 /* NOTREACHED */
229 }
230
231 + exponent *= 10;
232 + exponent += c - L_('0');
233 +
234 c = *++cp;
235 }
236 while (c >= L_('0') && c <= L_('9'));
237 @@ -932,7 +997,14 @@ ____STRTOF_INTERNAL (nptr, endptr, group
238 }
239 #endif
240 startp += lead_zero + decimal_len;
241 - exponent -= base == 16 ? 4 * lead_zero : lead_zero;
242 + assert (lead_zero <= (base == 16
243 + ? (uintmax_t) INTMAX_MAX / 4
244 + : (uintmax_t) INTMAX_MAX));
245 + assert (lead_zero <= (base == 16
246 + ? ((uintmax_t) exponent
247 + - (uintmax_t) INTMAX_MIN) / 4
248 + : ((uintmax_t) exponent - (uintmax_t) INTMAX_MIN)));
249 + exponent -= base == 16 ? 4 * (intmax_t) lead_zero : (intmax_t) lead_zero;
250 dig_no -= lead_zero;
251 }
252
253 @@ -974,7 +1046,10 @@ ____STRTOF_INTERNAL (nptr, endptr, group
254 }
255
256 /* Adjust the exponent for the bits we are shifting in. */
257 - exponent += bits - 1 + (int_no - 1) * 4;
258 + assert (int_no <= (uintmax_t) (exponent < 0
259 + ? (INTMAX_MAX - bits + 1) / 4
260 + : (INTMAX_MAX - exponent - bits + 1) / 4));
261 + exponent += bits - 1 + ((intmax_t) int_no - 1) * 4;
262
263 while (--dig_no > 0 && idx >= 0)
264 {
265 @@ -1014,13 +1089,15 @@ ____STRTOF_INTERNAL (nptr, endptr, group
266 really integer digits or belong to the fractional part; i.e. we normalize
267 123e-2 to 1.23. */
268 {
269 - register int incr = (exponent < 0 ? MAX (-int_no, exponent)
270 - : MIN (dig_no - int_no, exponent));
271 + register intmax_t incr = (exponent < 0
272 + ? MAX (-(intmax_t) int_no, exponent)
273 + : MIN ((intmax_t) dig_no - (intmax_t) int_no,
274 + exponent));
275 int_no += incr;
276 exponent -= incr;
277 }
278
279 - if (__builtin_expect (int_no + exponent > MAX_10_EXP + 1, 0))
280 + if (__builtin_expect (exponent > MAX_10_EXP + 1 - (intmax_t) int_no, 0))
281 {
282 __set_errno (ERANGE);
283 return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
284 @@ -1205,7 +1282,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
285 digits we should have enough bits for the result. The remaining
286 decimal digits give us the information that more bits are following.
287 This can be used while rounding. (Two added as a safety margin.) */
288 - if (dig_no - int_no > (MANT_DIG - bits + 2) / 3 + 2)
289 + if ((intmax_t) dig_no > (intmax_t) int_no + (MANT_DIG - bits + 2) / 3 + 2)
290 {
291 dig_no = int_no + (MANT_DIG - bits + 2) / 3 + 2;
292 more_bits = 1;
293 @@ -1213,7 +1290,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group
294 else
295 more_bits = 0;
296
297 - neg_exp = dig_no - int_no - exponent;
298 + neg_exp = (intmax_t) dig_no - (intmax_t) int_no - exponent;
299
300 /* Construct the denominator. */
301 densize = 0;
302 @@ -1491,7 +1568,9 @@ ____STRTOF_INTERNAL (nptr, endptr, group
303 register int i;
304 (void) __mpn_lshift (&retval[used
305 / BITS_PER_MP_LIMB],
306 - retval, RETURN_LIMB_SIZE,
307 + retval,
308 + (RETURN_LIMB_SIZE
309 + - used / BITS_PER_MP_LIMB),
310 used % BITS_PER_MP_LIMB);
311 for (i = used / BITS_PER_MP_LIMB - 1; i >= 0; --i)
312 retval[i] = 0;
313 diff -Nrup a/stdlib/tst-strtod-overflow.c b/stdlib/tst-strtod-overflow.c
314 --- a/stdlib/tst-strtod-overflow.c 1969-12-31 17:00:00.000000000 -0700
315 +++ b/stdlib/tst-strtod-overflow.c 2012-08-15 09:25:01.098592764 -0600
316 @@ -0,0 +1,48 @@
317 +/* Test for integer/buffer overflow in strtod.
318 + Copyright (C) 2012 Free Software Foundation, Inc.
319 + This file is part of the GNU C Library.
320 +
321 + The GNU C Library is free software; you can redistribute it and/or
322 + modify it under the terms of the GNU Lesser General Public
323 + License as published by the Free Software Foundation; either
324 + version 2.1 of the License, or (at your option) any later version.
325 +
326 + The GNU C Library is distributed in the hope that it will be useful,
327 + but WITHOUT ANY WARRANTY; without even the implied warranty of
328 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
329 + Lesser General Public License for more details.
330 +
331 + You should have received a copy of the GNU Lesser General Public
332 + License along with the GNU C Library; if not, see
333 + <http://www.gnu.org/licenses/>. */
334 +
335 +#include <stdio.h>
336 +#include <stdlib.h>
337 +#include <string.h>
338 +
339 +#define EXPONENT "e-2147483649"
340 +#define SIZE 214748364
341 +
342 +static int
343 +do_test (void)
344 +{
345 + char *p = malloc (1 + SIZE + sizeof (EXPONENT));
346 + if (p == NULL)
347 + {
348 + puts ("malloc failed, cannot test for overflow");
349 + return 0;
350 + }
351 + p[0] = '1';
352 + memset (p + 1, '0', SIZE);
353 + memcpy (p + 1 + SIZE, EXPONENT, sizeof (EXPONENT));
354 + double d = strtod (p, NULL);
355 + if (d != 0)
356 + {
357 + printf ("strtod returned wrong value: %a\n", d);
358 + return 1;
359 + }
360 + return 0;
361 +}
362 +
363 +#define TEST_FUNCTION do_test ()
364 +#include "../test-skeleton.c"