]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/glibc/glibc-rh681054.patch
Merge branch 'kernel-update' of ssh://git.ipfire.org/pub/git/ipfire-2.x into kernel...
[ipfire-2.x.git] / src / patches / glibc / glibc-rh681054.patch
CommitLineData
12788f63
MT
12011-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
72010-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
162010-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
22Index: 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
57Index: 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
182Index: 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
494Index: 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