Browse code

glibc: Fix for CVE-2017-15671

Change-Id: Iead6760682ded29e264c5444c0ea0bca7ae0d26c
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/5469
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>
Reviewed-by: Sharath George

Keerthana K authored on 2018/08/09 23:57:49
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,2220 @@
0
+2017-10-21  Florian Weimer  <fweimer@redhat.com>
1
+
2
+	* posix/Makefile (tests): Add tst-glob-tilde.
3
+	(tests-special): Add tst-glob-tilde-mem.out
4
+	(tst-glob-tilde-ENV): Set MALLOC_TRACE.
5
+	(tst-glob-tilde-mem.out): Add mtrace check.
6
+	* posix/tst-glob-tilde.c: New file.
7
+
8
+2017-09-08  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
9
+
10
+	[BZ #1062]
11
+	[BZ #22325]
12
+	CVE-2017-15671
13
+	* posix/Makefile (routines): Add globfree, globfree64, and
14
+	glob_pattern_p.
15
+	* posix/flexmember.h: New file.
16
+	* posix/glob_internal.h: Likewise.
17
+	* posix/glob_pattern_p.c: Likewise.
18
+	* posix/globfree.c: Likewise.
19
+	* posix/globfree64.c: Likewise.
20
+	* sysdeps/gnu/globfree64.c: Likewise.
21
+	* sysdeps/unix/sysv/linux/alpha/globfree.c: Likewise.
22
+	* sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c: Likewise.
23
+	* sysdeps/unix/sysv/linux/oldglob.c: Likewise.
24
+	* sysdeps/unix/sysv/linux/wordsize-64/globfree64.c: Likewise.
25
+	* sysdeps/unix/sysv/linux/x86_64/x32/globfree.c: Likewise.
26
+	* sysdeps/wordsize-64/globfree.c: Likewise.
27
+	* sysdeps/wordsize-64/globfree64.c: Likewise.
28
+	* posix/glob.c (HAVE_CONFIG_H): Use !_LIBC instead.
29
+	[NDEBUG): Remove comments.
30
+	(GLOB_ONLY_P, _AMIGA, VMS): Remove define.
31
+	(dirent_type): New type.  Use uint_fast8_t not
32
+	uint8_t, as C99 does not require uint8_t.
33
+	(DT_UNKNOWN, DT_DIR, DT_LNK): New macros.
34
+	(struct readdir_result): Use dirent_type.  Do not define skip_entry
35
+	unless it is needed; this saves a byte on platforms lacking d_ino.
36
+	(readdir_result_type, readdir_result_skip_entry):
37
+	New functions, replacing ...
38
+	(readdir_result_might_be_symlink, readdir_result_might_be_dir):
39
+	 these functions, which were removed.  This makes the callers
40
+	easier to read.  All callers changed.
41
+	(D_INO_TO_RESULT): Now empty if there is no d_ino.
42
+	(size_add_wrapv, glob_use_alloca): New static functions.
43
+	(glob, glob_in_dir): Check for size_t overflow in several places,
44
+	and fix some size_t checks that were not quite right.
45
+	Remove old code using SHELL since Bash no longer
46
+	uses this.
47
+	(glob, prefix_array): Separate MS code better.
48
+	(glob_in_dir): Remove old Amiga and VMS code.
49
+	(globfree, __glob_pattern_type, __glob_pattern_p): Move to
50
+	separate files.
51
+	(glob_in_dir): Do not rely on undefined behavior in accessing
52
+	struct members beyond their bounds.  Use a flexible array member
53
+	instead
54
+	(link_stat): Rename from link_exists2_p and return -1/0 instead of
55
+	0/1.  Caller changed.
56
+	(glob): Fix memory leaks.
57
+	* posix/glob64 (globfree64): Move to separate file.
58
+	* sysdeps/gnu/glob64.c (NO_GLOB_PATTERN_P): Remove define.
59
+	(globfree64): Remove hidden alias.
60
+	* sysdeps/unix/sysv/linux/Makefile (sysdeps_routines): Add
61
+	oldglob.
62
+	* sysdeps/unix/sysv/linux/alpha/glob.c (__new_globfree): Move to
63
+	separate file.
64
+	* sysdeps/unix/sysv/linux/i386/glob64.c (NO_GLOB_PATTERN_P): Remove
65
+	define.
66
+	Move compat code to separate file.
67
+	* sysdeps/wordsize-64/glob.c (globfree): Move definitions to
68
+	separate file.
69
+
70
+2017-08-20  H.J. Lu  <hongjiu.lu@intel.com>
71
+
72
+	[BZ #18822]
73
+	* sysdeps/unix/sysv/linux/i386/glob64.c (__old_glob64): Add
74
+	libc_hidden_proto and libc_hidden_def.
75
+
76
+Index: glibc-2.22/posix/Makefile
77
+===================================================================
78
+--- glibc-2.22.orig/posix/Makefile
79
+@@ -43,7 +43,7 @@ routines :=								      \
80
+ 	getpgid setpgid getpgrp bsd-getpgrp setpgrp getsid setsid	      \
81
+ 	getresuid getresgid setresuid setresgid				      \
82
+ 	pathconf sysconf fpathconf					      \
83
+-	glob glob64 fnmatch regex					      \
84
++	glob glob64 globfree globfree64 glob_pattern_p fnmatch regex	      \
85
+ 	confstr								      \
86
+ 	getopt getopt1 getopt_init					      \
87
+ 	sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax  \
88
+@@ -87,7 +87,7 @@ tests		:= tstgetopt testfnm runtests run
89
+ 		   bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
90
+ 		   bug-getopt5 tst-getopt_long1 bug-regex34 bug-regex35 \
91
+ 		   tst-pathconf tst-getaddrinfo4 tst-rxspencer-no-utf8 \
92
+-		   tst-fnmatch3 bug-regex36 tst-getaddrinfo5
93
++		   tst-fnmatch3 bug-regex36 tst-getaddrinfo5 tst-glob-tilde
94
+ xtests		:= bug-ga2
95
+ ifeq (yes,$(build-shared))
96
+ test-srcs	:= globtest
97
+@@ -130,7 +130,8 @@ tests-special += $(objpfx)bug-regex2-mem
98
+ 		 $(objpfx)tst-rxspencer-no-utf8-mem.out $(objpfx)tst-pcre-mem.out \
99
+ 		 $(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \
100
+ 		 $(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \
101
+-		 $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out
102
++		 $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out \
103
++		 $(objpfx)tst-glob-tilde-mem.out
104
+ xtests-special += $(objpfx)bug-ga2-mem.out
105
+ endif
106
+ 
107
+@@ -307,6 +308,12 @@ $(objpfx)bug-glob2-mem.out: $(objpfx)bug
108
+ 	$(common-objpfx)malloc/mtrace $(objpfx)bug-glob2.mtrace > $@; \
109
+ 	$(evaluate-test)
110
+ 
111
++tst-glob-tilde-ENV = MALLOC_TRACE=$(objpfx)tst-glob-tilde.mtrace
112
++
113
++$(objpfx)tst-glob-tilde-mem.out: $(objpfx)tst-glob-tilde.out
114
++	$(common-objpfx)malloc/mtrace $(objpfx)tst-glob-tilde.mtrace > $@; \
115
++	$(evaluate-test)
116
++
117
+ $(inst_libexecdir)/getconf: $(inst_bindir)/getconf \
118
+ 			    $(objpfx)getconf.speclist FORCE
119
+ 	$(addprefix $(..)./scripts/mkinstalldirs ,\
120
+Index: glibc-2.22/posix/flexmember.h
121
+===================================================================
122
+--- /dev/null
123
+@@ -0,0 +1,45 @@
124
++/* Sizes of structs with flexible array members.
125
++
126
++   Copyright 2016-2017 Free Software Foundation, Inc.
127
++
128
++   This file is part of the GNU C Library.
129
++
130
++   The GNU C Library is free software; you can redistribute it and/or
131
++   modify it under the terms of the GNU Lesser General Public
132
++   License as published by the Free Software Foundation; either
133
++   version 2.1 of the License, or (at your option) any later version.
134
++
135
++   The GNU C Library is distributed in the hope that it will be useful,
136
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
137
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
138
++   Lesser General Public License for more details.
139
++
140
++   You should have received a copy of the GNU Lesser General Public
141
++   License along with the GNU C Library; if not, see
142
++   <http://www.gnu.org/licenses/>.
143
++
144
++   Written by Paul Eggert.  */
145
++
146
++#include <stddef.h>
147
++
148
++/* Nonzero multiple of alignment of TYPE, suitable for FLEXSIZEOF below.
149
++   On older platforms without _Alignof, use a pessimistic bound that is
150
++   safe in practice even if FLEXIBLE_ARRAY_MEMBER is 1.
151
++   On newer platforms, use _Alignof to get a tighter bound.  */
152
++
153
++#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
154
++# define FLEXALIGNOF(type) (sizeof (type) & ~ (sizeof (type) - 1))
155
++#else
156
++# define FLEXALIGNOF(type) _Alignof (type)
157
++#endif
158
++
159
++/* Upper bound on the size of a struct of type TYPE with a flexible
160
++   array member named MEMBER that is followed by N bytes of other data.
161
++   This is not simply sizeof (TYPE) + N, since it may require
162
++   alignment on unusually picky C11 platforms, and
163
++   FLEXIBLE_ARRAY_MEMBER may be 1 on pre-C11 platforms.
164
++   Yield a value less than N if and only if arithmetic overflow occurs.  */
165
++
166
++#define FLEXSIZEOF(type, member, n) \
167
++   ((offsetof (type, member) + FLEXALIGNOF (type) - 1 + (n)) \
168
++    & ~ (FLEXALIGNOF (type) - 1))
169
+Index: glibc-2.22/posix/glob.c
170
+===================================================================
171
+--- glibc-2.22.orig/posix/glob.c
172
+@@ -15,7 +15,7 @@
173
+    License along with the GNU C Library; if not, see
174
+    <http://www.gnu.org/licenses/>.  */
175
+ 
176
+-#ifdef	HAVE_CONFIG_H
177
++#ifndef _LIBC
178
+ # include <config.h>
179
+ #endif
180
+ 
181
+@@ -27,29 +27,15 @@
182
+ #include <stdbool.h>
183
+ #include <stddef.h>
184
+ #include <stdint.h>
185
+-
186
+-/* Outcomment the following line for production quality code.  */
187
+-/* #define NDEBUG 1 */
188
+ #include <assert.h>
189
++#include <unistd.h>
190
+ 
191
+-#include <stdio.h>		/* Needed on stupid SunOS for assert.  */
192
+-
193
+-#if !defined _LIBC || !defined GLOB_ONLY_P
194
+-#if defined HAVE_UNISTD_H || defined _LIBC
195
+-# include <unistd.h>
196
+-# ifndef POSIX
197
+-#  ifdef _POSIX_VERSION
198
+-#   define POSIX
199
+-#  endif
200
+-# endif
201
++#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
202
++# define WINDOWS32
203
+ #endif
204
+ 
205
+-#include <pwd.h>
206
+-
207
+-#if defined HAVE_STDINT_H || defined _LIBC
208
+-# include <stdint.h>
209
+-#elif !defined UINTPTR_MAX
210
+-# define UINTPTR_MAX (~((size_t) 0))
211
++#ifndef WINDOWS32
212
++# include <pwd.h>
213
+ #endif
214
+ 
215
+ #include <errno.h>
216
+@@ -57,24 +43,7 @@
217
+ # define __set_errno(val) errno = (val)
218
+ #endif
219
+ 
220
+-#if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
221
+-# include <dirent.h>
222
+-#else
223
+-# define dirent direct
224
+-# ifdef HAVE_SYS_NDIR_H
225
+-#  include <sys/ndir.h>
226
+-# endif
227
+-# ifdef HAVE_SYS_DIR_H
228
+-#  include <sys/dir.h>
229
+-# endif
230
+-# ifdef HAVE_NDIR_H
231
+-#  include <ndir.h>
232
+-# endif
233
+-# ifdef HAVE_VMSDIR_H
234
+-#  include "vmsdir.h"
235
+-# endif /* HAVE_VMSDIR_H */
236
+-#endif
237
+-
238
++#include <dirent.h>
239
+ #include <stdlib.h>
240
+ #include <string.h>
241
+ #include <alloca.h>
242
+@@ -87,27 +56,29 @@
243
+ # define opendir(name) __opendir (name)
244
+ # define readdir(str) __readdir64 (str)
245
+ # define getpwnam_r(name, bufp, buf, len, res) \
246
+-   __getpwnam_r (name, bufp, buf, len, res)
247
++    __getpwnam_r (name, bufp, buf, len, res)
248
+ # ifndef __stat64
249
+ #  define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf)
250
+ # endif
251
+ # define struct_stat64		struct stat64
252
++# define FLEXIBLE_ARRAY_MEMBER
253
+ #else /* !_LIBC */
254
+-# include "getlogin_r.h"
255
+-# include "mempcpy.h"
256
+-# include "stat-macros.h"
257
+-# include "strdup.h"
258
+-# define __stat64(fname, buf)	stat (fname, buf)
259
+-# define struct_stat64		struct stat
260
+-# define __stat(fname, buf)	stat (fname, buf)
261
+-# define __alloca		alloca
262
+-# define __readdir		readdir
263
+-# define __readdir64		readdir64
264
+-# define __glob_pattern_p	glob_pattern_p
265
++# define __getlogin_r(buf, len) getlogin_r (buf, len)
266
++# define __stat64(fname, buf)   stat (fname, buf)
267
++# define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag)
268
++# define struct_stat64          struct stat
269
++# ifndef __MVS__
270
++#  define __alloca              alloca
271
++# endif
272
++# define __readdir              readdir
273
++# define COMPILE_GLOB64
274
+ #endif /* _LIBC */
275
+ 
276
+ #include <fnmatch.h>
277
+ 
278
++#include <flexmember.h>
279
++#include <glob_internal.h>
280
++
281
+ #ifdef _SC_GETPW_R_SIZE_MAX
282
+ # define GETPW_R_SIZE_MAX()	sysconf (_SC_GETPW_R_SIZE_MAX)
283
+ #else
284
+@@ -121,61 +92,59 @@
285
+ 
286
+ static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
287
+ 
288
++typedef uint_fast8_t dirent_type;
289
++
290
++#if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE
291
++/* Any distinct values will do here.
292
++   Undef any existing macros out of the way.  */
293
++# undef DT_UNKNOWN
294
++# undef DT_DIR
295
++# undef DT_LNK
296
++# define DT_UNKNOWN 0
297
++# define DT_DIR 1
298
++# define DT_LNK 2
299
++#endif
300
++
301
+ /* A representation of a directory entry which does not depend on the
302
+    layout of struct dirent, or the size of ino_t.  */
303
+ struct readdir_result
304
+ {
305
+   const char *name;
306
+-# if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
307
+-  uint8_t type;
308
+-# endif
309
++#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
310
++  dirent_type type;
311
++#endif
312
++#if defined _LIBC || defined D_INO_IN_DIRENT
313
+   bool skip_entry;
314
++#endif
315
+ };
316
+ 
317
+-# if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
318
+-/* Initializer based on the d_type member of struct dirent.  */
319
+-#  define D_TYPE_TO_RESULT(source) (source)->d_type,
320
+-
321
+-/* True if the directory entry D might be a symbolic link.  */
322
+-static bool
323
+-readdir_result_might_be_symlink (struct readdir_result d)
324
+-{
325
+-  return d.type == DT_UNKNOWN || d.type == DT_LNK;
326
+-}
327
+-
328
+-/* True if the directory entry D might be a directory.  */
329
+-static bool
330
+-readdir_result_might_be_dir (struct readdir_result d)
331
++/* Initialize and return type member of struct readdir_result.  */
332
++static dirent_type
333
++readdir_result_type (struct readdir_result d)
334
+ {
335
+-  return d.type == DT_DIR || readdir_result_might_be_symlink (d);
336
+-}
337
+-# else /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */
338
+-#  define D_TYPE_TO_RESULT(source)
339
+-
340
+-/* If we do not have type information, symbolic links and directories
341
+-   are always a possibility.  */
342
+-
343
+-static bool
344
+-readdir_result_might_be_symlink (struct readdir_result d)
345
+-{
346
+-  return true;
347
++#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
348
++# define D_TYPE_TO_RESULT(source) (source)->d_type,
349
++  return d.type;
350
++#else
351
++# define D_TYPE_TO_RESULT(source)
352
++  return DT_UNKNOWN;
353
++#endif
354
+ }
355
+ 
356
++/* Initialize and return skip_entry member of struct readdir_result.  */
357
+ static bool
358
+-readdir_result_might_be_dir (struct readdir_result d)
359
++readdir_result_skip_entry (struct readdir_result d)
360
+ {
361
+-  return true;
362
+-}
363
+-
364
+-# endif /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */
365
+-
366
+-# if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
367
+ /* Initializer for skip_entry.  POSIX does not require that the d_ino
368
+    field be present, and some systems do not provide it. */
369
+-#  define D_INO_TO_RESULT(source) false,
370
+-# else
371
+-#  define D_INO_TO_RESULT(source) (source)->d_ino == 0,
372
+-# endif
373
++#if defined _LIBC || defined D_INO_IN_DIRENT
374
++# define D_INO_TO_RESULT(source) (source)->d_ino == 0,
375
++  return d.skip_entry;
376
++#else
377
++# define D_INO_TO_RESULT(source)
378
++  return false;
379
++#endif
380
++}
381
+ 
382
+ /* Construct an initializer for a struct readdir_result object from a
383
+    struct dirent *.  No copy of the name is made.  */
384
+@@ -186,8 +155,6 @@ readdir_result_might_be_dir (struct read
385
+     D_INO_TO_RESULT (source)		   \
386
+   }
387
+ 
388
+-#endif /* !defined _LIBC || !defined GLOB_ONLY_P */
389
+-
390
+ /* Call gl_readdir on STREAM.  This macro can be overridden to reduce
391
+    type safety if an old interface version needs to be supported.  */
392
+ #ifndef GL_READDIR
393
+@@ -225,18 +192,55 @@ convert_dirent64 (const struct dirent64
394
+ }
395
+ #endif
396
+ 
397
++#ifndef _LIBC
398
++/* The results of opendir() in this file are not used with dirfd and fchdir,
399
++   and we do not leak fds to any single-threaded code that could use stdio,
400
++   therefore save some unnecessary recursion in fchdir.c and opendir_safer.c.
401
++   FIXME - if the kernel ever adds support for multi-thread safety for
402
++   avoiding standard fds, then we should use opendir_safer.  */
403
++# ifdef GNULIB_defined_opendir
404
++#  undef opendir
405
++# endif
406
++# ifdef GNULIB_defined_closedir
407
++#  undef closedir
408
++# endif
409
+ 
410
+-#ifndef attribute_hidden
411
+-# define attribute_hidden
412
++/* Just use malloc.  */
413
++# define __libc_use_alloca(n) false
414
++# define alloca_account(len, avar) ((void) (len), (void) (avar), (void *) 0)
415
++# define extend_alloca_account(buf, len, newlen, avar) \
416
++    ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0)
417
+ #endif
418
+ 
419
++/* Set *R = A + B.  Return true if the answer is mathematically
420
++   incorrect due to overflow; in this case, *R is the low order
421
++   bits of the correct answer.  */
422
++
423
++static bool
424
++size_add_wrapv (size_t a, size_t b, size_t *r)
425
++{
426
++#if 5 <= __GNUC__ && !defined __ICC
427
++  return __builtin_add_overflow (a, b, r);
428
++#else
429
++  *r = a + b;
430
++  return *r < a;
431
++#endif
432
++}
433
++
434
++static bool
435
++glob_use_alloca (size_t alloca_used, size_t len)
436
++{
437
++  size_t size;
438
++  return (!size_add_wrapv (alloca_used, len, &size)
439
++          && __libc_use_alloca (size));
440
++}
441
++
442
+ static int glob_in_dir (const char *pattern, const char *directory,
443
+ 			int flags, int (*errfunc) (const char *, int),
444
+ 			glob_t *pglob, size_t alloca_used);
445
+ extern int __glob_pattern_type (const char *pattern, int quote)
446
+     attribute_hidden;
447
+ 
448
+-#if !defined _LIBC || !defined GLOB_ONLY_P
449
+ static int prefix_array (const char *prefix, char **array, size_t n) __THROWNL;
450
+ static int collated_compare (const void *, const void *) __THROWNL;
451
+ 
452
+@@ -265,16 +269,15 @@ next_brace_sub (const char *cp, int flag
453
+   return *cp != '\0' ? cp : NULL;
454
+ }
455
+ 
456
+-#endif /* !defined _LIBC || !defined GLOB_ONLY_P */
457
+ 
458
+ /* Do glob searching for PATTERN, placing results in PGLOB.
459
+    The bits defined above may be set in FLAGS.
460
+    If a directory cannot be opened or read and ERRFUNC is not nil,
461
+    it is called with the pathname that caused the error, and the
462
+-   `errno' value from the failing call; if it returns non-zero
463
+-   `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
464
++   'errno' value from the failing call; if it returns non-zero
465
++   'glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
466
+    If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
467
+-   Otherwise, `glob' returns zero.  */
468
++   Otherwise, 'glob' returns zero.  */
469
+ int
470
+ #ifdef GLOB_ATTRIBUTE
471
+ GLOB_ATTRIBUTE
472
+@@ -295,9 +298,7 @@ glob (pattern, flags, errfunc, pglob)
473
+   int malloc_dirname = 0;
474
+   glob_t dirs;
475
+   int retval = 0;
476
+-#ifdef _LIBC
477
+   size_t alloca_used = 0;
478
+-#endif
479
+ 
480
+   if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
481
+     {
482
+@@ -311,7 +312,7 @@ glob (pattern, flags, errfunc, pglob)
483
+     flags |= GLOB_ONLYDIR;
484
+ 
485
+   if (!(flags & GLOB_DOOFFS))
486
+-    /* Have to do this so `globfree' knows where to start freeing.  It
487
++    /* Have to do this so 'globfree' knows where to start freeing.  It
488
+        also makes all the code that uses gl_offs simpler. */
489
+     pglob->gl_offs = 0;
490
+ 
491
+@@ -353,14 +354,12 @@ glob (pattern, flags, errfunc, pglob)
492
+ 	  size_t rest_len;
493
+ 	  char *onealt;
494
+ 	  size_t pattern_len = strlen (pattern) - 1;
495
+-#ifdef _LIBC
496
+-	  int alloca_onealt = __libc_use_alloca (alloca_used + pattern_len);
497
++	  int alloca_onealt = glob_use_alloca (alloca_used, pattern_len);
498
+ 	  if (alloca_onealt)
499
+ 	    onealt = alloca_account (pattern_len, alloca_used);
500
+ 	  else
501
+-#endif
502
+ 	    {
503
+-	      onealt = (char *) malloc (pattern_len);
504
++	      onealt = malloc (pattern_len);
505
+ 	      if (onealt == NULL)
506
+ 		{
507
+ 		  if (!(flags & GLOB_APPEND))
508
+@@ -380,11 +379,9 @@ glob (pattern, flags, errfunc, pglob)
509
+ 	  next = next_brace_sub (begin + 1, flags);
510
+ 	  if (next == NULL)
511
+ 	    {
512
+-	      /* It is an illegal expression.  */
513
++	      /* It is an invalid expression.  */
514
+ 	    illegal_brace:
515
+-#ifdef _LIBC
516
+ 	      if (__glibc_unlikely (!alloca_onealt))
517
+-#endif
518
+ 		free (onealt);
519
+ 	      return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
520
+ 	    }
521
+@@ -432,9 +429,7 @@ glob (pattern, flags, errfunc, pglob)
522
+ 	      /* If we got an error, return it.  */
523
+ 	      if (result && result != GLOB_NOMATCH)
524
+ 		{
525
+-#ifdef _LIBC
526
+ 		  if (__glibc_unlikely (!alloca_onealt))
527
+-#endif
528
+ 		    free (onealt);
529
+ 		  if (!(flags & GLOB_APPEND))
530
+ 		    {
531
+@@ -453,9 +448,7 @@ glob (pattern, flags, errfunc, pglob)
532
+ 	      assert (next != NULL);
533
+ 	    }
534
+ 
535
+-#ifdef _LIBC
536
+ 	  if (__glibc_unlikely (!alloca_onealt))
537
+-#endif
538
+ 	    free (onealt);
539
+ 
540
+ 	  if (pglob->gl_pathc != firstc)
541
+@@ -492,14 +485,16 @@ glob (pattern, flags, errfunc, pglob)
542
+ 
543
+   /* Find the filename.  */
544
+   filename = strrchr (pattern, '/');
545
++
546
+ #if defined __MSDOS__ || defined WINDOWS32
547
+-  /* The case of "d:pattern".  Since `:' is not allowed in
548
++  /* The case of "d:pattern".  Since ':' is not allowed in
549
+      file names, we can safely assume that wherever it
550
+      happens in pattern, it signals the filename part.  This
551
+      is so we could some day support patterns like "[a-z]:foo".  */
552
+   if (filename == NULL)
553
+     filename = strchr (pattern, ':');
554
+ #endif /* __MSDOS__ || WINDOWS32 */
555
++
556
+   dirname_modified = 0;
557
+   if (filename == NULL)
558
+     {
559
+@@ -524,11 +519,7 @@ glob (pattern, flags, errfunc, pglob)
560
+ 	    }
561
+ 
562
+ 	  filename = pattern;
563
+-#ifdef _AMIGA
564
+-	  dirname = (char *) "";
565
+-#else
566
+ 	  dirname = (char *) ".";
567
+-#endif
568
+ 	  dirlen = 0;
569
+ 	}
570
+     }
571
+@@ -552,22 +543,21 @@ glob (pattern, flags, errfunc, pglob)
572
+ 	  char *drive_spec;
573
+ 
574
+ 	  ++dirlen;
575
+-	  drive_spec = (char *) __alloca (dirlen + 1);
576
++	  drive_spec = __alloca (dirlen + 1);
577
+ 	  *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
578
+ 	  /* For now, disallow wildcards in the drive spec, to
579
+ 	     prevent infinite recursion in glob.  */
580
+ 	  if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
581
+ 	    return GLOB_NOMATCH;
582
+-	  /* If this is "d:pattern", we need to copy `:' to DIRNAME
583
++	  /* If this is "d:pattern", we need to copy ':' to DIRNAME
584
+ 	     as well.  If it's "d:/pattern", don't remove the slash
585
+ 	     from "d:/", since "d:" and "d:/" are not the same.*/
586
+ 	}
587
+ #endif
588
+-#ifdef _LIBC
589
+-      if (__libc_use_alloca (alloca_used + dirlen + 1))
590
++
591
++      if (glob_use_alloca (alloca_used, dirlen + 1))
592
+ 	newp = alloca_account (dirlen + 1, alloca_used);
593
+       else
594
+-#endif
595
+ 	{
596
+ 	  newp = malloc (dirlen + 1);
597
+ 	  if (newp == NULL)
598
+@@ -578,14 +568,17 @@ glob (pattern, flags, errfunc, pglob)
599
+       dirname = newp;
600
+       ++filename;
601
+ 
602
+-      if (filename[0] == '\0'
603
+ #if defined __MSDOS__ || defined WINDOWS32
604
+-	  && dirname[dirlen - 1] != ':'
605
+-	  && (dirlen < 3 || dirname[dirlen - 2] != ':'
606
+-	      || dirname[dirlen - 1] != '/')
607
++      bool drive_root = (dirlen > 1
608
++                         && (dirname[dirlen - 1] == ':'
609
++                             || (dirlen > 2 && dirname[dirlen - 2] == ':'
610
++                                 && dirname[dirlen - 1] == '/')));
611
++#else
612
++      bool drive_root = false;
613
+ #endif
614
+-	  && dirlen > 1)
615
+-	/* "pattern/".  Expand "pattern", appending slashes.  */
616
++
617
++      if (filename[0] == '\0' && dirlen > 1 && !drive_root)
618
++        /* "pattern/".  Expand "pattern", appending slashes.  */
619
+ 	{
620
+ 	  int orig_flags = flags;
621
+ 	  if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\')
622
+@@ -618,7 +611,6 @@ glob (pattern, flags, errfunc, pglob)
623
+ 	}
624
+     }
625
+ 
626
+-#ifndef VMS
627
+   if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
628
+     {
629
+       if (dirname[1] == '\0' || dirname[1] == '/'
630
+@@ -628,100 +620,127 @@ glob (pattern, flags, errfunc, pglob)
631
+ 	  /* Look up home directory.  */
632
+ 	  char *home_dir = getenv ("HOME");
633
+ 	  int malloc_home_dir = 0;
634
+-# ifdef _AMIGA
635
+-	  if (home_dir == NULL || home_dir[0] == '\0')
636
+-	    home_dir = "SYS:";
637
+-# else
638
+-#  ifdef WINDOWS32
639
+-	  if (home_dir == NULL || home_dir[0] == '\0')
640
+-	    home_dir = "c:/users/default"; /* poor default */
641
+-#  else
642
+ 	  if (home_dir == NULL || home_dir[0] == '\0')
643
+ 	    {
644
++#ifdef WINDOWS32
645
++	      /* Windows NT defines HOMEDRIVE and HOMEPATH.  But give
646
++		 preference to HOME, because the user can change HOME.  */
647
++	      const char *home_drive = getenv ("HOMEDRIVE");
648
++	      const char *home_path = getenv ("HOMEPATH");
649
++
650
++	      if (home_drive != NULL && home_path != NULL)
651
++		{
652
++		  size_t home_drive_len = strlen (home_drive);
653
++		  size_t home_path_len = strlen (home_path);
654
++		  char *mem = alloca (home_drive_len + home_path_len + 1);
655
++
656
++		  memcpy (mem, home_drive, home_drive_len);
657
++		  memcpy (mem + home_drive_len, home_path, home_path_len + 1);
658
++		  home_dir = mem;
659
++		}
660
++	      else
661
++		home_dir = "c:/users/default"; /* poor default */
662
++#else
663
+ 	      int success;
664
+ 	      char *name;
665
++	      int malloc_name = 0;
666
+ 	      size_t buflen = GET_LOGIN_NAME_MAX () + 1;
667
+ 
668
+ 	      if (buflen == 0)
669
+-		/* `sysconf' does not support _SC_LOGIN_NAME_MAX.  Try
670
++		/* 'sysconf' does not support _SC_LOGIN_NAME_MAX.  Try
671
+ 		   a moderate value.  */
672
+ 		buflen = 20;
673
+-	      name = alloca_account (buflen, alloca_used);
674
++	      if (glob_use_alloca (alloca_used, buflen))
675
++		name = alloca_account (buflen, alloca_used);
676
++	      else
677
++		{
678
++		  name = malloc (buflen);
679
++		  if (name == NULL)
680
++		    {
681
++		      retval = GLOB_NOSPACE;
682
++		      goto out;
683
++		    }
684
++		  malloc_name = 1;
685
++		}
686
+ 
687
+ 	      success = __getlogin_r (name, buflen) == 0;
688
+ 	      if (success)
689
+ 		{
690
+ 		  struct passwd *p;
691
+-#   if defined HAVE_GETPWNAM_R || defined _LIBC
692
+-		  long int pwbuflen = GETPW_R_SIZE_MAX ();
693
++		  char *malloc_pwtmpbuf = NULL;
694
+ 		  char *pwtmpbuf;
695
++# if defined HAVE_GETPWNAM_R || defined _LIBC
696
++		  long int pwbuflenmax = GETPW_R_SIZE_MAX ();
697
++		  size_t pwbuflen = pwbuflenmax;
698
+ 		  struct passwd pwbuf;
699
+-		  int malloc_pwtmpbuf = 0;
700
+ 		  int save = errno;
701
+ 
702
+-#    ifndef _LIBC
703
+-		  if (pwbuflen == -1)
704
+-		    /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
705
++#  ifndef _LIBC
706
++		  if (! (0 < pwbuflenmax && pwbuflenmax <= SIZE_MAX))
707
++		    /* 'sysconf' does not support _SC_GETPW_R_SIZE_MAX.
708
+ 		       Try a moderate value.  */
709
+ 		    pwbuflen = 1024;
710
+-#    endif
711
+-		  if (__libc_use_alloca (alloca_used + pwbuflen))
712
++#  endif
713
++		  if (glob_use_alloca (alloca_used, pwbuflen))
714
+ 		    pwtmpbuf = alloca_account (pwbuflen, alloca_used);
715
+ 		  else
716
+ 		    {
717
+ 		      pwtmpbuf = malloc (pwbuflen);
718
+ 		      if (pwtmpbuf == NULL)
719
+ 			{
720
++			  if (__glibc_unlikely (malloc_name))
721
++			    free (name);
722
+ 			  retval = GLOB_NOSPACE;
723
+ 			  goto out;
724
+ 			}
725
+-		      malloc_pwtmpbuf = 1;
726
++		      malloc_pwtmpbuf = pwtmpbuf;
727
+ 		    }
728
+ 
729
+ 		  while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
730
+ 			 != 0)
731
+ 		    {
732
++		      size_t newlen;
733
++		      bool v;
734
+ 		      if (errno != ERANGE)
735
+ 			{
736
+ 			  p = NULL;
737
+ 			  break;
738
+ 			}
739
+-
740
+-		      if (!malloc_pwtmpbuf
741
+-			  && __libc_use_alloca (alloca_used
742
+-						+ 2 * pwbuflen))
743
++		      v = size_add_wrapv (pwbuflen, pwbuflen, &newlen);
744
++		      if (!v && malloc_pwtmpbuf == NULL
745
++			  && glob_use_alloca (alloca_used, newlen))
746
+ 			pwtmpbuf = extend_alloca_account (pwtmpbuf, pwbuflen,
747
+-							  2 * pwbuflen,
748
+-							  alloca_used);
749
++							  newlen, alloca_used);
750
+ 		      else
751
+ 			{
752
+-			  char *newp = realloc (malloc_pwtmpbuf
753
+-						? pwtmpbuf : NULL,
754
+-						2 * pwbuflen);
755
++			  char *newp = (v ? NULL
756
++					: realloc (malloc_pwtmpbuf, newlen));
757
+ 			  if (newp == NULL)
758
+ 			    {
759
+-			      if (__glibc_unlikely (malloc_pwtmpbuf))
760
+-				free (pwtmpbuf);
761
++			      free (malloc_pwtmpbuf);
762
++			      if (__glibc_unlikely (malloc_name))
763
++				free (name);
764
+ 			      retval = GLOB_NOSPACE;
765
+ 			      goto out;
766
+ 			    }
767
+-			  pwtmpbuf = newp;
768
+-			  pwbuflen = 2 * pwbuflen;
769
+-			  malloc_pwtmpbuf = 1;
770
++			  malloc_pwtmpbuf = pwtmpbuf = newp;
771
+ 			}
772
++		      pwbuflen = newlen;
773
+ 		      __set_errno (save);
774
+ 		    }
775
+-#   else
776
++# else
777
+ 		  p = getpwnam (name);
778
+-#   endif
779
++# endif
780
++		  if (__glibc_unlikely (malloc_name))
781
++		    free (name);
782
+ 		  if (p != NULL)
783
+ 		    {
784
+-		      if (!malloc_pwtmpbuf)
785
++		      if (malloc_pwtmpbuf == NULL)
786
+ 			home_dir = p->pw_dir;
787
+ 		      else
788
+ 			{
789
+ 			  size_t home_dir_len = strlen (p->pw_dir) + 1;
790
+-			  if (__libc_use_alloca (alloca_used + home_dir_len))
791
++			  if (glob_use_alloca (alloca_used, home_dir_len))
792
+ 			    home_dir = alloca_account (home_dir_len,
793
+ 						       alloca_used);
794
+ 			  else
795
+@@ -736,26 +755,32 @@ glob (pattern, flags, errfunc, pglob)
796
+ 			      malloc_home_dir = 1;
797
+ 			    }
798
+ 			  memcpy (home_dir, p->pw_dir, home_dir_len);
799
+-
800
+-			  free (pwtmpbuf);
801
+ 			}
802
+ 		    }
803
++		  free (malloc_pwtmpbuf);
804
+ 		}
805
++	      else
806
++		{
807
++		  if (__glibc_unlikely (malloc_name))
808
++		    free (name);
809
++		}
810
++#endif /* WINDOWS32 */
811
+ 	    }
812
+ 	  if (home_dir == NULL || home_dir[0] == '\0')
813
+ 	    {
814
++	      if (__glibc_unlikely (malloc_home_dir))
815
++		free (home_dir);
816
+ 	      if (flags & GLOB_TILDE_CHECK)
817
+ 		{
818
+-		  if (__glibc_unlikely (malloc_home_dir))
819
+-		    free (home_dir);
820
+ 		  retval = GLOB_NOMATCH;
821
+ 		  goto out;
822
+ 		}
823
+ 	      else
824
+-		home_dir = (char *) "~"; /* No luck.  */
825
++		{
826
++		  home_dir = (char *) "~"; /* No luck.  */
827
++		  malloc_home_dir = 0;
828
++		}
829
+ 	    }
830
+-#  endif /* WINDOWS32 */
831
+-# endif
832
+ 	  /* Now construct the full directory.  */
833
+ 	  if (dirname[1] == '\0')
834
+ 	    {
835
+@@ -770,8 +795,7 @@ glob (pattern, flags, errfunc, pglob)
836
+ 	    {
837
+ 	      char *newp;
838
+ 	      size_t home_len = strlen (home_dir);
839
+-	      int use_alloca = __libc_use_alloca (alloca_used
840
+-						  + home_len + dirlen);
841
++	      int use_alloca = glob_use_alloca (alloca_used, home_len + dirlen);
842
+ 	      if (use_alloca)
843
+ 		newp = alloca_account (home_len + dirlen, alloca_used);
844
+ 	      else
845
+@@ -795,12 +819,15 @@ glob (pattern, flags, errfunc, pglob)
846
+ 	      dirname = newp;
847
+ 	      dirlen += home_len - 1;
848
+ 	      malloc_dirname = !use_alloca;
849
++
850
++	      if (__glibc_unlikely (malloc_home_dir))
851
++		free (home_dir);
852
+ 	    }
853
+ 	  dirname_modified = 1;
854
+ 	}
855
+-# if !defined _AMIGA && !defined WINDOWS32
856
+       else
857
+ 	{
858
++#ifndef WINDOWS32
859
+ 	  char *end_name = strchr (dirname, '/');
860
+ 	  char *user_name;
861
+ 	  int malloc_user_name = 0;
862
+@@ -822,7 +849,7 @@ glob (pattern, flags, errfunc, pglob)
863
+ 	  else
864
+ 	    {
865
+ 	      char *newp;
866
+-	      if (__libc_use_alloca (alloca_used + (end_name - dirname)))
867
++	      if (glob_use_alloca (alloca_used, end_name - dirname))
868
+ 		newp = alloca_account (end_name - dirname, alloca_used);
869
+ 	      else
870
+ 		{
871
+@@ -867,20 +894,21 @@ glob (pattern, flags, errfunc, pglob)
872
+ 	  /* Look up specific user's home directory.  */
873
+ 	  {
874
+ 	    struct passwd *p;
875
++	    char *malloc_pwtmpbuf = NULL;
876
+ #  if defined HAVE_GETPWNAM_R || defined _LIBC
877
+-	    long int buflen = GETPW_R_SIZE_MAX ();
878
++	    long int buflenmax = GETPW_R_SIZE_MAX ();
879
++	    size_t buflen = buflenmax;
880
+ 	    char *pwtmpbuf;
881
+-	    int malloc_pwtmpbuf = 0;
882
+ 	    struct passwd pwbuf;
883
+ 	    int save = errno;
884
+ 
885
+ #   ifndef _LIBC
886
+-	    if (buflen == -1)
887
+-	      /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.  Try a
888
++	    if (! (0 <= buflenmax && buflenmax <= SIZE_MAX))
889
++	      /* Perhaps 'sysconf' does not support _SC_GETPW_R_SIZE_MAX.  Try a
890
+ 		 moderate value.  */
891
+ 	      buflen = 1024;
892
+ #   endif
893
+-	    if (__libc_use_alloca (alloca_used + buflen))
894
++	    if (glob_use_alloca (alloca_used, buflen))
895
+ 	      pwtmpbuf = alloca_account (buflen, alloca_used);
896
+ 	    else
897
+ 	      {
898
+@@ -893,32 +921,32 @@ glob (pattern, flags, errfunc, pglob)
899
+ 		    retval = GLOB_NOSPACE;
900
+ 		    goto out;
901
+ 		  }
902
+-		malloc_pwtmpbuf = 1;
903
++		malloc_pwtmpbuf = pwtmpbuf;
904
+ 	      }
905
+ 
906
+ 	    while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
907
+ 	      {
908
++		size_t newlen;
909
++		bool v;
910
+ 		if (errno != ERANGE)
911
+ 		  {
912
+ 		    p = NULL;
913
+ 		    break;
914
+ 		  }
915
+-		if (!malloc_pwtmpbuf
916
+-		    && __libc_use_alloca (alloca_used + 2 * buflen))
917
++		v = size_add_wrapv (buflen, buflen, &newlen);
918
++		if (!v && malloc_pwtmpbuf == NULL
919
++		    && glob_use_alloca (alloca_used, newlen))
920
+ 		  pwtmpbuf = extend_alloca_account (pwtmpbuf, buflen,
921
+-						    2 * buflen, alloca_used);
922
++						    newlen, alloca_used);
923
+ 		else
924
+ 		  {
925
+-		    char *newp = realloc (malloc_pwtmpbuf ? pwtmpbuf : NULL,
926
+-					  2 * buflen);
927
++		    char *newp = v ? NULL : realloc (malloc_pwtmpbuf, newlen);
928
+ 		    if (newp == NULL)
929
+ 		      {
930
+-			if (__glibc_unlikely (malloc_pwtmpbuf))
931
+-			  free (pwtmpbuf);
932
++			free (malloc_pwtmpbuf);
933
+ 			goto nomem_getpw;
934
+ 		      }
935
+-		    pwtmpbuf = newp;
936
+-		    malloc_pwtmpbuf = 1;
937
++		    malloc_pwtmpbuf = pwtmpbuf = newp;
938
+ 		  }
939
+ 		__set_errno (save);
940
+ 	      }
941
+@@ -939,7 +967,7 @@ glob (pattern, flags, errfunc, pglob)
942
+ 		  free (dirname);
943
+ 		malloc_dirname = 0;
944
+ 
945
+-		if (__libc_use_alloca (alloca_used + home_len + rest_len + 1))
946
++		if (glob_use_alloca (alloca_used, home_len + rest_len + 1))
947
+ 		  dirname = alloca_account (home_len + rest_len + 1,
948
+ 					    alloca_used);
949
+ 		else
950
+@@ -947,8 +975,7 @@ glob (pattern, flags, errfunc, pglob)
951
+ 		    dirname = malloc (home_len + rest_len + 1);
952
+ 		    if (dirname == NULL)
953
+ 		      {
954
+-			if (__glibc_unlikely (malloc_pwtmpbuf))
955
+-			  free (pwtmpbuf);
956
++			free (malloc_pwtmpbuf);
957
+ 			retval = GLOB_NOSPACE;
958
+ 			goto out;
959
+ 		      }
960
+@@ -960,24 +987,24 @@ glob (pattern, flags, errfunc, pglob)
961
+ 		dirlen = home_len + rest_len;
962
+ 		dirname_modified = 1;
963
+ 
964
+-		if (__glibc_unlikely (malloc_pwtmpbuf))
965
+-		  free (pwtmpbuf);
966
++		free (malloc_pwtmpbuf);
967
+ 	      }
968
+ 	    else
969
+ 	      {
970
+-		if (__glibc_unlikely (malloc_pwtmpbuf))
971
+-		  free (pwtmpbuf);
972
++		free (malloc_pwtmpbuf);
973
+ 
974
+ 		if (flags & GLOB_TILDE_CHECK)
975
+-		  /* We have to regard it as an error if we cannot find the
976
+-		     home directory.  */
977
+-		  return GLOB_NOMATCH;
978
++		  {
979
++		    /* We have to regard it as an error if we cannot find the
980
++		       home directory.  */
981
++		    retval = GLOB_NOMATCH;
982
++		    goto out;
983
++		  }
984
+ 	      }
985
+ 	  }
986
++#endif /* !WINDOWS32 */
987
+ 	}
988
+-# endif	/* Not Amiga && not WINDOWS32.  */
989
+     }
990
+-#endif	/* Not VMS.  */
991
+ 
992
+   /* Now test whether we looked for "~" or "~NAME".  In this case we
993
+      can give the answer now.  */
994
+@@ -996,19 +1023,18 @@ glob (pattern, flags, errfunc, pglob)
995
+ 	  size_t newcount = pglob->gl_pathc + pglob->gl_offs;
996
+ 	  char **new_gl_pathv;
997
+ 
998
+-	  if (newcount > UINTPTR_MAX - (1 + 1)
999
+-	      || newcount + 1 + 1 > ~((size_t) 0) / sizeof (char *))
1000
++	  if (newcount > SIZE_MAX / sizeof (char *) - 2)
1001
+ 	    {
1002
+ 	    nospace:
1003
+ 	      free (pglob->gl_pathv);
1004
+ 	      pglob->gl_pathv = NULL;
1005
+ 	      pglob->gl_pathc = 0;
1006
+-	      return GLOB_NOSPACE;
1007
++	      retval = GLOB_NOSPACE;
1008
++	      goto out;
1009
+ 	    }
1010
+ 
1011
+-	  new_gl_pathv
1012
+-	    = (char **) realloc (pglob->gl_pathv,
1013
+-				 (newcount + 1 + 1) * sizeof (char *));
1014
++	  new_gl_pathv = realloc (pglob->gl_pathv,
1015
++				  (newcount + 2) * sizeof (char *));
1016
+ 	  if (new_gl_pathv == NULL)
1017
+ 	    goto nospace;
1018
+ 	  pglob->gl_pathv = new_gl_pathv;
1019
+@@ -1022,12 +1048,19 @@ glob (pattern, flags, errfunc, pglob)
1020
+ 	      p = mempcpy (pglob->gl_pathv[newcount], dirname, dirlen);
1021
+ 	      p[0] = '/';
1022
+ 	      p[1] = '\0';
1023
++	      if (__glibc_unlikely (malloc_dirname))
1024
++		free (dirname);
1025
+ 	    }
1026
+ 	  else
1027
+ 	    {
1028
+-	      pglob->gl_pathv[newcount] = strdup (dirname);
1029
+-	      if (pglob->gl_pathv[newcount] == NULL)
1030
+-		goto nospace;
1031
++	      if (__glibc_unlikely (malloc_dirname))
1032
++		pglob->gl_pathv[newcount] = dirname;
1033
++	      else
1034
++		{
1035
++		  pglob->gl_pathv[newcount] = strdup (dirname);
1036
++		  if (pglob->gl_pathv[newcount] == NULL)
1037
++		    goto nospace;
1038
++		}
1039
+ 	    }
1040
+ 	  pglob->gl_pathv[++newcount] = NULL;
1041
+ 	  ++pglob->gl_pathc;
1042
+@@ -1037,7 +1070,8 @@ glob (pattern, flags, errfunc, pglob)
1043
+ 	}
1044
+ 
1045
+       /* Not found.  */
1046
+-      return GLOB_NOMATCH;
1047
++      retval = GLOB_NOMATCH;
1048
++      goto out;
1049
+     }
1050
+ 
1051
+   meta = __glob_pattern_type (dirname, !(flags & GLOB_NOESCAPE));
1052
+@@ -1083,7 +1117,10 @@ glob (pattern, flags, errfunc, pglob)
1053
+       if (status != 0)
1054
+ 	{
1055
+ 	  if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH)
1056
+-	    return status;
1057
++	    {
1058
++	      retval = status;
1059
++	      goto out;
1060
++	    }
1061
+ 	  goto no_matches;
1062
+ 	}
1063
+ 
1064
+@@ -1094,19 +1131,6 @@ glob (pattern, flags, errfunc, pglob)
1065
+ 	{
1066
+ 	  size_t old_pathc;
1067
+ 
1068
+-#ifdef	SHELL
1069
+-	  {
1070
+-	    /* Make globbing interruptible in the bash shell. */
1071
+-	    extern int interrupt_state;
1072
+-
1073
+-	    if (interrupt_state)
1074
+-	      {
1075
+-		globfree (&dirs);
1076
+-		return GLOB_ABORTED;
1077
+-	      }
1078
+-	  }
1079
+-#endif /* SHELL.  */
1080
+-
1081
+ 	  old_pathc = pglob->gl_pathc;
1082
+ 	  status = glob_in_dir (filename, dirs.gl_pathv[i],
1083
+ 				((flags | GLOB_APPEND)
1084
+@@ -1121,7 +1145,8 @@ glob (pattern, flags, errfunc, pglob)
1085
+ 	      globfree (&dirs);
1086
+ 	      globfree (pglob);
1087
+ 	      pglob->gl_pathc = 0;
1088
+-	      return status;
1089
++	      retval = status;
1090
++	      goto out;
1091
+ 	    }
1092
+ 
1093
+ 	  /* Stick the directory on the front of each name.  */
1094
+@@ -1132,13 +1157,14 @@ glob (pattern, flags, errfunc, pglob)
1095
+ 	      globfree (&dirs);
1096
+ 	      globfree (pglob);
1097
+ 	      pglob->gl_pathc = 0;
1098
+-	      return GLOB_NOSPACE;
1099
++	      retval = GLOB_NOSPACE;
1100
++	      goto out;
1101
+ 	    }
1102
+ 	}
1103
+ 
1104
+       flags |= GLOB_MAGCHAR;
1105
+ 
1106
+-      /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
1107
++      /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls.
1108
+ 	 But if we have not found any matching entry and the GLOB_NOCHECK
1109
+ 	 flag was set we must return the input pattern itself.  */
1110
+       if (pglob->gl_pathc + pglob->gl_offs == oldcount)
1111
+@@ -1150,28 +1176,28 @@ glob (pattern, flags, errfunc, pglob)
1112
+ 	      size_t newcount = pglob->gl_pathc + pglob->gl_offs;
1113
+ 	      char **new_gl_pathv;
1114
+ 
1115
+-	      if (newcount > UINTPTR_MAX - 2
1116
+-		  || newcount + 2 > ~((size_t) 0) / sizeof (char *))
1117
++	      if (newcount > SIZE_MAX / sizeof (char *) - 2)
1118
+ 		{
1119
+ 		nospace2:
1120
+ 		  globfree (&dirs);
1121
+-		  return GLOB_NOSPACE;
1122
++		  retval = GLOB_NOSPACE;
1123
++		  goto out;
1124
+ 		}
1125
+ 
1126
+-	      new_gl_pathv = (char **) realloc (pglob->gl_pathv,
1127
+-						(newcount + 2)
1128
+-						* sizeof (char *));
1129
++	      new_gl_pathv = realloc (pglob->gl_pathv,
1130
++				      (newcount + 2) * sizeof (char *));
1131
+ 	      if (new_gl_pathv == NULL)
1132
+ 		goto nospace2;
1133
+ 	      pglob->gl_pathv = new_gl_pathv;
1134
+ 
1135
+-	      pglob->gl_pathv[newcount] = __strdup (pattern);
1136
++	      pglob->gl_pathv[newcount] = strdup (pattern);
1137
+ 	      if (pglob->gl_pathv[newcount] == NULL)
1138
+ 		{
1139
+ 		  globfree (&dirs);
1140
+ 		  globfree (pglob);
1141
+ 		  pglob->gl_pathc = 0;
1142
+-		  return GLOB_NOSPACE;
1143
++		  retval = GLOB_NOSPACE;
1144
++		  goto out;
1145
+ 		}
1146
+ 
1147
+ 	      ++pglob->gl_pathc;
1148
+@@ -1183,7 +1209,8 @@ glob (pattern, flags, errfunc, pglob)
1149
+ 	  else
1150
+ 	    {
1151
+ 	      globfree (&dirs);
1152
+-	      return GLOB_NOMATCH;
1153
++	      retval = GLOB_NOMATCH;
1154
++	      goto out;
1155
+ 	    }
1156
+ 	}
1157
+ 
1158
+@@ -1229,7 +1256,8 @@ glob (pattern, flags, errfunc, pglob)
1159
+ 	      flags = orig_flags;
1160
+ 	      goto no_matches;
1161
+ 	    }
1162
+-	  return status;
1163
++	  retval = status;
1164
++	  goto out;
1165
+ 	}
1166
+ 
1167
+       if (dirlen > 0)
1168
+@@ -1241,7 +1269,8 @@ glob (pattern, flags, errfunc, pglob)
1169
+ 	    {
1170
+ 	      globfree (pglob);
1171
+ 	      pglob->gl_pathc = 0;
1172
+-	      return GLOB_NOSPACE;
1173
++	      retval = GLOB_NOSPACE;
1174
++	      goto out;
1175
+ 	    }
1176
+ 	}
1177
+     }
1178
+@@ -1266,7 +1295,8 @@ glob (pattern, flags, errfunc, pglob)
1179
+ 	      {
1180
+ 		globfree (pglob);
1181
+ 		pglob->gl_pathc = 0;
1182
+-		return GLOB_NOSPACE;
1183
++		retval = GLOB_NOSPACE;
1184
++		goto out;
1185
+ 	      }
1186
+ 	    strcpy (&new[len - 2], "/");
1187
+ 	    pglob->gl_pathv[i] = new;
1188
+@@ -1292,33 +1322,12 @@ libc_hidden_def (glob)
1189
+ #endif
1190
+ 
1191
+ 
1192
+-#if !defined _LIBC || !defined GLOB_ONLY_P
1193
+-
1194
+-/* Free storage allocated in PGLOB by a previous `glob' call.  */
1195
+-void
1196
+-globfree (pglob)
1197
+-     glob_t *pglob;
1198
+-{
1199
+-  if (pglob->gl_pathv != NULL)
1200
+-    {
1201
+-      size_t i;
1202
+-      for (i = 0; i < pglob->gl_pathc; ++i)
1203
+-	free (pglob->gl_pathv[pglob->gl_offs + i]);
1204
+-      free (pglob->gl_pathv);
1205
+-      pglob->gl_pathv = NULL;
1206
+-    }
1207
+-}
1208
+-#if defined _LIBC && !defined globfree
1209
+-libc_hidden_def (globfree)
1210
+-#endif
1211
+-
1212
+-
1213
+ /* Do a collated comparison of A and B.  */
1214
+ static int
1215
+ collated_compare (const void *a, const void *b)
1216
+ {
1217
+-  const char *const s1 = *(const char *const * const) a;
1218
+-  const char *const s2 = *(const char *const * const) b;
1219
++  char *const *ps1 = a; char *s1 = *ps1;
1220
++  char *const *ps2 = b; char *s2 = *ps2;
1221
+ 
1222
+   if (s1 == s2)
1223
+     return 0;
1224
+@@ -1339,28 +1348,24 @@ prefix_array (const char *dirname, char
1225
+ {
1226
+   size_t i;
1227
+   size_t dirlen = strlen (dirname);
1228
+-#if defined __MSDOS__ || defined WINDOWS32
1229
+-  int sep_char = '/';
1230
+-# define DIRSEP_CHAR sep_char
1231
+-#else
1232
+-# define DIRSEP_CHAR '/'
1233
+-#endif
1234
++  char dirsep_char = '/';
1235
+ 
1236
+   if (dirlen == 1 && dirname[0] == '/')
1237
+     /* DIRNAME is just "/", so normal prepending would get us "//foo".
1238
+        We want "/foo" instead, so don't prepend any chars from DIRNAME.  */
1239
+     dirlen = 0;
1240
++
1241
+ #if defined __MSDOS__ || defined WINDOWS32
1242
+-  else if (dirlen > 1)
1243
++  if (dirlen > 1)
1244
+     {
1245
+       if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
1246
+ 	/* DIRNAME is "d:/".  Don't prepend the slash from DIRNAME.  */
1247
+ 	--dirlen;
1248
+       else if (dirname[dirlen - 1] == ':')
1249
+ 	{
1250
+-	  /* DIRNAME is "d:".  Use `:' instead of `/'.  */
1251
++	  /* DIRNAME is "d:".  Use ':' instead of '/'.  */
1252
+ 	  --dirlen;
1253
+-	  sep_char = ':';
1254
++	  dirsep_char = ':';
1255
+ 	}
1256
+     }
1257
+ #endif
1258
+@@ -1368,7 +1373,7 @@ prefix_array (const char *dirname, char
1259
+   for (i = 0; i < n; ++i)
1260
+     {
1261
+       size_t eltlen = strlen (array[i]) + 1;
1262
+-      char *new = (char *) malloc (dirlen + 1 + eltlen);
1263
++      char *new = malloc (dirlen + 1 + eltlen);
1264
+       if (new == NULL)
1265
+ 	{
1266
+ 	  while (i > 0)
1267
+@@ -1378,7 +1383,7 @@ prefix_array (const char *dirname, char
1268
+ 
1269
+       {
1270
+ 	char *endp = mempcpy (new, dirname, dirlen);
1271
+-	*endp++ = DIRSEP_CHAR;
1272
++	*endp++ = dirsep_char;
1273
+ 	mempcpy (endp, array[i], eltlen);
1274
+       }
1275
+       free (array[i]);
1276
+@@ -1388,107 +1393,57 @@ prefix_array (const char *dirname, char
1277
+   return 0;
1278
+ }
1279
+ 
1280
+-
1281
+-/* We must not compile this function twice.  */
1282
+-#if !defined _LIBC || !defined NO_GLOB_PATTERN_P
1283
+-int
1284
+-__glob_pattern_type (pattern, quote)
1285
+-     const char *pattern;
1286
+-     int quote;
1287
+-{
1288
+-  const char *p;
1289
+-  int ret = 0;
1290
+-
1291
+-  for (p = pattern; *p != '\0'; ++p)
1292
+-    switch (*p)
1293
+-      {
1294
+-      case '?':
1295
+-      case '*':
1296
+-	return 1;
1297
+-
1298
+-      case '\\':
1299
+-	if (quote)
1300
+-	  {
1301
+-	    if (p[1] != '\0')
1302
+-	      ++p;
1303
+-	    ret |= 2;
1304
+-	  }
1305
+-	break;
1306
+-
1307
+-      case '[':
1308
+-	ret |= 4;
1309
+-	break;
1310
+-
1311
+-      case ']':
1312
+-	if (ret & 4)
1313
+-	  return 1;
1314
+-	break;
1315
+-      }
1316
+-
1317
+-  return ret;
1318
+-}
1319
+-
1320
+-/* Return nonzero if PATTERN contains any metacharacters.
1321
+-   Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */
1322
+-int
1323
+-__glob_pattern_p (pattern, quote)
1324
+-     const char *pattern;
1325
+-     int quote;
1326
+-{
1327
+-  return __glob_pattern_type (pattern, quote) == 1;
1328
+-}
1329
+-# ifdef _LIBC
1330
+-weak_alias (__glob_pattern_p, glob_pattern_p)
1331
+-# endif
1332
+-#endif
1333
+-
1334
+-#endif /* !GLOB_ONLY_P */
1335
+-
1336
+-
1337
+ /* We put this in a separate function mainly to allow the memory
1338
+    allocated with alloca to be recycled.  */
1339
+-#if !defined _LIBC || !defined GLOB_ONLY_P
1340
+ static int
1341
+ __attribute_noinline__
1342
+-link_exists2_p (const char *dir, size_t dirlen, const char *fname,
1343
+-	       glob_t *pglob
1344
+-# ifndef _LIBC
1345
+-		, int flags
1346
++link_stat (const char *dir, size_t dirlen, const char *fname,
1347
++	   glob_t *pglob
1348
++# if !defined _LIBC && !HAVE_FSTATAT
1349
++	   , int flags
1350
+ # endif
1351
+-		)
1352
++	   )
1353
+ {
1354
+   size_t fnamelen = strlen (fname);
1355
+-  char *fullname = (char *) __alloca (dirlen + 1 + fnamelen + 1);
1356
++  char *fullname = __alloca (dirlen + 1 + fnamelen + 1);
1357
+   struct stat st;
1358
+-# ifndef _LIBC
1359
+-  struct_stat64 st64;
1360
+-# endif
1361
+ 
1362
+   mempcpy (mempcpy (mempcpy (fullname, dir, dirlen), "/", 1),
1363
+ 	   fname, fnamelen + 1);
1364
+ 
1365
+-# ifdef _LIBC
1366
+-  return (*pglob->gl_stat) (fullname, &st) == 0;
1367
+-# else
1368
+-  return ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1369
+-	   ? (*pglob->gl_stat) (fullname, &st)
1370
+-	   : __stat64 (fullname, &st64)) == 0);
1371
++# if !defined _LIBC && !HAVE_FSTATAT
1372
++  if (__builtin_expect ((flags & GLOB_ALTDIRFUNC) == 0, 1))
1373
++    {
1374
++      struct_stat64 st64;
1375
++      return __stat64 (fullname, &st64);
1376
++    }
1377
+ # endif
1378
++  return (*pglob->gl_stat) (fullname, &st);
1379
+ }
1380
+-# ifdef _LIBC
1381
+-#  define link_exists_p(dfd, dirname, dirnamelen, fname, pglob, flags) \
1382
+-  (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)			      \
1383
+-   ? link_exists2_p (dirname, dirnamelen, fname, pglob)			      \
1384
+-   : ({ struct stat64 st64;						      \
1385
+-       __fxstatat64 (_STAT_VER, dfd, fname, &st64, 0) == 0; }))
1386
++
1387
++/* Return true if DIR/FNAME exists.  */
1388
++static int
1389
++link_exists_p (int dfd, const char *dir, size_t dirlen, const char *fname,
1390
++	       glob_t *pglob, int flags)
1391
++{
1392
++  int status;
1393
++# if defined _LIBC || HAVE_FSTATAT
1394
++  if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
1395
++    status = link_stat (dir, dirlen, fname, pglob);
1396
++  else
1397
++    {
1398
++      /* dfd cannot be -1 here, because dirfd never returns -1 on
1399
++	 glibc, or on hosts that have fstatat.  */
1400
++      struct_stat64 st64;
1401
++      status = __fxstatat64 (_STAT_VER, dfd, fname, &st64, 0);
1402
++    }
1403
+ # else
1404
+-#  define link_exists_p(dfd, dirname, dirnamelen, fname, pglob, flags) \
1405
+-  link_exists2_p (dirname, dirnamelen, fname, pglob, flags)
1406
++  status = link_stat (dir, dirlen, fname, pglob, flags);
1407
+ # endif
1408
+-#endif
1409
+-
1410
++  return status == 0 || errno == EOVERFLOW;
1411
++}
1412
+ 
1413
+-/* Like `glob', but PATTERN is a final pathname component,
1414
++/* Like 'glob', but PATTERN is a final pathname component,
1415
+    and matches are searched for in DIRECTORY.
1416
+    The GLOB_NOSORT bit in FLAGS is ignored.  No sorting is ever done.
1417
+    The GLOB_APPEND flag is assumed to be set (always appends).  */
1418
+@@ -1499,25 +1454,25 @@ glob_in_dir (const char *pattern, const
1419
+ {
1420
+   size_t dirlen = strlen (directory);
1421
+   void *stream = NULL;
1422
+-  struct globnames
1423
+-    {
1424
+-      struct globnames *next;
1425
+-      size_t count;
1426
+-      char *name[64];
1427
+-    };
1428
+-#define INITIAL_COUNT sizeof (init_names.name) / sizeof (init_names.name[0])
1429
+-  struct globnames init_names;
1430
+-  struct globnames *names = &init_names;
1431
+-  struct globnames *names_alloca = &init_names;
1432
++# define GLOBNAMES_MEMBERS(nnames) \
1433
++    struct globnames *next; size_t count; char *name[nnames];
1434
++  struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) };
1435
++  struct { GLOBNAMES_MEMBERS (64) } init_names_buf;
1436
++  struct globnames *init_names = (struct globnames *) &init_names_buf;
1437
++  struct globnames *names = init_names;
1438
++  struct globnames *names_alloca = init_names;
1439
+   size_t nfound = 0;
1440
+   size_t cur = 0;
1441
+   int meta;
1442
+   int save;
1443
++  int result;
1444
+ 
1445
+-  alloca_used += sizeof (init_names);
1446
++  alloca_used += sizeof init_names_buf;
1447
+ 
1448
+-  init_names.next = NULL;
1449
+-  init_names.count = INITIAL_COUNT;
1450
++  init_names->next = NULL;
1451
++  init_names->count = ((sizeof init_names_buf
1452
++                        - offsetof (struct globnames, name))
1453
++                       / sizeof init_names->name[0]);
1454
+ 
1455
+   meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE));
1456
+   if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
1457
+@@ -1537,14 +1492,16 @@ glob_in_dir (const char *pattern, const
1458
+ 	struct_stat64 st64;
1459
+       } ust;
1460
+       size_t patlen = strlen (pattern);
1461
+-      int alloca_fullname = __libc_use_alloca (alloca_used
1462
+-					       + dirlen + 1 + patlen + 1);
1463
++      size_t fullsize;
1464
++      bool alloca_fullname
1465
++        = (! size_add_wrapv (dirlen + 1, patlen + 1, &fullsize)
1466
++           && glob_use_alloca (alloca_used, fullsize));
1467
+       char *fullname;
1468
+       if (alloca_fullname)
1469
+-	fullname = alloca_account (dirlen + 1 + patlen + 1, alloca_used);
1470
++        fullname = alloca_account (fullsize, alloca_used);
1471
+       else
1472
+ 	{
1473
+-	  fullname = malloc (dirlen + 1 + patlen + 1);
1474
++	  fullname = malloc (fullsize);
1475
+ 	  if (fullname == NULL)
1476
+ 	    return GLOB_NOSPACE;
1477
+ 	}
1478
+@@ -1552,9 +1509,11 @@ glob_in_dir (const char *pattern, const
1479
+       mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
1480
+ 			"/", 1),
1481
+ 	       pattern, patlen + 1);
1482
+-      if ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1483
++      if (((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1484
+ 	   ? (*pglob->gl_stat) (fullname, &ust.st)
1485
+-	   : __stat64 (fullname, &ust.st64)) == 0)
1486
++	    : __stat64 (fullname, &ust.st64))
1487
++	   == 0)
1488
++	  || errno == EOVERFLOW)
1489
+ 	/* We found this file to be existing.  Now tell the rest
1490
+ 	   of the function to copy this name into the result.  */
1491
+ 	flags |= GLOB_NOCHECK;
1492
+@@ -1576,16 +1535,10 @@ glob_in_dir (const char *pattern, const
1493
+ 	}
1494
+       else
1495
+ 	{
1496
+-#ifdef _LIBC
1497
+ 	  int dfd = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
1498
+ 		     ? -1 : dirfd ((DIR *) stream));
1499
+-#endif
1500
+ 	  int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
1501
+-			   | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
1502
+-#if defined _AMIGA || defined VMS
1503
+-			   | FNM_CASEFOLD
1504
+-#endif
1505
+-			   );
1506
++			   | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
1507
+ 	  flags |= GLOB_MAGCHAR;
1508
+ 
1509
+ 	  while (1)
1510
+@@ -1605,19 +1558,24 @@ glob_in_dir (const char *pattern, const
1511
+ 	      }
1512
+ 	      if (d.name == NULL)
1513
+ 		break;
1514
+-	      if (d.skip_entry)
1515
++	      if (readdir_result_skip_entry (d))
1516
+ 		continue;
1517
+ 
1518
+ 	      /* If we shall match only directories use the information
1519
+ 		 provided by the dirent call if possible.  */
1520
+-	      if ((flags & GLOB_ONLYDIR) && !readdir_result_might_be_dir (d))
1521
+-		continue;
1522
++	      if (flags & GLOB_ONLYDIR)
1523
++		switch (readdir_result_type (d))
1524
++		  {
1525
++		  case DT_DIR: case DT_LNK: case DT_UNKNOWN: break;
1526
++		  default: continue;
1527
++		  }
1528
+ 
1529
+ 	      if (fnmatch (pattern, d.name, fnm_flags) == 0)
1530
+ 		{
1531
+ 		  /* If the file we found is a symlink we have to
1532
+ 		     make sure the target file exists.  */
1533
+-		  if (!readdir_result_might_be_symlink (d)
1534
++		  dirent_type type = readdir_result_type (d);
1535
++		  if (! (type == DT_LNK || type == DT_UNKNOWN)
1536
+ 		      || link_exists_p (dfd, directory, dirlen, d.name,
1537
+ 					pglob, flags))
1538
+ 		    {
1539
+@@ -1625,10 +1583,13 @@ glob_in_dir (const char *pattern, const
1540
+ 			{
1541
+ 			  struct globnames *newnames;
1542
+ 			  size_t count = names->count * 2;
1543
+-			  size_t size = (sizeof (struct globnames)
1544
+-					 + ((count - INITIAL_COUNT)
1545
+-					    * sizeof (char *)));
1546
+-			  if (__libc_use_alloca (alloca_used + size))
1547
++			  size_t nameoff = offsetof (struct globnames, name);
1548
++			  size_t size = FLEXSIZEOF (struct globnames, name,
1549
++						    count * sizeof (char *));
1550
++			  if ((SIZE_MAX - nameoff) / 2 / sizeof (char *)
1551
++			      < names->count)
1552
++			    goto memory_error;
1553
++			  if (glob_use_alloca (alloca_used, size))
1554
+ 			    newnames = names_alloca
1555
+ 			      = alloca_account (size, alloca_used);
1556
+ 			  else if ((newnames = malloc (size))
1557
+@@ -1644,6 +1605,8 @@ glob_in_dir (const char *pattern, const
1558
+ 			goto memory_error;
1559
+ 		      ++cur;
1560
+ 		      ++nfound;
1561
++		      if (SIZE_MAX - pglob->gl_offs <= nfound)
1562
++			goto memory_error;
1563
+ 		    }
1564
+ 		}
1565
+ 	    }
1566
+@@ -1654,29 +1617,27 @@ glob_in_dir (const char *pattern, const
1567
+     {
1568
+       size_t len = strlen (pattern);
1569
+       nfound = 1;
1570
+-      names->name[cur] = (char *) malloc (len + 1);
1571
++      names->name[cur] = malloc (len + 1);
1572
+       if (names->name[cur] == NULL)
1573
+ 	goto memory_error;
1574
+       *((char *) mempcpy (names->name[cur++], pattern, len)) = '\0';
1575
+     }
1576
+ 
1577
+-  int result = GLOB_NOMATCH;
1578
++  result = GLOB_NOMATCH;
1579
+   if (nfound != 0)
1580
+     {
1581
++      char **new_gl_pathv;
1582
+       result = 0;
1583
+ 
1584
+-      if (pglob->gl_pathc > UINTPTR_MAX - pglob->gl_offs
1585
+-	  || pglob->gl_pathc + pglob->gl_offs > UINTPTR_MAX - nfound
1586
+-	  || pglob->gl_pathc + pglob->gl_offs + nfound > UINTPTR_MAX - 1
1587
+-	  || (pglob->gl_pathc + pglob->gl_offs + nfound + 1
1588
+-	      > UINTPTR_MAX / sizeof (char *)))
1589
++      if (SIZE_MAX / sizeof (char *) - pglob->gl_pathc
1590
++	  < pglob->gl_offs + nfound + 1)
1591
+ 	goto memory_error;
1592
+ 
1593
+-      char **new_gl_pathv;
1594
+       new_gl_pathv
1595
+-	= (char **) realloc (pglob->gl_pathv,
1596
+-			     (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
1597
+-			     * sizeof (char *));
1598
++	= realloc (pglob->gl_pathv,
1599
++		   (pglob->gl_pathc + pglob->gl_offs + nfound + 1)
1600
++		    * sizeof (char *));
1601
++
1602
+       if (new_gl_pathv == NULL)
1603
+ 	{
1604
+ 	memory_error:
1605
+@@ -1692,7 +1653,7 @@ glob_in_dir (const char *pattern, const
1606
+ 		 and this is the block assigned to OLD here.  */
1607
+ 	      if (names == NULL)
1608
+ 		{
1609
+-		  assert (old == &init_names);
1610
++		  assert (old == init_names);
1611
+ 		  break;
1612
+ 		}
1613
+ 	      cur = names->count;
1614
+@@ -1718,7 +1679,7 @@ glob_in_dir (const char *pattern, const
1615
+ 		 and this is the block assigned to OLD here.  */
1616
+ 	      if (names == NULL)
1617
+ 		{
1618
+-		  assert (old == &init_names);
1619
++		  assert (old == init_names);
1620
+ 		  break;
1621
+ 		}
1622
+ 	      cur = names->count;
1623
+Index: glibc-2.22/posix/glob64.c
1624
+===================================================================
1625
+--- glibc-2.22.orig/posix/glob64.c
1626
+@@ -43,10 +43,4 @@ glob64 (const char *pattern, int flags,
1627
+ }
1628
+ libc_hidden_def (glob64)
1629
+ 
1630
+-void
1631
+-globfree64 (glob64_t *pglob)
1632
+-{
1633
+-}
1634
+-libc_hidden_def (globfree64)
1635
+-
1636
+ stub_warning (glob64)
1637
+Index: glibc-2.22/posix/glob_internal.h
1638
+===================================================================
1639
+--- /dev/null
1640
+@@ -0,0 +1,57 @@
1641
++/* Shared definition for glob and glob_pattern_p.
1642
++   Copyright (C) 2017 Free Software Foundation, Inc.
1643
++   This file is part of the GNU C Library.
1644
++
1645
++   The GNU C Library is free software; you can redistribute it and/or
1646
++   modify it under the terms of the GNU Lesser General Public
1647
++   License as published by the Free Software Foundation; either
1648
++   version 2.1 of the License, or (at your option) any later version.
1649
++
1650
++   The GNU C Library is distributed in the hope that it will be useful,
1651
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
1652
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1653
++   Lesser General Public License for more details.
1654
++
1655
++   You should have received a copy of the GNU Lesser General Public
1656
++   License along with the GNU C Library; if not, see
1657
++   <http://www.gnu.org/licenses/>.  */
1658
++
1659
++#ifndef GLOB_INTERNAL_H
1660
++# define GLOB_INTERNAL_H
1661
++
1662
++static inline int
1663
++__glob_pattern_type (const char *pattern, int quote)
1664
++{
1665
++  const char *p;
1666
++  int ret = 0;
1667
++
1668
++  for (p = pattern; *p != '\0'; ++p)
1669
++    switch (*p)
1670
++      {
1671
++      case '?':
1672
++      case '*':
1673
++        return 1;
1674
++
1675
++      case '\\':
1676
++        if (quote)
1677
++          {
1678
++            if (p[1] != '\0')
1679
++              ++p;
1680
++            ret |= 2;
1681
++          }
1682
++        break;
1683
++
1684
++      case '[':
1685
++        ret |= 4;
1686
++        break;
1687
++
1688
++      case ']':
1689
++        if (ret & 4)
1690
++          return 1;
1691
++        break;
1692
++      }
1693
++
1694
++  return ret;
1695
++}
1696
++
1697
++#endif /* GLOB_INTERNAL_H  */
1698
+Index: glibc-2.22/posix/glob_pattern_p.c
1699
+===================================================================
1700
+--- /dev/null
1701
+@@ -0,0 +1,33 @@
1702
++/* Return nonzero if PATTERN contains any metacharacters.
1703
++   Copyright (C) 2017 Free Software Foundation, Inc.
1704
++   This file is part of the GNU C Library.
1705
++
1706
++   The GNU C Library is free software; you can redistribute it and/or
1707
++   modify it under the terms of the GNU Lesser General Public
1708
++   License as published by the Free Software Foundation; either
1709
++   version 2.1 of the License, or (at your option) any later version.
1710
++
1711
++   The GNU C Library is distributed in the hope that it will be useful,
1712
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
1713
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1714
++   Lesser General Public License for more details.
1715
++
1716
++   You should have received a copy of the GNU Lesser General Public
1717
++   License along with the GNU C Library; if not, see
1718
++   <http://www.gnu.org/licenses/>.  */
1719
++
1720
++#ifndef _LIBC
1721
++# include <config.h>
1722
++#endif
1723
++
1724
++#include <glob.h>
1725
++#include "glob_internal.h"
1726
++
1727
++/* Return nonzero if PATTERN contains any metacharacters.
1728
++   Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */
1729
++int
1730
++__glob_pattern_p (const char *pattern, int quote)
1731
++{
1732
++  return __glob_pattern_type (pattern, quote) == 1;
1733
++}
1734
++weak_alias (__glob_pattern_p, glob_pattern_p)
1735
+Index: glibc-2.22/posix/globfree.c
1736
+===================================================================
1737
+--- /dev/null
1738
+@@ -0,0 +1,41 @@
1739
++/* Frees the dynamically allocated storage from an earlier call to glob.
1740
++   Copyright (C) 2017 Free Software Foundation, Inc.
1741
++   This file is part of the GNU C Library.
1742
++
1743
++   The GNU C Library is free software; you can redistribute it and/or
1744
++   modify it under the terms of the GNU Lesser General Public
1745
++   License as published by the Free Software Foundation; either
1746
++   version 2.1 of the License, or (at your option) any later version.
1747
++
1748
++   The GNU C Library is distributed in the hope that it will be useful,
1749
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
1750
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1751
++   Lesser General Public License for more details.
1752
++
1753
++   You should have received a copy of the GNU Lesser General Public
1754
++   License along with the GNU C Library; if not, see
1755
++   <http://www.gnu.org/licenses/>.  */
1756
++
1757
++#ifndef _LIBC
1758
++# include <config.h>
1759
++#endif
1760
++
1761
++#include <glob.h>
1762
++#include <stdlib.h>
1763
++
1764
++/* Free storage allocated in PGLOB by a previous `glob' call.  */
1765
++void
1766
++globfree (glob_t *pglob)
1767
++{
1768
++  if (pglob->gl_pathv != NULL)
1769
++    {
1770
++      size_t i;
1771
++      for (i = 0; i < pglob->gl_pathc; ++i)
1772
++        free (pglob->gl_pathv[pglob->gl_offs + i]);
1773
++      free (pglob->gl_pathv);
1774
++      pglob->gl_pathv = NULL;
1775
++    }
1776
++}
1777
++#ifndef globfree
1778
++libc_hidden_def (globfree)
1779
++#endif
1780
+Index: glibc-2.22/posix/globfree64.c
1781
+===================================================================
1782
+--- /dev/null
1783
+@@ -0,0 +1,31 @@
1784
++/* Frees the dynamically allocated storage from an earlier call to glob.
1785
++   Copyright (C) 2017 Free Software Foundation, Inc.
1786
++   This file is part of the GNU C Library.
1787
++
1788
++   The GNU C Library is free software; you can redistribute it and/or
1789
++   modify it under the terms of the GNU Lesser General Public
1790
++   License as published by the Free Software Foundation; either
1791
++   version 2.1 of the License, or (at your option) any later version.
1792
++
1793
++   The GNU C Library is distributed in the hope that it will be useful,
1794
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
1795
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1796
++   Lesser General Public License for more details.
1797
++
1798
++   You should have received a copy of the GNU Lesser General Public
1799
++   License along with the GNU C Library; if not, see
1800
++   <http://www.gnu.org/licenses/>.  */
1801
++
1802
++#ifndef _LIBC
1803
++# include <config.h>
1804
++#endif
1805
++
1806
++#include <glob.h>
1807
++#include <stdlib.h>
1808
++
1809
++/* Free storage allocated in PGLOB by a previous `glob' call.  */
1810
++void
1811
++globfree64 (glob64_t *pglob)
1812
++{
1813
++}
1814
++libc_hidden_def (globfree64)
1815
+Index: glibc-2.22/posix/tst-glob-tilde.c
1816
+===================================================================
1817
+--- /dev/null
1818
+@@ -0,0 +1,136 @@
1819
++/* Check for GLOB_TIDLE heap allocation issues (bug 22320, bug 22325).
1820
++   Copyright (C) 2017 Free Software Foundation, Inc.
1821
++   This file is part of the GNU C Library.
1822
++
1823
++   The GNU C Library is free software; you can redistribute it and/or
1824
++   modify it under the terms of the GNU Lesser General Public
1825
++   License as published by the Free Software Foundation; either
1826
++   version 2.1 of the License, or (at your option) any later version.
1827
++
1828
++   The GNU C Library is distributed in the hope that it will be useful,
1829
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
1830
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1831
++   Lesser General Public License for more details.
1832
++
1833
++   You should have received a copy of the GNU Lesser General Public
1834
++   License along with the GNU C Library; if not, see
1835
++   <http://www.gnu.org/licenses/>.  */
1836
++
1837
++#include <glob.h>
1838
++#include <mcheck.h>
1839
++#include <nss.h>
1840
++#include <pwd.h>
1841
++#include <stdlib.h>
1842
++#include <string.h>
1843
++#include <support/check.h>
1844
++#include <support/support.h>
1845
++
1846
++/* Flag which indicates whether to pass the GLOB_ONLYDIR flag.  */
1847
++static int do_onlydir;
1848
++
1849
++/* Flag which indicates whether to pass the GLOB_NOCHECK flag.  */
1850
++static int do_nocheck;
1851
++
1852
++/* Flag which indicates whether to pass the GLOB_MARK flag.  */
1853
++static int do_mark;
1854
++
1855
++static void
1856
++one_test (const char *prefix, const char *middle, const char *suffix)
1857
++{
1858
++  char *pattern = xasprintf ("%s%s%s", prefix, middle, suffix);
1859
++  int flags = GLOB_TILDE;
1860
++  if (do_onlydir)
1861
++    flags |= GLOB_ONLYDIR;
1862
++  if (do_nocheck)
1863
++    flags |= GLOB_NOCHECK;
1864
++  if (do_mark)
1865
++    flags |= GLOB_MARK;
1866
++  glob_t gl;
1867
++  /* This glob call might result in crashes or memory leaks.  */
1868
++  if (glob (pattern, flags, NULL, &gl) == 0)
1869
++    globfree (&gl);
1870
++  free (pattern);
1871
++}
1872
++
1873
++enum
1874
++  {
1875
++    /* The largest base being tested.  */
1876
++    largest_base_size = 500000,
1877
++
1878
++    /* The actual size is the base size plus a variable whose absolute
1879
++       value is not greater than this.  This helps malloc to trigger
1880
++       overflows.  */
1881
++    max_size_skew = 16,
1882
++
1883
++    /* The maximum string length supported by repeating_string
1884
++       below.  */
1885
++    repeat_size = largest_base_size + max_size_skew,
1886
++  };
1887
++
1888
++/* Used to construct strings which repeat a single character 'x'.  */
1889
++static char *repeat;
1890
++
1891
++/* Return a string of SIZE characters.  */
1892
++const char *
1893
++repeating_string (int size)
1894
++{
1895
++  TEST_VERIFY (size >= 0);
1896
++  TEST_VERIFY (size <= repeat_size);
1897
++  const char *repeated_shifted = repeat + repeat_size - size;
1898
++  TEST_VERIFY (strlen (repeated_shifted) == size);
1899
++  return repeated_shifted;
1900
++}
1901
++
1902
++static int
1903
++do_test (void)
1904
++{
1905
++  /* Avoid network-based NSS modules and initialize nss_files with a
1906
++     dummy lookup.  This has to come before mtrace because NSS does
1907
++     not free all memory.  */
1908
++  __nss_configure_lookup ("passwd", "files");
1909
++  (void) getpwnam ("root");
1910
++
1911
++  mtrace ();
1912
++
1913
++  repeat = xmalloc (repeat_size + 1);
1914
++  memset (repeat, 'x', repeat_size);
1915
++  repeat[repeat_size] = '\0';
1916
++
1917
++  /* These numbers control the size of the user name.  The values
1918
++     cover the minimum (0), a typical size (8), a large
1919
++     stack-allocated size (100000), and a somewhat large
1920
++     heap-allocated size (largest_base_size).  */
1921
++  static const int base_sizes[] = { 0, 8, 100, 100000, largest_base_size, -1 };
1922
++
1923
++  for (do_onlydir = 0; do_onlydir < 2; ++do_onlydir)
1924
++    for (do_nocheck = 0; do_nocheck < 2; ++do_nocheck)
1925
++      for (do_mark = 0; do_mark < 2; ++do_mark)
1926
++        for (int base_idx = 0; base_sizes[base_idx] >= 0; ++base_idx)
1927
++          {
1928
++            for (int size_skew = -max_size_skew; size_skew <= max_size_skew;
1929
++                 ++size_skew)
1930
++              {
1931
++                int size = base_sizes[base_idx] + size_skew;
1932
++                if (size < 0)
1933
++                  continue;
1934
++
1935
++                const char *user_name = repeating_string (size);
1936
++                one_test ("~", user_name, "/a/b");
1937
++              }
1938
++
1939
++            const char *user_name = repeating_string (base_sizes[base_idx]);
1940
++            one_test ("~", user_name, "");
1941
++            one_test ("~", user_name, "/");
1942
++            one_test ("~", user_name, "/a");
1943
++            one_test ("~", user_name, "/*/*");
1944
++            one_test ("~", user_name, "\\/");
1945
++            one_test ("/~", user_name, "");
1946
++            one_test ("*/~", user_name, "/a/b");
1947
++          }
1948
++
1949
++  free (repeat);
1950
++
1951
++  return 0;
1952
++}
1953
++
1954
++#include <support/test-driver.c>
1955
+Index: glibc-2.22/sysdeps/gnu/glob64.c
1956
+===================================================================
1957
+--- glibc-2.22.orig/sysdeps/gnu/glob64.c
1958
+@@ -15,11 +15,8 @@
1959
+ #undef __stat
1960
+ #define __stat(file, buf) __xstat64 (_STAT_VER, file, buf)
1961
+ 
1962
+-#define NO_GLOB_PATTERN_P 1
1963
+-
1964
+ #define COMPILE_GLOB64	1
1965
+ 
1966
+ #include <posix/glob.c>
1967
+ 
1968
+ libc_hidden_def (glob64)
1969
+-libc_hidden_def (globfree64)
1970
+Index: glibc-2.22/sysdeps/gnu/globfree64.c
1971
+===================================================================
1972
+--- /dev/null
1973
+@@ -0,0 +1,10 @@
1974
++#include <dirent.h>
1975
++#include <glob.h>
1976
++#include <sys/stat.h>
1977
++
1978
++#define glob_t glob64_t
1979
++#define globfree(pglob) globfree64 (pglob)
1980
++
1981
++#include <posix/globfree.c>
1982
++
1983
++libc_hidden_def (globfree64)
1984
+Index: glibc-2.22/sysdeps/unix/sysv/linux/Makefile
1985
+===================================================================
1986
+--- glibc-2.22.orig/sysdeps/unix/sysv/linux/Makefile
1987
+@@ -137,7 +137,7 @@ endif
1988
+ ifeq ($(subdir),posix)
1989
+ sysdep_headers += bits/initspin.h
1990
+ 
1991
+-sysdep_routines += sched_getcpu
1992
++sysdep_routines += sched_getcpu oldglob
1993
+ 
1994
+ tests += tst-getcpu
1995
+ 
1996
+Index: glibc-2.22/sysdeps/unix/sysv/linux/alpha/glob.c
1997
+===================================================================
1998
+--- glibc-2.22.orig/sysdeps/unix/sysv/linux/alpha/glob.c
1999
+@@ -42,10 +42,6 @@ extern void __new_globfree (glob_t *__pg
2000
+ #undef globfree64
2001
+ 
2002
+ versioned_symbol (libc, __new_glob, glob, GLIBC_2_1);
2003
+-versioned_symbol (libc, __new_globfree, globfree, GLIBC_2_1);
2004
+ libc_hidden_ver (__new_glob, glob)
2005
+-libc_hidden_ver (__new_globfree, globfree)
2006
+ 
2007
+ weak_alias (__new_glob, glob64)
2008
+-weak_alias (__new_globfree, globfree64)
2009
+-libc_hidden_ver (__new_globfree, globfree64)
2010
+Index: glibc-2.22/sysdeps/unix/sysv/linux/alpha/globfree.c
2011
+===================================================================
2012
+--- /dev/null
2013
+@@ -0,0 +1,37 @@
2014
++/* Compat globfree.  Linux/alpha version.
2015
++   Copyright (C) 2017 Free Software Foundation, Inc.
2016
++   This file is part of the GNU C Library.
2017
++
2018
++   The GNU C Library is free software; you can redistribute it and/or
2019
++   modify it under the terms of the GNU Lesser General Public
2020
++   License as published by the Free Software Foundation; either
2021
++   version 2.1 of the License, or (at your option) any later version.
2022
++
2023
++   The GNU C Library is distributed in the hope that it will be useful,
2024
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
2025
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
2026
++   Lesser General Public License for more details.
2027
++
2028
++   You should have received a copy of the GNU Lesser General Public
2029
++   License along with the GNU C Library.  If not, see
2030
++   <http://www.gnu.org/licenses/>.  */
2031
++
2032
++#define globfree64 __no_globfree64_decl
2033
++#include <sys/types.h>
2034
++#include <glob.h>
2035
++#include <shlib-compat.h>
2036
++
2037
++#define globfree(pglob) \
2038
++  __new_globfree (pglob)
2039
++
2040
++extern void __new_globfree (glob_t *__pglob);
2041
++
2042
++#include <posix/globfree.c>
2043
++
2044
++#undef globfree64
2045
++
2046
++versioned_symbol (libc, __new_globfree, globfree, GLIBC_2_1);
2047
++libc_hidden_ver (__new_globfree, globfree)
2048
++
2049
++weak_alias (__new_globfree, globfree64)
2050
++libc_hidden_ver (__new_globfree, globfree64)
2051
+Index: glibc-2.22/sysdeps/unix/sysv/linux/i386/glob64.c
2052
+===================================================================
2053
+--- glibc-2.22.orig/sysdeps/unix/sysv/linux/i386/glob64.c
2054
+@@ -19,6 +19,7 @@
2055
+ #include <dirent.h>
2056
+ #include <glob.h>
2057
+ #include <sys/stat.h>
2058
++#include <shlib-compat.h>
2059
+ 
2060
+ #define dirent dirent64
2061
+ #define __readdir(dirp) __readdir64 (dirp)
2062
+@@ -33,44 +34,9 @@
2063
+ #undef __stat
2064
+ #define __stat(file, buf) __xstat64 (_STAT_VER, file, buf)
2065
+ 
2066
+-#define NO_GLOB_PATTERN_P 1
2067
+-
2068
+ #define COMPILE_GLOB64	1
2069
+ 
2070
+ #include <posix/glob.c>
2071
+ 
2072
+-#include "shlib-compat.h"
2073
+-
2074
+-libc_hidden_def (globfree64)
2075
+-
2076
+ versioned_symbol (libc, __glob64, glob64, GLIBC_2_2);
2077
+ libc_hidden_ver (__glob64, glob64)
2078
+-
2079
+-#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
2080
+-
2081
+-#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
2082
+-
2083
+-int __old_glob64 (const char *__pattern, int __flags,
2084
+-		  int (*__errfunc) (const char *, int),
2085
+-		  glob64_t *__pglob);
2086
+-
2087
+-#undef dirent
2088
+-#define dirent __old_dirent64
2089
+-#undef GL_READDIR
2090
+-# define GL_READDIR(pglob, stream) \
2091
+-  ((struct __old_dirent64 *) (pglob)->gl_readdir (stream))
2092
+-#undef __readdir
2093
+-#define __readdir(dirp) __old_readdir64 (dirp)
2094
+-#undef glob
2095
+-#define glob(pattern, flags, errfunc, pglob) \
2096
+-  __old_glob64 (pattern, flags, errfunc, pglob)
2097
+-#define convert_dirent __old_convert_dirent
2098
+-#define glob_in_dir __old_glob_in_dir
2099
+-#define GLOB_ATTRIBUTE attribute_compat_text_section
2100
+-
2101
+-#define GLOB_ONLY_P 1
2102
+-
2103
+-#include <posix/glob.c>
2104
+-
2105
+-compat_symbol (libc, __old_glob64, glob64, GLIBC_2_1);
2106
+-#endif
2107
+Index: glibc-2.22/sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c
2108
+===================================================================
2109
+--- /dev/null
2110
+@@ -0,0 +1 @@
2111
++/* glob64 is in globfree64.c */
2112
+Index: glibc-2.22/sysdeps/unix/sysv/linux/oldglob.c
2113
+===================================================================
2114
+--- /dev/null
2115
+@@ -0,0 +1,42 @@
2116
++#include <shlib-compat.h>
2117
++
2118
++#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
2119
++
2120
++#include <dirent.h>
2121
++#include <glob.h>
2122
++#include <sys/stat.h>
2123
++
2124
++#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
2125
++
2126
++int __old_glob64 (const char *__pattern, int __flags,
2127
++		  int (*__errfunc) (const char *, int),
2128
++		  glob64_t *__pglob);
2129
++libc_hidden_proto (__old_glob64);
2130
++
2131
++#define dirent __old_dirent64
2132
++#define GL_READDIR(pglob, stream) \
2133
++  ((struct __old_dirent64 *) (pglob)->gl_readdir (stream))
2134
++#undef __readdir
2135
++#define __readdir(dirp) __old_readdir64 (dirp)
2136
++
2137
++#define glob_t glob64_t
2138
++#define glob(pattern, flags, errfunc, pglob) \
2139
++  __old_glob64 (pattern, flags, errfunc, pglob)
2140
++#define globfree(pglob) globfree64(pglob)
2141
++
2142
++#define convert_dirent __old_convert_dirent
2143
++#define glob_in_dir __old_glob_in_dir
2144
++
2145
++#undef stat
2146
++#define stat stat64
2147
++#undef __stat
2148
++#define __stat(file, buf) __xstat64 (_STAT_VER, file, buf)
2149
++
2150
++#define GLOB_ATTRIBUTE attribute_compat_text_section
2151
++
2152
++#include <posix/glob.c>
2153
++
2154
++libc_hidden_def (__old_glob64);
2155
++
2156
++compat_symbol (libc, __old_glob64, glob64, GLIBC_2_1);
2157
++#endif
2158
+Index: glibc-2.22/sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c
2159
+===================================================================
2160
+--- /dev/null
2161
+@@ -0,0 +1 @@
2162
++/* no old glob */
2163
+Index: glibc-2.22/sysdeps/unix/sysv/linux/wordsize-64/globfree64.c
2164
+===================================================================
2165
+--- /dev/null
2166
+@@ -0,0 +1,2 @@
2167
++/* This file is here so sysdeps/gnu/glob64.c doesn't take precedence.  */
2168
++#include <sysdeps/wordsize-64/globfree64.c>
2169
+Index: glibc-2.22/sysdeps/unix/sysv/linux/x86_64/x32/globfree.c
2170
+===================================================================
2171
+--- /dev/null
2172
+@@ -0,0 +1 @@
2173
++#include <sysdeps/wordsize-64/globfree.c>
2174
+Index: glibc-2.22/sysdeps/wordsize-64/glob.c
2175
+===================================================================
2176
+--- glibc-2.22.orig/sysdeps/wordsize-64/glob.c
2177
+@@ -4,5 +4,3 @@
2178
+ #undef glob64
2179
+ #undef globfree64
2180
+ weak_alias (glob, glob64)
2181
+-weak_alias (globfree, globfree64)
2182
+-libc_hidden_ver (globfree, globfree64)
2183
+Index: glibc-2.22/sysdeps/wordsize-64/globfree.c
2184
+===================================================================
2185
+--- /dev/null
2186
+@@ -0,0 +1,5 @@
2187
++#define globfree64 __no_globfree64_decl
2188
++#include <posix/globfree.c>
2189
++#undef globfree64
2190
++weak_alias (globfree, globfree64)
2191
++libc_hidden_ver (globfree, globfree64)
2192
+Index: glibc-2.22/sysdeps/wordsize-64/globfree64.c
2193
+===================================================================
2194
+--- /dev/null
2195
+@@ -0,0 +1 @@
2196
++/* globfree64 is in globfree.c */
... ...
@@ -6,7 +6,7 @@
6 6
 Summary:        Main C library
7 7
 Name:           glibc
8 8
 Version:        2.22
9
-Release:        21%{?dist}
9
+Release:        22%{?dist}
10 10
 License:        LGPLv2+
11 11
 URL:            http://www.gnu.org/software/libc
12 12
 Group:          Applications/System
... ...
@@ -50,6 +50,7 @@ Patch22:        glibc-fix-CVE-2018-1000001.patch
50 50
 Patch23:        glibc-fix-CVE-2018-6485.patch
51 51
 Patch24:        glibc-fix-CVE-2017-18269.patch
52 52
 Patch25:        glibc-fix-CVE-2018-11236.patch
53
+Patch26:        glibc-fix-CVE-2017-15671.patch
53 54
 Provides:       rtld(GNU_HASH)
54 55
 Requires:       filesystem
55 56
 %description
... ...
@@ -101,6 +102,7 @@ sed -i 's/\\$$(pwd)/`pwd`/' timezone/Makefile
101 101
 %patch23 -p1
102 102
 %patch24 -p1
103 103
 %patch25 -p1
104
+%patch26 -p1
104 105
 
105 106
 install -vdm 755 %{_builddir}/%{name}-build
106 107
 # do not try to explicitly provide GLIBC_PRIVATE versioned libraries
... ...
@@ -228,6 +230,8 @@ popd
228 228
 %{_datarootdir}/locale/locale.alias
229 229
 
230 230
 %changelog
231
+*   Thu Aug 09 2018 Keerthana K <keerthanak@vmware.com> 2.22-22
232
+-   Fix for CVE-2017-15761.
231 233
 *   Tue Jun 26 2018 Keerthana K <keerthnanak@vmware.com> 2.22-21
232 234
 -   Fix for CVE-2018-11236.
233 235
 *   Mon Jun 25 2018 Keerthana K <keerthanak@vmware.com> 2.22-20