]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/glibc/glibc-rh681054.patch
Merge branch 'iptables-upnpfw' into core67-merge
[ipfire-2.x.git] / src / patches / glibc / glibc-rh681054.patch
1 2011-03-18 Ulrich Drepper <drepper@gmail.com>
2
3 * posix/fnmatch.c (fnmatch): Check size of pattern in wide
4 character representation.
5 Partly based on a patch by Tomas Hoger <thoger@redhat.com>.
6
7 2010-11-11 Andreas Schwab <schwab@redhat.com>
8
9 * posix/fnmatch_loop.c (NEW_PATTERN): Fix use of alloca.
10 * posix/Makefile (tests): Add $(objpfx)tst-fnmatch-mem.
11 (tst-fnmatch-ENV): Set MALLOC_TRACE.
12 ($(objpfx)tst-fnmatch-mem): New rule.
13 (generated): Add tst-fnmatch-mem and tst-fnmatch.mtrace.
14 * posix/tst-fnmatch.c (main): Call mtrace.
15
16 2010-08-09 Ulrich Drepper <drepper@redhat.com>
17
18 [BZ #11883]
19 * posix/fnmatch.c: Keep track of alloca use and fall back on malloc.
20 * posix/fnmatch_loop.c: Likewise.
21
22 Index: glibc-2.12-2-gc4ccff1/posix/Makefile
23 ===================================================================
24 --- glibc-2.12-2-gc4ccff1.orig/posix/Makefile
25 +++ glibc-2.12-2-gc4ccff1/posix/Makefile
26 @@ -114,7 +114,8 @@ generated := $(addprefix wordexp-test-re
27 tst-rxspencer-mem tst-rxspencer.mtrace tst-getconf.out \
28 tst-pcre-mem tst-pcre.mtrace tst-boost-mem tst-boost.mtrace \
29 bug-ga2.mtrace bug-ga2-mem bug-glob2.mtrace bug-glob2-mem \
30 - tst-vfork3-mem tst-vfork3.mtrace getconf.speclist
31 + tst-vfork3-mem tst-vfork3.mtrace getconf.speclist \
32 + tst-fnmatch-mem tst-fnmatch.mtrace
33
34 include ../Rules
35
36 @@ -226,7 +227,7 @@ ifeq (no,$(cross-compiling))
37 tests: $(objpfx)bug-regex2-mem $(objpfx)bug-regex14-mem \
38 $(objpfx)bug-regex21-mem $(objpfx)tst-rxspencer-mem \
39 $(objpfx)tst-pcre-mem $(objpfx)tst-boost-mem $(objpfx)tst-getconf.out \
40 - $(objpfx)bug-glob2-mem $(objpfx)tst-vfork3-mem
41 + $(objpfx)bug-glob2-mem $(objpfx)tst-vfork3-mem $(objpfx)tst-fnmatch-mem
42 xtests: $(objpfx)bug-ga2-mem
43 endif
44
45 @@ -238,6 +239,11 @@ annexc-CFLAGS = -O
46 $(objpfx)annexc: annexc.c
47 $(native-compile)
48
49 +tst-fnmatch-ENV += MALLOC_TRACE=$(objpfx)tst-fnmatch.mtrace
50 +
51 +$(objpfx)tst-fnmatch-mem: $(objpfx)tst-fnmatch.out
52 + $(common-objpfx)malloc/mtrace $(objpfx)tst-fnmatch.mtrace > $@
53 +
54 bug-regex2-ENV = MALLOC_TRACE=$(objpfx)bug-regex2.mtrace
55
56 $(objpfx)bug-regex2-mem: $(objpfx)bug-regex2.out
57 Index: glibc-2.12-2-gc4ccff1/posix/fnmatch.c
58 ===================================================================
59 --- glibc-2.12-2-gc4ccff1.orig/posix/fnmatch.c
60 +++ glibc-2.12-2-gc4ccff1/posix/fnmatch.c
61 @@ -41,6 +41,12 @@
62 # include <stdlib.h>
63 #endif
64
65 +#ifdef _LIBC
66 +# include <alloca.h>
67 +#else
68 +# define alloca_account(size., var) alloca (size)
69 +#endif
70 +
71 /* For platform which support the ISO C amendement 1 functionality we
72 support user defined character classes. */
73 #if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
74 @@ -330,8 +336,11 @@ fnmatch (pattern, string, flags)
75 mbstate_t ps;
76 size_t n;
77 const char *p;
78 + wchar_t *wpattern_malloc = NULL;
79 wchar_t *wpattern;
80 + wchar_t *wstring_malloc = NULL;
81 wchar_t *wstring;
82 + size_t alloca_used = 0;
83
84 /* Convert the strings into wide characters. */
85 memset (&ps, '\0', sizeof (ps));
86 @@ -343,7 +352,8 @@ fnmatch (pattern, string, flags)
87 #endif
88 if (__builtin_expect (n < 1024, 1))
89 {
90 - wpattern = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
91 + wpattern = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
92 + alloca_used);
93 n = mbsrtowcs (wpattern, &p, n + 1, &ps);
94 if (__builtin_expect (n == (size_t) -1, 0))
95 /* Something wrong.
96 @@ -365,8 +375,16 @@ fnmatch (pattern, string, flags)
97 XXX Do we have to set `errno' to something which mbsrtows hasn't
98 already done? */
99 return -1;
100 - wpattern = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
101 + if (__builtin_expect (n >= (size_t) -1 / sizeof (wchar_t), 0))
102 + {
103 + __set_errno (ENOMEM);
104 + return -2;
105 + }
106 + wpattern_malloc = wpattern
107 + = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
108 assert (mbsinit (&ps));
109 + if (wpattern == NULL)
110 + return -2;
111 (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps);
112 }
113
114 @@ -379,13 +397,18 @@ fnmatch (pattern, string, flags)
115 p = string;
116 if (__builtin_expect (n < 1024, 1))
117 {
118 - wstring = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
119 + wstring = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t),
120 + alloca_used);
121 n = mbsrtowcs (wstring, &p, n + 1, &ps);
122 if (__builtin_expect (n == (size_t) -1, 0))
123 - /* Something wrong.
124 - XXX Do we have to set `errno' to something which mbsrtows hasn't
125 - already done? */
126 - return -1;
127 + {
128 + /* Something wrong.
129 + XXX Do we have to set `errno' to something which
130 + mbsrtows hasn't already done? */
131 + free_return:
132 + free (wpattern_malloc);
133 + return -1;
134 + }
135 if (p)
136 {
137 memset (&ps, '\0', sizeof (ps));
138 @@ -400,19 +423,38 @@ fnmatch (pattern, string, flags)
139 /* Something wrong.
140 XXX Do we have to set `errno' to something which mbsrtows hasn't
141 already done? */
142 - return -1;
143 - wstring = (wchar_t *) alloca ((n + 1) * sizeof (wchar_t));
144 + goto free_return;
145 + if (__builtin_expect (n >= (size_t) -1 / sizeof (wchar_t), 0))
146 + {
147 + free (wpattern_malloc);
148 + __set_errno (ENOMEM);
149 + return -2;
150 + }
151 +
152 + wstring_malloc = wstring
153 + = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t));
154 + if (wstring == NULL)
155 + {
156 + free (wpattern_malloc);
157 + return -2;
158 + }
159 assert (mbsinit (&ps));
160 (void) mbsrtowcs (wstring, &string, n + 1, &ps);
161 }
162
163 - return internal_fnwmatch (wpattern, wstring, wstring + n,
164 - flags & FNM_PERIOD, flags, NULL);
165 + int res = internal_fnwmatch (wpattern, wstring, wstring + n,
166 + flags & FNM_PERIOD, flags, NULL,
167 + alloca_used);
168 +
169 + free (wstring_malloc);
170 + free (wpattern_malloc);
171 +
172 + return res;
173 }
174 # endif /* mbstate_t and mbsrtowcs or _LIBC. */
175
176 return internal_fnmatch (pattern, string, string + strlen (string),
177 - flags & FNM_PERIOD, flags, NULL);
178 + flags & FNM_PERIOD, flags, NULL, 0);
179 }
180
181 # ifdef _LIBC
182 Index: glibc-2.12-2-gc4ccff1/posix/fnmatch_loop.c
183 ===================================================================
184 --- glibc-2.12-2-gc4ccff1.orig/posix/fnmatch_loop.c
185 +++ glibc-2.12-2-gc4ccff1/posix/fnmatch_loop.c
186 @@ -28,22 +28,24 @@ struct STRUCT
187 it matches, nonzero if not. */
188 static int FCT (const CHAR *pattern, const CHAR *string,
189 const CHAR *string_end, int no_leading_period, int flags,
190 - struct STRUCT *ends)
191 + struct STRUCT *ends, size_t alloca_used)
192 internal_function;
193 static int EXT (INT opt, const CHAR *pattern, const CHAR *string,
194 - const CHAR *string_end, int no_leading_period, int flags)
195 + const CHAR *string_end, int no_leading_period, int flags,
196 + size_t alloca_used)
197 internal_function;
198 static const CHAR *END (const CHAR *patternp) internal_function;
199
200 static int
201 internal_function
202 -FCT (pattern, string, string_end, no_leading_period, flags, ends)
203 +FCT (pattern, string, string_end, no_leading_period, flags, ends, alloca_used)
204 const CHAR *pattern;
205 const CHAR *string;
206 const CHAR *string_end;
207 int no_leading_period;
208 int flags;
209 struct STRUCT *ends;
210 + size_t alloca_used;
211 {
212 register const CHAR *p = pattern, *n = string;
213 register UCHAR c;
214 @@ -67,10 +69,8 @@ FCT (pattern, string, string_end, no_lea
215 case L('?'):
216 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
217 {
218 - int res;
219 -
220 - res = EXT (c, p, n, string_end, no_leading_period,
221 - flags);
222 + int res = EXT (c, p, n, string_end, no_leading_period,
223 + flags, alloca_used);
224 if (res != -1)
225 return res;
226 }
227 @@ -99,10 +99,8 @@ FCT (pattern, string, string_end, no_lea
228 case L('*'):
229 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
230 {
231 - int res;
232 -
233 - res = EXT (c, p, n, string_end, no_leading_period,
234 - flags);
235 + int res = EXT (c, p, n, string_end, no_leading_period,
236 + flags, alloca_used);
237 if (res != -1)
238 return res;
239 }
240 @@ -191,7 +189,7 @@ FCT (pattern, string, string_end, no_lea
241
242 for (--p; n < endp; ++n, no_leading_period = 0)
243 if (FCT (p, n, string_end, no_leading_period, flags2,
244 - &end) == 0)
245 + &end, alloca_used) == 0)
246 goto found;
247 }
248 else if (c == L('/') && (flags & FNM_FILE_NAME))
249 @@ -200,7 +198,7 @@ FCT (pattern, string, string_end, no_lea
250 ++n;
251 if (n < string_end && *n == L('/')
252 && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags,
253 - NULL) == 0))
254 + NULL, alloca_used) == 0))
255 return 0;
256 }
257 else
258 @@ -214,7 +212,7 @@ FCT (pattern, string, string_end, no_lea
259 for (--p; n < endp; ++n, no_leading_period = 0)
260 if (FOLD ((UCHAR) *n) == c
261 && (FCT (p, n, string_end, no_leading_period, flags2,
262 - &end) == 0))
263 + &end, alloca_used) == 0))
264 {
265 found:
266 if (end.pattern == NULL)
267 @@ -749,7 +747,7 @@ FCT (pattern, string, string_end, no_lea
268 _NL_COLLATE_SYMB_EXTRAMB);
269
270 /* Locate the character in the hashing
271 - table. */
272 + table. */
273 hash = elem_hash (str, c1);
274
275 idx = 0;
276 @@ -971,9 +969,8 @@ FCT (pattern, string, string_end, no_lea
277 case L('!'):
278 if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(')
279 {
280 - int res;
281 -
282 - res = EXT (c, p, n, string_end, no_leading_period, flags);
283 + int res = EXT (c, p, n, string_end, no_leading_period, flags,
284 + alloca_used);
285 if (res != -1)
286 return res;
287 }
288 @@ -1052,26 +1049,32 @@ END (const CHAR *pattern)
289 static int
290 internal_function
291 EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
292 - int no_leading_period, int flags)
293 + int no_leading_period, int flags, size_t alloca_used)
294 {
295 const CHAR *startp;
296 int level;
297 struct patternlist
298 {
299 struct patternlist *next;
300 + CHAR malloced;
301 CHAR str[0];
302 } *list = NULL;
303 struct patternlist **lastp = &list;
304 size_t pattern_len = STRLEN (pattern);
305 + int any_malloced = 0;
306 const CHAR *p;
307 const CHAR *rs;
308 + int retval = 0;
309
310 /* Parse the pattern. Store the individual parts in the list. */
311 level = 0;
312 for (startp = p = pattern + 1; level >= 0; ++p)
313 if (*p == L('\0'))
314 - /* This is an invalid pattern. */
315 - return -1;
316 + {
317 + /* This is an invalid pattern. */
318 + retval = -1;
319 + goto out;
320 + }
321 else if (*p == L('['))
322 {
323 /* Handle brackets special. */
324 @@ -1088,8 +1091,11 @@ EXT (INT opt, const CHAR *pattern, const
325 /* Skip over all characters of the list. */
326 while (*p != L(']'))
327 if (*p++ == L('\0'))
328 - /* This is no valid pattern. */
329 - return -1;
330 + {
331 + /* This is no valid pattern. */
332 + retval = -1;
333 + goto out;
334 + }
335 }
336 else if ((*p == L('?') || *p == L('*') || *p == L('+') || *p == L('@')
337 || *p == L('!')) && p[1] == L('('))
338 @@ -1102,15 +1108,25 @@ EXT (INT opt, const CHAR *pattern, const
339 /* This means we found the end of the pattern. */
340 #define NEW_PATTERN \
341 struct patternlist *newp; \
342 - \
343 - if (opt == L('?') || opt == L('@')) \
344 - newp = alloca (sizeof (struct patternlist) \
345 - + (pattern_len * sizeof (CHAR))); \
346 + size_t slen = (opt == L('?') || opt == L('@') \
347 + ? pattern_len : (p - startp + 1)); \
348 + slen = sizeof (struct patternlist) + (slen * sizeof (CHAR)); \
349 + int malloced = ! __libc_use_alloca (alloca_used + slen); \
350 + if (__builtin_expect (malloced, 0)) \
351 + { \
352 + newp = malloc (slen); \
353 + if (newp == NULL) \
354 + { \
355 + retval = -2; \
356 + goto out; \
357 + } \
358 + any_malloced = 1; \
359 + } \
360 else \
361 - newp = alloca (sizeof (struct patternlist) \
362 - + ((p - startp + 1) * sizeof (CHAR))); \
363 - *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \
364 + newp = alloca_account (slen, alloca_used); \
365 newp->next = NULL; \
366 + newp->malloced = malloced; \
367 + *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \
368 *lastp = newp; \
369 lastp = &newp->next
370 NEW_PATTERN;
371 @@ -1131,8 +1147,9 @@ EXT (INT opt, const CHAR *pattern, const
372 switch (opt)
373 {
374 case L('*'):
375 - if (FCT (p, string, string_end, no_leading_period, flags, NULL) == 0)
376 - return 0;
377 + if (FCT (p, string, string_end, no_leading_period, flags, NULL,
378 + alloca_used) == 0)
379 + goto success;
380 /* FALLTHROUGH */
381
382 case L('+'):
383 @@ -1143,7 +1160,7 @@ EXT (INT opt, const CHAR *pattern, const
384 current pattern. */
385 if (FCT (list->str, string, rs, no_leading_period,
386 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD,
387 - NULL) == 0
388 + NULL, alloca_used) == 0
389 /* This was successful. Now match the rest with the rest
390 of the pattern. */
391 && (FCT (p, rs, string_end,
392 @@ -1151,7 +1168,7 @@ EXT (INT opt, const CHAR *pattern, const
393 ? no_leading_period
394 : rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0,
395 flags & FNM_FILE_NAME
396 - ? flags : flags & ~FNM_PERIOD, NULL) == 0
397 + ? flags : flags & ~FNM_PERIOD, NULL, alloca_used) == 0
398 /* This didn't work. Try the whole pattern. */
399 || (rs != string
400 && FCT (pattern - 1, rs, string_end,
401 @@ -1160,18 +1177,21 @@ EXT (INT opt, const CHAR *pattern, const
402 : (rs[-1] == '/' && NO_LEADING_PERIOD (flags)
403 ? 1 : 0),
404 flags & FNM_FILE_NAME
405 - ? flags : flags & ~FNM_PERIOD, NULL) == 0)))
406 + ? flags : flags & ~FNM_PERIOD, NULL,
407 + alloca_used) == 0)))
408 /* It worked. Signal success. */
409 - return 0;
410 + goto success;
411 }
412 while ((list = list->next) != NULL);
413
414 /* None of the patterns lead to a match. */
415 - return FNM_NOMATCH;
416 + retval = FNM_NOMATCH;
417 + break;
418
419 case L('?'):
420 - if (FCT (p, string, string_end, no_leading_period, flags, NULL) == 0)
421 - return 0;
422 + if (FCT (p, string, string_end, no_leading_period, flags, NULL,
423 + alloca_used) == 0)
424 + goto success;
425 /* FALLTHROUGH */
426
427 case L('@'):
428 @@ -1183,13 +1203,14 @@ EXT (INT opt, const CHAR *pattern, const
429 if (FCT (STRCAT (list->str, p), string, string_end,
430 no_leading_period,
431 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD,
432 - NULL) == 0)
433 + NULL, alloca_used) == 0)
434 /* It worked. Signal success. */
435 - return 0;
436 + goto success;
437 while ((list = list->next) != NULL);
438
439 /* None of the patterns lead to a match. */
440 - return FNM_NOMATCH;
441 + retval = FNM_NOMATCH;
442 + break;
443
444 case L('!'):
445 for (rs = string; rs <= string_end; ++rs)
446 @@ -1199,7 +1220,7 @@ EXT (INT opt, const CHAR *pattern, const
447 for (runp = list; runp != NULL; runp = runp->next)
448 if (FCT (runp->str, string, rs, no_leading_period,
449 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD,
450 - NULL) == 0)
451 + NULL, alloca_used) == 0)
452 break;
453
454 /* If none of the patterns matched see whether the rest does. */
455 @@ -1209,21 +1230,34 @@ EXT (INT opt, const CHAR *pattern, const
456 ? no_leading_period
457 : rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0,
458 flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD,
459 - NULL) == 0))
460 + NULL, alloca_used) == 0))
461 /* This is successful. */
462 - return 0;
463 + goto success;
464 }
465
466 /* None of the patterns together with the rest of the pattern
467 lead to a match. */
468 - return FNM_NOMATCH;
469 + retval = FNM_NOMATCH;
470 + break;
471
472 default:
473 assert (! "Invalid extended matching operator");
474 + retval = -1;
475 break;
476 }
477
478 - return -1;
479 + success:
480 + out:
481 + if (any_malloced)
482 + while (list != NULL)
483 + {
484 + struct patternlist *old = list;
485 + list = list->next;
486 + if (old->malloced)
487 + free (old);
488 + }
489 +
490 + return retval;
491 }
492
493
494 Index: glibc-2.12-2-gc4ccff1/posix/tst-fnmatch.c
495 ===================================================================
496 --- glibc-2.12-2-gc4ccff1.orig/posix/tst-fnmatch.c
497 +++ glibc-2.12-2-gc4ccff1/posix/tst-fnmatch.c
498 @@ -25,6 +25,7 @@
499 #include <stdlib.h>
500 #include <string.h>
501 #include <sys/types.h>
502 +#include <mcheck.h>
503
504
505 static char *next_input (char **line, int first, int last);
506 @@ -46,6 +47,8 @@ main (void)
507 size_t escpatternlen = 0;
508 int nr = 0;
509
510 + mtrace ();
511 +
512 /* Read lines from stdin with the following format:
513
514 locale input-string match-string flags result