Browse code

[BUG 1986103] glob(), in glob.c, could skip freeing allocated memory when processing ~ operator

The function glob(), in glob.c, when invoked with GLOB_TILDE, could skip freeing allocated memory when processing the ~ operator with a long user name, potentially leading to a denial of service (memory leak).
Reference: https://bugzilla.eng.vmware.com/show_bug.cgi?id=1986103

Change-Id: I8de9cb9f136b543dc75dbe22e06cbd8a2338aa86

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