Ticket #1185: glibc-2.26-glob_fixes-1.patch
File glibc-2.26-glob_fixes-1.patch, 82.1 KB (added by , 6 years ago) |
---|
-
ChangeLog
Submitted by: William Harrington (kb0iic at clfs dot ort) Date: 2018-01-05 Initial Package Version: 2.26 Origin: https://sourceware.org/bugzilla/show_bug.cgi?id=22320 https://sourceware.org/bugzilla/show_bug.cgi?id=22325 https://sourceware.org/bugzilla/show_bug.cgi?id=22332 Description: Fixes Memory leak in glob with GLOB_TILDE Fixes Buffer overflow in glob with GLOB_TILDE in unescaping diff -Naur glibc-2.26.orig/ChangeLog glibc-2.26/ChangeLog
old new 1 2017-08-20 H.J. Lu <hongjiu.lu@intel.com> 2 3 [BZ #18822] 4 * sysdeps/unix/sysv/linux/i386/glob64.c (__old_glob64): Add 5 libc_hidden_proto and libc_hidden_def. 6 7 2017-09-08 Adhemerval Zanella <adhemerval.zanella@linaro.org> 8 9 [BZ #1062] 10 [BZ #22325] 11 CVE-2017-15671 12 * posix/Makefile (routines): Add globfree, globfree64, and 13 glob_pattern_p. 14 * posix/flexmember.h: New file. 15 * posix/glob_internal.h: Likewise. 16 * posix/glob_pattern_p.c: Likewise. 17 * posix/globfree.c: Likewise. 18 * posix/globfree64.c: Likewise. 19 * sysdeps/gnu/globfree64.c: Likewise. 20 * sysdeps/unix/sysv/linux/alpha/globfree.c: Likewise. 21 * sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c: Likewise. 22 * sysdeps/unix/sysv/linux/oldglob.c: Likewise. 23 * sysdeps/unix/sysv/linux/wordsize-64/globfree64.c: Likewise. 24 * sysdeps/unix/sysv/linux/x86_64/x32/globfree.c: Likewise. 25 * sysdeps/wordsize-64/globfree.c: Likewise. 26 * sysdeps/wordsize-64/globfree64.c: Likewise. 27 * posix/glob.c (HAVE_CONFIG_H): Use !_LIBC instead. 28 [NDEBUG): Remove comments. 29 (GLOB_ONLY_P, _AMIGA, VMS): Remove define. 30 (dirent_type): New type. Use uint_fast8_t not 31 uint8_t, as C99 does not require uint8_t. 32 (DT_UNKNOWN, DT_DIR, DT_LNK): New macros. 33 (struct readdir_result): Use dirent_type. Do not define skip_entry 34 unless it is needed; this saves a byte on platforms lacking d_ino. 35 (readdir_result_type, readdir_result_skip_entry): 36 New functions, replacing ... 37 (readdir_result_might_be_symlink, readdir_result_might_be_dir): 38 these functions, which were removed. This makes the callers 39 easier to read. All callers changed. 40 (D_INO_TO_RESULT): Now empty if there is no d_ino. 41 (size_add_wrapv, glob_use_alloca): New static functions. 42 (glob, glob_in_dir): Check for size_t overflow in several places, 43 and fix some size_t checks that were not quite right. 44 Remove old code using SHELL since Bash no longer 45 uses this. 46 (glob, prefix_array): Separate MS code better. 47 (glob_in_dir): Remove old Amiga and VMS code. 48 (globfree, __glob_pattern_type, __glob_pattern_p): Move to 49 separate files. 50 (glob_in_dir): Do not rely on undefined behavior in accessing 51 struct members beyond their bounds. Use a flexible array member 52 instead 53 (link_stat): Rename from link_exists2_p and return -1/0 instead of 54 0/1. Caller changed. 55 (glob): Fix memory leaks. 56 * posix/glob64 (globfree64): Move to separate file. 57 * sysdeps/gnu/glob64.c (NO_GLOB_PATTERN_P): Remove define. 58 (globfree64): Remove hidden alias. 59 * sysdeps/unix/sysv/linux/Makefile (sysdeps_routines): Add 60 oldglob. 61 * sysdeps/unix/sysv/linux/alpha/glob.c (__new_globfree): Move to 62 separate file. 63 * sysdeps/unix/sysv/linux/i386/glob64.c (NO_GLOB_PATTERN_P): Remove 64 define. 65 Move compat code to separate file. 66 * sysdeps/wordsize-64/glob.c (globfree): Move definitions to 67 separate file. 68 69 2017-10-20 Paul Eggert <eggert@cs.ucla.edu> 70 71 [BZ #22320] 72 CVE-2017-15670 73 * posix/glob.c (__glob): Fix one-byte overflow. 74 75 2017-10-21 Florian Weimer <fweimer@redhat.com> 76 77 * posix/Makefile (tests): Add tst-glob-tilde. 78 (tests-special): Add tst-glob-tilde-mem.out 79 (tst-glob-tilde-ENV): Set MALLOC_TRACE. 80 (tst-glob-tilde-mem.out): Add mtrace check. 81 * posix/tst-glob-tilde.c: New file. 82 83 2017-09-08 Adhemerval Zanella <adhemerval.zanella@linaro.org> 84 85 * sysdeps/unix/sysv/linux/arm/glob64.c: Remove file. 86 * sysdeps/unix/sysv/linux/i386/glob64.c: Likewise. 87 * sysdeps/unix/sysv/linux/m68k/glob64.c: Likewise. 88 * sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c: Likewise. 89 * sysdeps/unix/sysv/linux/mips/mips64/n64/globfree64.c: Likewise. 90 * sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c: Likewise. 91 * sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c: Likewise. 92 * sysdeps/unix/sysv/linux/wordsize-64/glob64.c: Likewise. 93 * sysdeps/unix/sysv/linux/wordsize-64/globfree64.c: Likewise. 94 * sysdeps/unix/sysv/linux/x86_64/x32/glob.c: Likewise. 95 * sysdeps/unix/sysv/linux/x86_64/x32/globfree.c: Likewise. 96 * sysdeps/wordsize-64/glob.c: Likewise. 97 * sysdeps/wordsize-64/glob64.c: Likewise. 98 * sysdeps/wordsize-64/globfree.c: Likewise. 99 * sysdeps/wordsize-64/globfree64.c: Likewise. 100 * sysdeps/unix/sysv/linux/glob.c: New file. 101 * sysdeps/unix/sysv/linux/glob64.c: Likewise. 102 * sysdeps/unix/sysv/linux/globfree.c: Likewise. 103 * sysdeps/unix/sysv/linux/globfree64.c: Likewise. 104 * sysdeps/unix/sysv/linux/s390/s390-32/glob64.c: Likewise. 105 * sysdeps/unix/sysv/linux/oldglob.c [SHLIB_COMPAT]: Also 106 adds !GLOB_NO_OLD_VERSION as an extra condition. 107 * sysdeps/unix/sysv/linux/i386/alphasort64.c: Include olddirent.h 108 using relative path instead of absolute one. 109 * sysdeps/unix/sysv/linux/i386/getdents64.c: Likewise. 110 * sysdeps/unix/sysv/linux/i386/readdir64.c: Likewise. 111 * sysdeps/unix/sysv/linux/i386/readdir64_r.c: Likewise. 112 * sysdeps/unix/sysv/linux/i386/versionsort64.c: Likewise. 113 * sysdeps/unix/sysv/linux/i386/olddirent.h: Move to ... 114 * sysdeps/unix/sysv/linux//olddirent.h: ... here. 115 116 2017-09-13 Adhemerval Zanella <adhemerval.zanella@linaro.org> 117 118 * sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c: New file. 119 * sysdeps/unix/sysv/linux/alpha/Makefile 120 [$(subdir) = csu] (sysdep_routines): Remove rule. 121 122 2017-10-22 Paul Eggert <eggert@cs.ucla.edu> 123 124 [BZ #22332] 125 * posix/glob.c (__glob): Fix buffer overflow during GLOB_TILDE 126 unescaping. 127 1 128 2017-08-02 Siddhesh Poyarekar <siddhesh@sourceware.org> 2 129 3 130 * version.h (RELEASE): Set to "stable" -
glibc-2.26
diff -Naur glibc-2.26.orig/NEWS glibc-2.26/NEWS
old new 5 5 Please send GNU C library bug reports via <http://sourceware.org/bugzilla/> 6 6 using `glibc' in the "product" field. 7 7 8 8 9 Version 2.26.1 10 11 CVE-2017-15670: The glob function, when invoked with GLOB_TILDE, 12 suffered from a one-byte overflow during ~ operator processing (either 13 on the stack or the heap, depending on the length of the user name). 14 Reported by Tim RÃŒhsen. 15 16 The glob function, when invoked with GLOB_TILDE and without 17 GLOB_NOESCAPE, could write past the end of a buffer while 18 unescaping user names. Reported by Tim RÃŒhsen. 19 20 The following bugs are resolved with this release: 21 22 [22325] glibc: Memory leak in glob with GLOB_TILDE (CVE-2017-15671) 23 [21885] getaddrinfo: Release resolver context on error in gethosts 24 9 25 10 26 Version 2.26 -
posix/Makefile
Major new features: diff -Naur glibc-2.26.orig/posix/Makefile glibc-2.26/posix/Makefile
old new 45 45 getpgid setpgid getpgrp bsd-getpgrp setpgrp getsid setsid \ 46 46 getresuid getresgid setresuid setresgid \ 47 47 pathconf sysconf fpathconf \ 48 glob glob64 fnmatch regex\48 glob glob64 globfree globfree64 glob_pattern_p fnmatch regex \ 49 49 confstr \ 50 50 getopt getopt1 \ 51 51 sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax \ … … 93 93 tst-fnmatch3 bug-regex36 tst-getaddrinfo5 \ 94 94 tst-posix_spawn-fd tst-posix_spawn-setsid \ 95 95 tst-posix_fadvise tst-posix_fadvise64 \ 96 tst-sysconf-empty-chroot 96 tst-sysconf-empty-chroot tst-glob-tilde 97 97 tests-internal := bug-regex5 bug-regex20 bug-regex33 \ 98 98 tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 99 99 xtests := bug-ga2 … … 141 141 $(objpfx)tst-rxspencer-no-utf8-mem.out $(objpfx)tst-pcre-mem.out \ 142 142 $(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \ 143 143 $(objpfx)bug-glob2-mem.out $(objpfx)tst-vfork3-mem.out \ 144 $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out 144 $(objpfx)tst-fnmatch-mem.out $(objpfx)bug-regex36-mem.out \ 145 $(objpfx)tst-glob-tilde-mem.out 145 146 xtests-special += $(objpfx)bug-ga2-mem.out 146 147 endif 147 148 … … 350 351 $(common-objpfx)malloc/mtrace $(objpfx)bug-glob2.mtrace > $@; \ 351 352 $(evaluate-test) 352 353 354 tst-glob-tilde-ENV = MALLOC_TRACE=$(objpfx)tst-glob-tilde.mtrace 355 356 $(objpfx)tst-glob-tilde-mem.out: $(objpfx)tst-glob-tilde.out 357 $(common-objpfx)malloc/mtrace $(objpfx)tst-glob-tilde.mtrace > $@; \ 358 $(evaluate-test) 359 353 360 $(inst_libexecdir)/getconf: $(inst_bindir)/getconf \ 354 361 $(objpfx)getconf.speclist FORCE 355 362 $(addprefix $(..)./scripts/mkinstalldirs ,\ -
posix/flexmember.h
diff -Naur glibc-2.26.orig/posix/flexmember.h glibc-2.26/posix/flexmember.h
old new 1 /* Sizes of structs with flexible array members. 2 3 Copyright 2016-2017 Free Software Foundation, Inc. 4 5 This file is part of the GNU C Library. 6 7 The GNU C Library is free software; you can redistribute it and/or 8 modify it under the terms of the GNU Lesser General Public 9 License as published by the Free Software Foundation; either 10 version 2.1 of the License, or (at your option) any later version. 11 12 The GNU C Library is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 Lesser General Public License for more details. 16 17 You should have received a copy of the GNU Lesser General Public 18 License along with the GNU C Library; if not, see 19 <http://www.gnu.org/licenses/>. 20 21 Written by Paul Eggert. */ 22 23 #include <stddef.h> 24 25 /* Nonzero multiple of alignment of TYPE, suitable for FLEXSIZEOF below. 26 On older platforms without _Alignof, use a pessimistic bound that is 27 safe in practice even if FLEXIBLE_ARRAY_MEMBER is 1. 28 On newer platforms, use _Alignof to get a tighter bound. */ 29 30 #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112 31 # define FLEXALIGNOF(type) (sizeof (type) & ~ (sizeof (type) - 1)) 32 #else 33 # define FLEXALIGNOF(type) _Alignof (type) 34 #endif 35 36 /* Upper bound on the size of a struct of type TYPE with a flexible 37 array member named MEMBER that is followed by N bytes of other data. 38 This is not simply sizeof (TYPE) + N, since it may require 39 alignment on unusually picky C11 platforms, and 40 FLEXIBLE_ARRAY_MEMBER may be 1 on pre-C11 platforms. 41 Yield a value less than N if and only if arithmetic overflow occurs. */ 42 43 #define FLEXSIZEOF(type, member, n) \ 44 ((offsetof (type, member) + FLEXALIGNOF (type) - 1 + (n)) \ 45 & ~ (FLEXALIGNOF (type) - 1)) -
posix/glob.c
diff -Naur glibc-2.26.orig/posix/glob.c glibc-2.26/posix/glob.c
old new 15 15 License along with the GNU C Library; if not, see 16 16 <http://www.gnu.org/licenses/>. */ 17 17 18 #if def HAVE_CONFIG_H18 #ifndef _LIBC 19 19 # include <config.h> 20 20 #endif 21 21 … … 27 27 #include <stdbool.h> 28 28 #include <stddef.h> 29 29 #include <stdint.h> 30 31 /* Outcomment the following line for production quality code. */32 /* #define NDEBUG 1 */33 30 #include <assert.h> 31 #include <unistd.h> 34 32 35 #include <stdio.h> /* Needed on stupid SunOS for assert. */ 36 37 #if !defined _LIBC || !defined GLOB_ONLY_P 38 #if defined HAVE_UNISTD_H || defined _LIBC 39 # include <unistd.h> 40 # ifndef POSIX 41 # ifdef _POSIX_VERSION 42 # define POSIX 43 # endif 44 # endif 33 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ 34 # define WINDOWS32 45 35 #endif 46 36 47 #include <pwd.h> 48 49 #if defined HAVE_STDINT_H || defined _LIBC 50 # include <stdint.h> 51 #elif !defined UINTPTR_MAX 52 # define UINTPTR_MAX (~((size_t) 0)) 37 #ifndef WINDOWS32 38 # include <pwd.h> 53 39 #endif 54 40 55 41 #include <errno.h> … … 57 43 # define __set_errno(val) errno = (val) 58 44 #endif 59 45 60 #if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__ 61 # include <dirent.h> 62 #else 63 # define dirent direct 64 # ifdef HAVE_SYS_NDIR_H 65 # include <sys/ndir.h> 66 # endif 67 # ifdef HAVE_SYS_DIR_H 68 # include <sys/dir.h> 69 # endif 70 # ifdef HAVE_NDIR_H 71 # include <ndir.h> 72 # endif 73 # ifdef HAVE_VMSDIR_H 74 # include "vmsdir.h" 75 # endif /* HAVE_VMSDIR_H */ 76 #endif 77 46 #include <dirent.h> 78 47 #include <stdlib.h> 79 48 #include <string.h> 80 49 #include <alloca.h> … … 87 56 # define opendir(name) __opendir (name) 88 57 # define readdir(str) __readdir64 (str) 89 58 # define getpwnam_r(name, bufp, buf, len, res) \ 90 __getpwnam_r (name, bufp, buf, len, res)59 __getpwnam_r (name, bufp, buf, len, res) 91 60 # ifndef __stat64 92 61 # define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf) 93 62 # endif 94 63 # define struct_stat64 struct stat64 64 # define FLEXIBLE_ARRAY_MEMBER 95 65 #else /* !_LIBC */ 96 # include "getlogin_r.h" 97 # include "mempcpy.h" 98 # include "stat-macros.h" 99 # include "strdup.h" 100 # define __stat64(fname, buf) stat (fname, buf) 101 # define struct_stat64 struct stat 102 # define __stat(fname, buf) stat (fname, buf) 103 # define __alloca alloca 104 # define __readdir readdir 105 # define __readdir64 readdir64 106 # define __glob_pattern_p glob_pattern_p 66 # define __getlogin_r(buf, len) getlogin_r (buf, len) 67 # define __stat64(fname, buf) stat (fname, buf) 68 # define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag) 69 # define struct_stat64 struct stat 70 # ifndef __MVS__ 71 # define __alloca alloca 72 # endif 73 # define __readdir readdir 74 # define COMPILE_GLOB64 107 75 #endif /* _LIBC */ 108 76 109 77 #include <fnmatch.h> 110 78 79 #include <flexmember.h> 80 #include <glob_internal.h> 81 111 82 #ifdef _SC_GETPW_R_SIZE_MAX 112 83 # define GETPW_R_SIZE_MAX() sysconf (_SC_GETPW_R_SIZE_MAX) 113 84 #else … … 121 92 122 93 123 94 static const char *next_brace_sub (const char *begin, int flags) __THROWNL; 124 95 96 typedef uint_fast8_t dirent_type; 97 98 #if !defined _LIBC && !defined HAVE_STRUCT_DIRENT_D_TYPE 99 /* Any distinct values will do here. 100 Undef any existing macros out of the way. */ 101 # undef DT_UNKNOWN 102 # undef DT_DIR 103 # undef DT_LNK 104 # define DT_UNKNOWN 0 105 # define DT_DIR 1 106 # define DT_LNK 2 107 #endif 108 125 109 /* A representation of a directory entry which does not depend on the 126 110 layout of struct dirent, or the size of ino_t. */ 127 111 struct readdir_result 128 112 { 129 113 const char *name; 130 # if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE 131 uint8_t type; 132 # endif 114 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE 115 dirent_type type; 116 #endif 117 #if defined _LIBC || defined D_INO_IN_DIRENT 133 118 bool skip_entry; 119 #endif 134 120 }; 135 121 136 # if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE 137 /* Initializer based on the d_type member of struct dirent. */ 138 # define D_TYPE_TO_RESULT(source) (source)->d_type, 139 140 /* True if the directory entry D might be a symbolic link. */ 141 static bool 142 readdir_result_might_be_symlink (struct readdir_result d) 143 { 144 return d.type == DT_UNKNOWN || d.type == DT_LNK; 145 } 146 147 /* True if the directory entry D might be a directory. */ 148 static bool 149 readdir_result_might_be_dir (struct readdir_result d) 150 { 151 return d.type == DT_DIR || readdir_result_might_be_symlink (d); 152 } 153 # else /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */ 154 # define D_TYPE_TO_RESULT(source) 155 156 /* If we do not have type information, symbolic links and directories 157 are always a possibility. */ 158 159 static bool 160 readdir_result_might_be_symlink (struct readdir_result d) 122 /* Initialize and return type member of struct readdir_result. */ 123 static dirent_type 124 readdir_result_type (struct readdir_result d) 161 125 { 162 return true; 126 #if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE 127 # define D_TYPE_TO_RESULT(source) (source)->d_type, 128 return d.type; 129 #else 130 # define D_TYPE_TO_RESULT(source) 131 return DT_UNKNOWN; 132 #endif 163 133 } 164 134 135 /* Initialize and return skip_entry member of struct readdir_result. */ 165 136 static bool 166 readdir_result_ might_be_dir(struct readdir_result d)137 readdir_result_skip_entry (struct readdir_result d) 167 138 { 168 return true;169 }170 171 # endif /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */172 173 # if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__174 139 /* Initializer for skip_entry. POSIX does not require that the d_ino 175 140 field be present, and some systems do not provide it. */ 176 # define D_INO_TO_RESULT(source) false, 177 # else 178 # define D_INO_TO_RESULT(source) (source)->d_ino == 0, 179 # endif 141 #if defined _LIBC || defined D_INO_IN_DIRENT 142 # define D_INO_TO_RESULT(source) (source)->d_ino == 0, 143 return d.skip_entry; 144 #else 145 # define D_INO_TO_RESULT(source) 146 return false; 147 #endif 148 } 180 149 181 150 /* Construct an initializer for a struct readdir_result object from a -
posix/glob64.c
struct dirent *. No copy of the name is made. */ @@ -186,8 +155,6 @@ D_INO_TO_RESULT (source) \ } -#endif /* !defined _LIBC || !defined GLOB_ONLY_P */ - /* Call gl_readdir on STREAM. This macro can be overridden to reduce type safety if an old interface version needs to be supported. */ #ifndef GL_READDIR @@ -225,18 +192,55 @@ } #endif +#ifndef _LIBC +/* The results of opendir() in this file are not used with dirfd and fchdir, + and we do not leak fds to any single-threaded code that could use stdio, + therefore save some unnecessary recursion in fchdir.c and opendir_safer.c. + FIXME - if the kernel ever adds support for multi-thread safety for + avoiding standard fds, then we should use opendir_safer. */ +# ifdef GNULIB_defined_opendir +# undef opendir +# endif +# ifdef GNULIB_defined_closedir +# undef closedir +# endif -#ifndef attribute_hidden -# define attribute_hidden +/* Just use malloc. */ +# define __libc_use_alloca(n) false +# define alloca_account(len, avar) ((void) (len), (void) (avar), (void *) 0) +# define extend_alloca_account(buf, len, newlen, avar) \ + ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0) #endif +/* Set *R = A + B. Return true if the answer is mathematically + incorrect due to overflow; in this case, *R is the low order + bits of the correct answer. */ + +static bool +size_add_wrapv (size_t a, size_t b, size_t *r) +{ +#if 5 <= __GNUC__ && !defined __ICC + return __builtin_add_overflow (a, b, r); +#else + *r = a + b; + return *r < a; +#endif +} + +static bool +glob_use_alloca (size_t alloca_used, size_t len) +{ + size_t size; + return (!size_add_wrapv (alloca_used, len, &size) + && __libc_use_alloca (size)); +} + static int glob_in_dir (const char *pattern, const char *directory, int flags, int (*errfunc) (const char *, int), glob_t *pglob, size_t alloca_used); extern int __glob_pattern_type (const char *pattern, int quote) attribute_hidden; -#if !defined _LIBC || !defined GLOB_ONLY_P static int prefix_array (const char *prefix, char **array, size_t n) __THROWNL; static int collated_compare (const void *, const void *) __THROWNL; @@ -265,16 +269,15 @@ return *cp != '\0' ? cp : NULL; } -#endif /* !defined _LIBC || !defined GLOB_ONLY_P */ /* Do glob searching for PATTERN, placing results in PGLOB. The bits defined above may be set in FLAGS. If a directory cannot be opened or read and ERRFUNC is not nil, it is called with the pathname that caused the error, and the - `errno' value from the failing call; if it returns non-zero - `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored. + 'errno' value from the failing call; if it returns non-zero + 'glob' returns GLOB_ABORTED; if it returns zero, the error is ignored. If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. - Otherwise, `glob' returns zero. */ + Otherwise, 'glob' returns zero. */ int #ifdef GLOB_ATTRIBUTE GLOB_ATTRIBUTE @@ -292,9 +295,7 @@ int malloc_dirname = 0; glob_t dirs; int retval = 0; -#ifdef _LIBC size_t alloca_used = 0; -#endif if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0) { @@ -308,7 +309,7 @@ flags |= GLOB_ONLYDIR; if (!(flags & GLOB_DOOFFS)) - /* Have to do this so `globfree' knows where to start freeing. It + /* Have to do this so 'globfree' knows where to start freeing. It also makes all the code that uses gl_offs simpler. */ pglob->gl_offs = 0; @@ -372,14 +373,12 @@ size_t rest_len; char *onealt; size_t pattern_len = strlen (pattern) - 1; -#ifdef _LIBC - int alloca_onealt = __libc_use_alloca (alloca_used + pattern_len); + int alloca_onealt = glob_use_alloca (alloca_used, pattern_len); if (alloca_onealt) onealt = alloca_account (pattern_len, alloca_used); else -#endif { - onealt = (char *) malloc (pattern_len); + onealt = malloc (pattern_len); if (onealt == NULL) return GLOB_NOSPACE; } @@ -392,11 +391,9 @@ next = next_brace_sub (begin + 1, flags); if (next == NULL) { - /* It is an illegal expression. */ + /* It is an invalid expression. */ illegal_brace: -#ifdef _LIBC if (__glibc_unlikely (!alloca_onealt)) -#endif free (onealt); flags &= ~GLOB_BRACE; goto no_brace; @@ -437,9 +434,7 @@ /* If we got an error, return it. */ if (result && result != GLOB_NOMATCH) { -#ifdef _LIBC if (__glibc_unlikely (!alloca_onealt)) -#endif free (onealt); if (!(flags & GLOB_APPEND)) { @@ -458,9 +453,7 @@ assert (next != NULL); } -#ifdef _LIBC if (__glibc_unlikely (!alloca_onealt)) -#endif free (onealt); if (pglob->gl_pathc != firstc) @@ -476,14 +469,16 @@ /* Find the filename. */ filename = strrchr (pattern, '/'); + #if defined __MSDOS__ || defined WINDOWS32 - /* The case of "d:pattern". Since `:' is not allowed in + /* The case of "d:pattern". Since ':' is not allowed in file names, we can safely assume that wherever it happens in pattern, it signals the filename part. This is so we could some day support patterns like "[a-z]:foo". */ if (filename == NULL) filename = strchr (pattern, ':'); #endif /* __MSDOS__ || WINDOWS32 */ + dirname_modified = 0; if (filename == NULL) { @@ -508,11 +503,7 @@ } filename = pattern; -#ifdef _AMIGA - dirname = (char *) ""; -#else dirname = (char *) "."; -#endif dirlen = 0; } } @@ -536,22 +527,21 @@ char *drive_spec; ++dirlen; - drive_spec = (char *) __alloca (dirlen + 1); + drive_spec = __alloca (dirlen + 1); *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0'; /* For now, disallow wildcards in the drive spec, to prevent infinite recursion in glob. */ if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE))) return GLOB_NOMATCH; - /* If this is "d:pattern", we need to copy `:' to DIRNAME + /* If this is "d:pattern", we need to copy ':' to DIRNAME as well. If it's "d:/pattern", don't remove the slash from "d:/", since "d:" and "d:/" are not the same.*/ } #endif -#ifdef _LIBC - if (__libc_use_alloca (alloca_used + dirlen + 1)) + + if (glob_use_alloca (alloca_used, dirlen + 1)) newp = alloca_account (dirlen + 1, alloca_used); else -#endif { newp = malloc (dirlen + 1); if (newp == NULL) @@ -562,14 +552,17 @@ dirname = newp; ++filename; - if (filename[0] == '\0' #if defined __MSDOS__ || defined WINDOWS32 - && dirname[dirlen - 1] != ':' - && (dirlen < 3 || dirname[dirlen - 2] != ':' - || dirname[dirlen - 1] != '/') + bool drive_root = (dirlen > 1 + && (dirname[dirlen - 1] == ':' + || (dirlen > 2 && dirname[dirlen - 2] == ':' + && dirname[dirlen - 1] == '/'))); +#else + bool drive_root = false; #endif - && dirlen > 1) - /* "pattern/". Expand "pattern", appending slashes. */ + + if (filename[0] == '\0' && dirlen > 1 && !drive_root) + /* "pattern/". Expand "pattern", appending slashes. */ { int orig_flags = flags; if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\') @@ -602,7 +595,6 @@ } } -#ifndef VMS if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~') { if (dirname[1] == '\0' || dirname[1] == '/' @@ -612,100 +604,127 @@ /* Look up home directory. */ char *home_dir = getenv ("HOME"); int malloc_home_dir = 0; -# ifdef _AMIGA - if (home_dir == NULL || home_dir[0] == '\0') - home_dir = "SYS:"; -# else -# ifdef WINDOWS32 - if (home_dir == NULL || home_dir[0] == '\0') - home_dir = "c:/users/default"; /* poor default */ -# else if (home_dir == NULL || home_dir[0] == '\0') { +#ifdef WINDOWS32 + /* Windows NT defines HOMEDRIVE and HOMEPATH. But give + preference to HOME, because the user can change HOME. */ + const char *home_drive = getenv ("HOMEDRIVE"); + const char *home_path = getenv ("HOMEPATH"); + + if (home_drive != NULL && home_path != NULL) + { + size_t home_drive_len = strlen (home_drive); + size_t home_path_len = strlen (home_path); + char *mem = alloca (home_drive_len + home_path_len + 1); + + memcpy (mem, home_drive, home_drive_len); + memcpy (mem + home_drive_len, home_path, home_path_len + 1); + home_dir = mem; + } + else + home_dir = "c:/users/default"; /* poor default */ +#else int success; char *name; + int malloc_name = 0; size_t buflen = GET_LOGIN_NAME_MAX () + 1; if (buflen == 0) - /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try + /* 'sysconf' does not support _SC_LOGIN_NAME_MAX. Try a moderate value. */ buflen = 20; - name = alloca_account (buflen, alloca_used); + if (glob_use_alloca (alloca_used, buflen)) + name = alloca_account (buflen, alloca_used); + else + { + name = malloc (buflen); + if (name == NULL) + { + retval = GLOB_NOSPACE; + goto out; + } + malloc_name = 1; + } success = __getlogin_r (name, buflen) == 0; if (success) { struct passwd *p; -# if defined HAVE_GETPWNAM_R || defined _LIBC - long int pwbuflen = GETPW_R_SIZE_MAX (); + char *malloc_pwtmpbuf = NULL; char *pwtmpbuf; +# if defined HAVE_GETPWNAM_R || defined _LIBC + long int pwbuflenmax = GETPW_R_SIZE_MAX (); + size_t pwbuflen = pwbuflenmax; struct passwd pwbuf; - int malloc_pwtmpbuf = 0; int save = errno; -# ifndef _LIBC - if (pwbuflen == -1) - /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. +# ifndef _LIBC + if (! (0 < pwbuflenmax && pwbuflenmax <= SIZE_MAX)) + /* 'sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a moderate value. */ pwbuflen = 1024; -# endif - if (__libc_use_alloca (alloca_used + pwbuflen)) +# endif + if (glob_use_alloca (alloca_used, pwbuflen)) pwtmpbuf = alloca_account (pwbuflen, alloca_used); else { pwtmpbuf = malloc (pwbuflen); if (pwtmpbuf == NULL) { + if (__glibc_unlikely (malloc_name)) + free (name); retval = GLOB_NOSPACE; goto out; } - malloc_pwtmpbuf = 1; + malloc_pwtmpbuf = pwtmpbuf; } while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p) != 0) { + size_t newlen; + bool v; if (errno != ERANGE) { p = NULL; break; } - - if (!malloc_pwtmpbuf - && __libc_use_alloca (alloca_used - + 2 * pwbuflen)) + v = size_add_wrapv (pwbuflen, pwbuflen, &newlen); + if (!v && malloc_pwtmpbuf == NULL + && glob_use_alloca (alloca_used, newlen)) pwtmpbuf = extend_alloca_account (pwtmpbuf, pwbuflen, - 2 * pwbuflen, - alloca_used); + newlen, alloca_used); else { - char *newp = realloc (malloc_pwtmpbuf - ? pwtmpbuf : NULL, - 2 * pwbuflen); + char *newp = (v ? NULL + : realloc (malloc_pwtmpbuf, newlen)); if (newp == NULL) { - if (__glibc_unlikely (malloc_pwtmpbuf)) - free (pwtmpbuf); + free (malloc_pwtmpbuf); + if (__glibc_unlikely (malloc_name)) + free (name); retval = GLOB_NOSPACE; goto out; } - pwtmpbuf = newp; - pwbuflen = 2 * pwbuflen; - malloc_pwtmpbuf = 1; + malloc_pwtmpbuf = pwtmpbuf = newp; } + pwbuflen = newlen; __set_errno (save); } -# else +# else p = getpwnam (name); -# endif +# endif + if (__glibc_unlikely (malloc_name)) + free (name); if (p != NULL) { - if (!malloc_pwtmpbuf) + if (malloc_pwtmpbuf == NULL) home_dir = p->pw_dir; else { size_t home_dir_len = strlen (p->pw_dir) + 1; - if (__libc_use_alloca (alloca_used + home_dir_len)) + if (glob_use_alloca (alloca_used, home_dir_len)) home_dir = alloca_account (home_dir_len, alloca_used); else @@ -720,26 +739,32 @@ malloc_home_dir = 1; } memcpy (home_dir, p->pw_dir, home_dir_len); - - free (pwtmpbuf); } } + free (malloc_pwtmpbuf); } + else + { + if (__glibc_unlikely (malloc_name)) + free (name); + } +#endif /* WINDOWS32 */ } if (home_dir == NULL || home_dir[0] == '\0') { + if (__glibc_unlikely (malloc_home_dir)) + free (home_dir); if (flags & GLOB_TILDE_CHECK) { - if (__glibc_unlikely (malloc_home_dir)) - free (home_dir); retval = GLOB_NOMATCH; goto out; } else - home_dir = (char *) "~"; /* No luck. */ + { + home_dir = (char *) "~"; /* No luck. */ + malloc_home_dir = 0; + } } -# endif /* WINDOWS32 */ -# endif /* Now construct the full directory. */ if (dirname[1] == '\0') { @@ -754,8 +779,7 @@ { char *newp; size_t home_len = strlen (home_dir); - int use_alloca = __libc_use_alloca (alloca_used - + home_len + dirlen); + int use_alloca = glob_use_alloca (alloca_used, home_len + dirlen); if (use_alloca) newp = alloca_account (home_len + dirlen, alloca_used); else @@ -779,12 +803,15 @@ dirname = newp; dirlen += home_len - 1; malloc_dirname = !use_alloca; + + if (__glibc_unlikely (malloc_home_dir)) + free (home_dir); } dirname_modified = 1; } -# if !defined _AMIGA && !defined WINDOWS32 else { +#ifndef WINDOWS32 char *end_name = strchr (dirname, '/'); char *user_name; int malloc_user_name = 0; @@ -806,7 +833,7 @@ else { char *newp; - if (__libc_use_alloca (alloca_used + (end_name - dirname))) + if (glob_use_alloca (alloca_used, end_name - dirname)) newp = alloca_account (end_name - dirname, alloca_used); else { @@ -823,11 +850,11 @@ char *p = mempcpy (newp, dirname + 1, unescape - dirname - 1); char *q = unescape; - while (*q != '\0') + while (q != end_name) { if (*q == '\\') { - if (q[1] == '\0') + if (q + 1 == end_name) { /* "~fo\\o\\" unescape to user_name "foo\\", but "~fo\\o\\/" unescape to user_name @@ -843,7 +870,7 @@ *p = '\0'; } else - *((char *) mempcpy (newp, dirname + 1, end_name - dirname)) + *((char *) mempcpy (newp, dirname + 1, end_name - dirname - 1)) = '\0'; user_name = newp; } @@ -851,20 +878,21 @@ /* Look up specific user's home directory. */ { struct passwd *p; + char *malloc_pwtmpbuf = NULL; # if defined HAVE_GETPWNAM_R || defined _LIBC - long int buflen = GETPW_R_SIZE_MAX (); + long int buflenmax = GETPW_R_SIZE_MAX (); + size_t buflen = buflenmax; char *pwtmpbuf; - int malloc_pwtmpbuf = 0; struct passwd pwbuf; int save = errno; # ifndef _LIBC - if (buflen == -1) - /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a + if (! (0 <= buflenmax && buflenmax <= SIZE_MAX)) + /* Perhaps 'sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a moderate value. */ buflen = 1024; # endif - if (__libc_use_alloca (alloca_used + buflen)) + if (glob_use_alloca (alloca_used, buflen)) pwtmpbuf = alloca_account (buflen, alloca_used); else { @@ -877,32 +905,32 @@ retval = GLOB_NOSPACE; goto out; } - malloc_pwtmpbuf = 1; + malloc_pwtmpbuf = pwtmpbuf; } while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0) { + size_t newlen; + bool v; if (errno != ERANGE) { p = NULL; break; } - if (!malloc_pwtmpbuf - && __libc_use_alloca (alloca_used + 2 * buflen)) + v = size_add_wrapv (buflen, buflen, &newlen); + if (!v && malloc_pwtmpbuf == NULL + && glob_use_alloca (alloca_used, newlen)) pwtmpbuf = extend_alloca_account (pwtmpbuf, buflen, - 2 * buflen, alloca_used); + newlen, alloca_used); else { - char *newp = realloc (malloc_pwtmpbuf ? pwtmpbuf : NULL, - 2 * buflen); + char *newp = v ? NULL : realloc (malloc_pwtmpbuf, newlen); if (newp == NULL) { - if (__glibc_unlikely (malloc_pwtmpbuf)) - free (pwtmpbuf); + free (malloc_pwtmpbuf); goto nomem_getpw; } - pwtmpbuf = newp; - malloc_pwtmpbuf = 1; + malloc_pwtmpbuf = pwtmpbuf = newp; } __set_errno (save); } @@ -923,7 +951,7 @@ free (dirname); malloc_dirname = 0; - if (__libc_use_alloca (alloca_used + home_len + rest_len + 1)) + if (glob_use_alloca (alloca_used, home_len + rest_len + 1)) dirname = alloca_account (home_len + rest_len + 1, alloca_used); else @@ -931,8 +959,7 @@ dirname = malloc (home_len + rest_len + 1); if (dirname == NULL) { - if (__glibc_unlikely (malloc_pwtmpbuf)) - free (pwtmpbuf); + free (malloc_pwtmpbuf); retval = GLOB_NOSPACE; goto out; } @@ -944,24 +971,24 @@ dirlen = home_len + rest_len; dirname_modified = 1; - if (__glibc_unlikely (malloc_pwtmpbuf)) - free (pwtmpbuf); + free (malloc_pwtmpbuf); } else { - if (__glibc_unlikely (malloc_pwtmpbuf)) - free (pwtmpbuf); + free (malloc_pwtmpbuf); if (flags & GLOB_TILDE_CHECK) - /* We have to regard it as an error if we cannot find the - home directory. */ - return GLOB_NOMATCH; + { + /* We have to regard it as an error if we cannot find the + home directory. */ + retval = GLOB_NOMATCH; + goto out; + } } } +#endif /* !WINDOWS32 */ } -# endif /* Not Amiga && not WINDOWS32. */ } -#endif /* Not VMS. */ /* Now test whether we looked for "~" or "~NAME". In this case we can give the answer now. */ @@ -980,19 +1007,18 @@ size_t newcount = pglob->gl_pathc + pglob->gl_offs; char **new_gl_pathv; - if (newcount > UINTPTR_MAX - (1 + 1) - || newcount + 1 + 1 > ~((size_t) 0) / sizeof (char *)) + if (newcount > SIZE_MAX / sizeof (char *) - 2) { nospace: free (pglob->gl_pathv); pglob->gl_pathv = NULL; pglob->gl_pathc = 0; - return GLOB_NOSPACE; + retval = GLOB_NOSPACE; + goto out; } - new_gl_pathv - = (char **) realloc (pglob->gl_pathv, - (newcount + 1 + 1) * sizeof (char *)); + new_gl_pathv = realloc (pglob->gl_pathv, + (newcount + 2) * sizeof (char *)); if (new_gl_pathv == NULL) goto nospace; pglob->gl_pathv = new_gl_pathv; @@ -1006,12 +1032,19 @@ p = mempcpy (pglob->gl_pathv[newcount], dirname, dirlen); p[0] = '/'; p[1] = '\0'; + if (__glibc_unlikely (malloc_dirname)) + free (dirname); } else { - pglob->gl_pathv[newcount] = strdup (dirname); - if (pglob->gl_pathv[newcount] == NULL) - goto nospace; + if (__glibc_unlikely (malloc_dirname)) + pglob->gl_pathv[newcount] = dirname; + else + { + pglob->gl_pathv[newcount] = strdup (dirname); + if (pglob->gl_pathv[newcount] == NULL) + goto nospace; + } } pglob->gl_pathv[++newcount] = NULL; ++pglob->gl_pathc; @@ -1021,7 +1054,8 @@ } /* Not found. */ - return GLOB_NOMATCH; + retval = GLOB_NOMATCH; + goto out; } meta = __glob_pattern_type (dirname, !(flags & GLOB_NOESCAPE)); @@ -1067,7 +1101,10 @@ if (status != 0) { if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH) - return status; + { + retval = status; + goto out; + } goto no_matches; } @@ -1078,19 +1115,6 @@ { size_t old_pathc; -#ifdef SHELL - { - /* Make globbing interruptible in the bash shell. */ - extern int interrupt_state; - - if (interrupt_state) - { - globfree (&dirs); - return GLOB_ABORTED; - } - } -#endif /* SHELL. */ - old_pathc = pglob->gl_pathc; status = glob_in_dir (filename, dirs.gl_pathv[i], ((flags | GLOB_APPEND) @@ -1105,7 +1129,8 @@ globfree (&dirs); globfree (pglob); pglob->gl_pathc = 0; - return status; + retval = status; + goto out; } /* Stick the directory on the front of each name. */ @@ -1116,13 +1141,14 @@ globfree (&dirs); globfree (pglob); pglob->gl_pathc = 0; - return GLOB_NOSPACE; + retval = GLOB_NOSPACE; + goto out; } } flags |= GLOB_MAGCHAR; - /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls. + /* We have ignored the GLOB_NOCHECK flag in the 'glob_in_dir' calls. But if we have not found any matching entry and the GLOB_NOCHECK flag was set we must return the input pattern itself. */ if (pglob->gl_pathc + pglob->gl_offs == oldcount) @@ -1134,28 +1160,28 @@ size_t newcount = pglob->gl_pathc + pglob->gl_offs; char **new_gl_pathv; - if (newcount > UINTPTR_MAX - 2 - || newcount + 2 > ~((size_t) 0) / sizeof (char *)) + if (newcount > SIZE_MAX / sizeof (char *) - 2) { nospace2: globfree (&dirs); - return GLOB_NOSPACE; + retval = GLOB_NOSPACE; + goto out; } - new_gl_pathv = (char **) realloc (pglob->gl_pathv, - (newcount + 2) - * sizeof (char *)); + new_gl_pathv = realloc (pglob->gl_pathv, + (newcount + 2) * sizeof (char *)); if (new_gl_pathv == NULL) goto nospace2; pglob->gl_pathv = new_gl_pathv; - pglob->gl_pathv[newcount] = __strdup (pattern); + pglob->gl_pathv[newcount] = strdup (pattern); if (pglob->gl_pathv[newcount] == NULL) { globfree (&dirs); globfree (pglob); pglob->gl_pathc = 0; - return GLOB_NOSPACE; + retval = GLOB_NOSPACE; + goto out; } ++pglob->gl_pathc; @@ -1167,7 +1193,8 @@ else { globfree (&dirs); - return GLOB_NOMATCH; + retval = GLOB_NOMATCH; + goto out; } } @@ -1213,7 +1240,8 @@ flags = orig_flags; goto no_matches; } - return status; + retval = status; + goto out; } if (dirlen > 0) @@ -1225,7 +1253,8 @@ { globfree (pglob); pglob->gl_pathc = 0; - return GLOB_NOSPACE; + retval = GLOB_NOSPACE; + goto out; } } } @@ -1250,7 +1279,8 @@ { globfree (pglob); pglob->gl_pathc = 0; - return GLOB_NOSPACE; + retval = GLOB_NOSPACE; + goto out; } strcpy (&new[len - 2], "/"); pglob->gl_pathv[i] = new; @@ -1276,32 +1306,12 @@ #endif -#if !defined _LIBC || !defined GLOB_ONLY_P - -/* Free storage allocated in PGLOB by a previous `glob' call. */ -void -globfree (glob_t *pglob) -{ - if (pglob->gl_pathv != NULL) - { - size_t i; - for (i = 0; i < pglob->gl_pathc; ++i) - free (pglob->gl_pathv[pglob->gl_offs + i]); - free (pglob->gl_pathv); - pglob->gl_pathv = NULL; - } -} -#if defined _LIBC && !defined globfree -libc_hidden_def (globfree) -#endif - - /* Do a collated comparison of A and B. */ static int collated_compare (const void *a, const void *b) { - const char *const s1 = *(const char *const * const) a; - const char *const s2 = *(const char *const * const) b; + char *const *ps1 = a; char *s1 = *ps1; + char *const *ps2 = b; char *s2 = *ps2; if (s1 == s2) return 0; @@ -1322,28 +1332,24 @@ { size_t i; size_t dirlen = strlen (dirname); -#if defined __MSDOS__ || defined WINDOWS32 - int sep_char = '/'; -# define DIRSEP_CHAR sep_char -#else -# define DIRSEP_CHAR '/' -#endif + char dirsep_char = '/'; if (dirlen == 1 && dirname[0] == '/') /* DIRNAME is just "/", so normal prepending would get us "//foo". We want "/foo" instead, so don't prepend any chars from DIRNAME. */ dirlen = 0; + #if defined __MSDOS__ || defined WINDOWS32 - else if (dirlen > 1) + if (dirlen > 1) { if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':') /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */ --dirlen; else if (dirname[dirlen - 1] == ':') { - /* DIRNAME is "d:". Use `:' instead of `/'. */ + /* DIRNAME is "d:". Use ':' instead of '/'. */ --dirlen; - sep_char = ':'; + dirsep_char = ':'; } } #endif @@ -1351,7 +1357,7 @@ for (i = 0; i < n; ++i) { size_t eltlen = strlen (array[i]) + 1; - char *new = (char *) malloc (dirlen + 1 + eltlen); + char *new = malloc (dirlen + 1 + eltlen); if (new == NULL) { while (i > 0) @@ -1361,7 +1367,7 @@ { char *endp = mempcpy (new, dirname, dirlen); - *endp++ = DIRSEP_CHAR; + *endp++ = dirsep_char; mempcpy (endp, array[i], eltlen); } free (array[i]); @@ -1371,103 +1377,57 @@ return 0; } - -/* We must not compile this function twice. */ -#if !defined _LIBC || !defined NO_GLOB_PATTERN_P -int -__glob_pattern_type (const char *pattern, int quote) -{ - const char *p; - int ret = 0; - - for (p = pattern; *p != '\0'; ++p) - switch (*p) - { - case '?': - case '*': - return 1; - - case '\\': - if (quote) - { - if (p[1] != '\0') - ++p; - ret |= 2; - } - break; - - case '[': - ret |= 4; - break; - - case ']': - if (ret & 4) - return 1; - break; - } - - return ret; -} - -/* Return nonzero if PATTERN contains any metacharacters. - Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ -int -__glob_pattern_p (const char *pattern, int quote) -{ - return __glob_pattern_type (pattern, quote) == 1; -} -# ifdef _LIBC -weak_alias (__glob_pattern_p, glob_pattern_p) -# endif -#endif - -#endif /* !GLOB_ONLY_P */ - - /* We put this in a separate function mainly to allow the memory allocated with alloca to be recycled. */ -#if !defined _LIBC || !defined GLOB_ONLY_P static int __attribute_noinline__ -link_exists2_p (const char *dir, size_t dirlen, const char *fname, - glob_t *pglob -# ifndef _LIBC - , int flags +link_stat (const char *dir, size_t dirlen, const char *fname, + glob_t *pglob +# if !defined _LIBC && !HAVE_FSTATAT + , int flags # endif - ) + ) { size_t fnamelen = strlen (fname); - char *fullname = (char *) __alloca (dirlen + 1 + fnamelen + 1); + char *fullname = __alloca (dirlen + 1 + fnamelen + 1); struct stat st; -# ifndef _LIBC - struct_stat64 st64; -# endif mempcpy (mempcpy (mempcpy (fullname, dir, dirlen), "/", 1), fname, fnamelen + 1); -# ifdef _LIBC - return (*pglob->gl_stat) (fullname, &st) == 0; -# else - return ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) - ? (*pglob->gl_stat) (fullname, &st) - : __stat64 (fullname, &st64)) == 0); +# if !defined _LIBC && !HAVE_FSTATAT + if (__builtin_expect ((flags & GLOB_ALTDIRFUNC) == 0, 1)) + { + struct_stat64 st64; + return __stat64 (fullname, &st64); + } # endif + return (*pglob->gl_stat) (fullname, &st); } -# ifdef _LIBC -# define link_exists_p(dfd, dirname, dirnamelen, fname, pglob, flags) \ - (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) \ - ? link_exists2_p (dirname, dirnamelen, fname, pglob) \ - : ({ struct stat64 st64; \ - __fxstatat64 (_STAT_VER, dfd, fname, &st64, 0) == 0; })) + +/* Return true if DIR/FNAME exists. */ +static int +link_exists_p (int dfd, const char *dir, size_t dirlen, const char *fname, + glob_t *pglob, int flags) +{ + int status; +# if defined _LIBC || HAVE_FSTATAT + if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)) + status = link_stat (dir, dirlen, fname, pglob); + else + { + /* dfd cannot be -1 here, because dirfd never returns -1 on + glibc, or on hosts that have fstatat. */ + struct_stat64 st64; + status = __fxstatat64 (_STAT_VER, dfd, fname, &st64, 0); + } # else -# define link_exists_p(dfd, dirname, dirnamelen, fname, pglob, flags) \ - link_exists2_p (dirname, dirnamelen, fname, pglob, flags) + status = link_stat (dir, dirlen, fname, pglob, flags); # endif -#endif - + return status == 0 || errno == EOVERFLOW; +} -/* Like `glob', but PATTERN is a final pathname component, +/* Like 'glob', but PATTERN is a final pathname component, and matches are searched for in DIRECTORY. The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done. The GLOB_APPEND flag is assumed to be set (always appends). */ @@ -1478,25 +1438,25 @@ { size_t dirlen = strlen (directory); void *stream = NULL; - struct globnames - { - struct globnames *next; - size_t count; - char *name[64]; - }; -#define INITIAL_COUNT sizeof (init_names.name) / sizeof (init_names.name[0]) - struct globnames init_names; - struct globnames *names = &init_names; - struct globnames *names_alloca = &init_names; +# define GLOBNAMES_MEMBERS(nnames) \ + struct globnames *next; size_t count; char *name[nnames]; + struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) }; + struct { GLOBNAMES_MEMBERS (64) } init_names_buf; + struct globnames *init_names = (struct globnames *) &init_names_buf; + struct globnames *names = init_names; + struct globnames *names_alloca = init_names; size_t nfound = 0; size_t cur = 0; int meta; int save; + int result; - alloca_used += sizeof (init_names); + alloca_used += sizeof init_names_buf; - init_names.next = NULL; - init_names.count = INITIAL_COUNT; + init_names->next = NULL; + init_names->count = ((sizeof init_names_buf + - offsetof (struct globnames, name)) + / sizeof init_names->name[0]); meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE)); if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) @@ -1516,14 +1476,16 @@ struct_stat64 st64; } ust; size_t patlen = strlen (pattern); - int alloca_fullname = __libc_use_alloca (alloca_used - + dirlen + 1 + patlen + 1); + size_t fullsize; + bool alloca_fullname + = (! size_add_wrapv (dirlen + 1, patlen + 1, &fullsize) + && glob_use_alloca (alloca_used, fullsize)); char *fullname; if (alloca_fullname) - fullname = alloca_account (dirlen + 1 + patlen + 1, alloca_used); + fullname = alloca_account (fullsize, alloca_used); else { - fullname = malloc (dirlen + 1 + patlen + 1); + fullname = malloc (fullsize); if (fullname == NULL) return GLOB_NOSPACE; } @@ -1531,9 +1493,11 @@ mempcpy (mempcpy (mempcpy (fullname, directory, dirlen), "/", 1), pattern, patlen + 1); - if ((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) + if (((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) ? (*pglob->gl_stat) (fullname, &ust.st) - : __stat64 (fullname, &ust.st64)) == 0) + : __stat64 (fullname, &ust.st64)) + == 0) + || errno == EOVERFLOW) /* We found this file to be existing. Now tell the rest of the function to copy this name into the result. */ flags |= GLOB_NOCHECK; @@ -1555,16 +1519,10 @@ } else { -#ifdef _LIBC int dfd = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) ? -1 : dirfd ((DIR *) stream)); -#endif int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) - | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0) -#if defined _AMIGA || defined VMS - | FNM_CASEFOLD -#endif - ); + | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)); flags |= GLOB_MAGCHAR; while (1) @@ -1584,19 +1542,24 @@ } if (d.name == NULL) break; - if (d.skip_entry) + if (readdir_result_skip_entry (d)) continue; /* If we shall match only directories use the information provided by the dirent call if possible. */ - if ((flags & GLOB_ONLYDIR) && !readdir_result_might_be_dir (d)) - continue; + if (flags & GLOB_ONLYDIR) + switch (readdir_result_type (d)) + { + case DT_DIR: case DT_LNK: case DT_UNKNOWN: break; + default: continue; + } if (fnmatch (pattern, d.name, fnm_flags) == 0) { /* If the file we found is a symlink we have to make sure the target file exists. */ - if (!readdir_result_might_be_symlink (d) + dirent_type type = readdir_result_type (d); + if (! (type == DT_LNK || type == DT_UNKNOWN) || link_exists_p (dfd, directory, dirlen, d.name, pglob, flags)) { @@ -1604,10 +1567,13 @@ { struct globnames *newnames; size_t count = names->count * 2; - size_t size = (sizeof (struct globnames) - + ((count - INITIAL_COUNT) - * sizeof (char *))); - if (__libc_use_alloca (alloca_used + size)) + size_t nameoff = offsetof (struct globnames, name); + size_t size = FLEXSIZEOF (struct globnames, name, + count * sizeof (char *)); + if ((SIZE_MAX - nameoff) / 2 / sizeof (char *) + < names->count) + goto memory_error; + if (glob_use_alloca (alloca_used, size)) newnames = names_alloca = alloca_account (size, alloca_used); else if ((newnames = malloc (size)) @@ -1623,6 +1589,8 @@ goto memory_error; ++cur; ++nfound; + if (SIZE_MAX - pglob->gl_offs <= nfound) + goto memory_error; } } } @@ -1633,29 +1601,27 @@ { size_t len = strlen (pattern); nfound = 1; - names->name[cur] = (char *) malloc (len + 1); + names->name[cur] = malloc (len + 1); if (names->name[cur] == NULL) goto memory_error; *((char *) mempcpy (names->name[cur++], pattern, len)) = '\0'; } - int result = GLOB_NOMATCH; + result = GLOB_NOMATCH; if (nfound != 0) { + char **new_gl_pathv; result = 0; - if (pglob->gl_pathc > UINTPTR_MAX - pglob->gl_offs - || pglob->gl_pathc + pglob->gl_offs > UINTPTR_MAX - nfound - || pglob->gl_pathc + pglob->gl_offs + nfound > UINTPTR_MAX - 1 - || (pglob->gl_pathc + pglob->gl_offs + nfound + 1 - > UINTPTR_MAX / sizeof (char *))) + if (SIZE_MAX / sizeof (char *) - pglob->gl_pathc + < pglob->gl_offs + nfound + 1) goto memory_error; - char **new_gl_pathv; new_gl_pathv - = (char **) realloc (pglob->gl_pathv, - (pglob->gl_pathc + pglob->gl_offs + nfound + 1) - * sizeof (char *)); + = realloc (pglob->gl_pathv, + (pglob->gl_pathc + pglob->gl_offs + nfound + 1) + * sizeof (char *)); + if (new_gl_pathv == NULL) { memory_error: @@ -1671,7 +1637,7 @@ and this is the block assigned to OLD here. */ if (names == NULL) { - assert (old == &init_names); + assert (old == init_names); break; } cur = names->count; @@ -1697,7 +1663,7 @@ and this is the block assigned to OLD here. */ if (names == NULL) { - assert (old == &init_names); + assert (old == init_names); break; } cur = names->count; diff -Naur glibc-2.26.orig/posix/glob64.c glibc-2.26/posix/glob64.c
old new 43 43 } 44 44 libc_hidden_def (glob64) 45 45 46 void47 globfree64 (glob64_t *pglob)48 {49 }50 libc_hidden_def (globfree64)51 52 46 stub_warning (glob64) -
posix/glob_internal.h
diff -Naur glibc-2.26.orig/posix/glob_internal.h glibc-2.26/posix/glob_internal.h
old new 1 /* Shared definition for glob and glob_pattern_p. 2 Copyright (C) 2017 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <http://www.gnu.org/licenses/>. */ 18 19 #ifndef GLOB_INTERNAL_H 20 # define GLOB_INTERNAL_H 21 22 static inline int 23 __glob_pattern_type (const char *pattern, int quote) 24 { 25 const char *p; 26 int ret = 0; 27 28 for (p = pattern; *p != '\0'; ++p) 29 switch (*p) 30 { 31 case '?': 32 case '*': 33 return 1; 34 35 case '\\': 36 if (quote) 37 { 38 if (p[1] != '\0') 39 ++p; 40 ret |= 2; 41 } 42 break; 43 44 case '[': 45 ret |= 4; 46 break; 47 48 case ']': 49 if (ret & 4) 50 return 1; 51 break; 52 } 53 54 return ret; 55 } 56 57 #endif /* GLOB_INTERNAL_H */ -
posix/glob_pattern_p.c
diff -Naur glibc-2.26.orig/posix/glob_pattern_p.c glibc-2.26/posix/glob_pattern_p.c
old new 1 /* Return nonzero if PATTERN contains any metacharacters. 2 Copyright (C) 2017 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <http://www.gnu.org/licenses/>. */ 18 19 #ifndef _LIBC 20 # include <config.h> 21 #endif 22 23 #include <glob.h> 24 #include "glob_internal.h" 25 26 /* Return nonzero if PATTERN contains any metacharacters. 27 Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ 28 int 29 __glob_pattern_p (const char *pattern, int quote) 30 { 31 return __glob_pattern_type (pattern, quote) == 1; 32 } 33 weak_alias (__glob_pattern_p, glob_pattern_p) -
posix/globfree.c
diff -Naur glibc-2.26.orig/posix/globfree.c glibc-2.26/posix/globfree.c
old new 1 /* Frees the dynamically allocated storage from an earlier call to glob. 2 Copyright (C) 2017 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <http://www.gnu.org/licenses/>. */ 18 19 #ifndef _LIBC 20 # include <config.h> 21 #endif 22 23 #include <glob.h> 24 #include <stdlib.h> 25 26 /* Free storage allocated in PGLOB by a previous `glob' call. */ 27 void 28 globfree (glob_t *pglob) 29 { 30 if (pglob->gl_pathv != NULL) 31 { 32 size_t i; 33 for (i = 0; i < pglob->gl_pathc; ++i) 34 free (pglob->gl_pathv[pglob->gl_offs + i]); 35 free (pglob->gl_pathv); 36 pglob->gl_pathv = NULL; 37 } 38 } 39 #ifndef globfree 40 libc_hidden_def (globfree) 41 #endif -
posix/globfree64.c
diff -Naur glibc-2.26.orig/posix/globfree64.c glibc-2.26/posix/globfree64.c
old new 1 /* Frees the dynamically allocated storage from an earlier call to glob. 2 Copyright (C) 2017 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <http://www.gnu.org/licenses/>. */ 18 19 #ifndef _LIBC 20 # include <config.h> 21 #endif 22 23 #include <glob.h> 24 #include <stdlib.h> 25 26 /* Free storage allocated in PGLOB by a previous `glob' call. */ 27 void 28 globfree64 (glob64_t *pglob) 29 { 30 } 31 libc_hidden_def (globfree64) -
posix/tst-glob-tilde.c
diff -Naur glibc-2.26.orig/posix/tst-glob-tilde.c glibc-2.26/posix/tst-glob-tilde.c
old new 1 /* Check for GLOB_TIDLE heap allocation issues (bugs 22320, 22325, 22332). 2 Copyright (C) 2017 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <http://www.gnu.org/licenses/>. */ 18 19 #include <glob.h> 20 #include <mcheck.h> 21 #include <nss.h> 22 #include <pwd.h> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <support/check.h> 26 #include <support/support.h> 27 28 /* Flag which indicates whether to pass the GLOB_ONLYDIR flag. */ 29 static int do_onlydir; 30 31 /* Flag which indicates whether to pass the GLOB_NOCHECK flag. */ 32 static int do_nocheck; 33 34 /* Flag which indicates whether to pass the GLOB_MARK flag. */ 35 static int do_mark; 36 37 /* Flag which indicates whether to pass the GLOB_NOESCAPE flag. */ 38 static int do_noescape; 39 40 static void 41 one_test (const char *prefix, const char *middle, const char *suffix) 42 { 43 char *pattern = xasprintf ("%s%s%s", prefix, middle, suffix); 44 int flags = GLOB_TILDE; 45 if (do_onlydir) 46 flags |= GLOB_ONLYDIR; 47 if (do_nocheck) 48 flags |= GLOB_NOCHECK; 49 if (do_mark) 50 flags |= GLOB_MARK; 51 if (do_noescape) 52 flags |= GLOB_NOESCAPE; 53 glob_t gl; 54 /* This glob call might result in crashes or memory leaks. */ 55 if (glob (pattern, flags, NULL, &gl) == 0) 56 globfree (&gl); 57 free (pattern); 58 } 59 60 enum 61 { 62 /* The largest base being tested. */ 63 largest_base_size = 500000, 64 65 /* The actual size is the base size plus a variable whose absolute 66 value is not greater than this. This helps malloc to trigger 67 overflows. */ 68 max_size_skew = 16, 69 70 /* The maximum string length supported by repeating_string 71 below. */ 72 repeat_size = largest_base_size + max_size_skew, 73 }; 74 75 /* Used to construct strings which repeat a single character 'x'. */ 76 static char *repeat; 77 78 /* Return a string of SIZE characters. */ 79 const char * 80 repeating_string (int size) 81 { 82 TEST_VERIFY (size >= 0); 83 TEST_VERIFY (size <= repeat_size); 84 const char *repeated_shifted = repeat + repeat_size - size; 85 TEST_VERIFY (strlen (repeated_shifted) == size); 86 return repeated_shifted; 87 } 88 89 static int 90 do_test (void) 91 { 92 /* Avoid network-based NSS modules and initialize nss_files with a 93 dummy lookup. This has to come before mtrace because NSS does 94 not free all memory. */ 95 __nss_configure_lookup ("passwd", "files"); 96 (void) getpwnam ("root"); 97 98 mtrace (); 99 100 repeat = xmalloc (repeat_size + 1); 101 memset (repeat, 'x', repeat_size); 102 repeat[repeat_size] = '\0'; 103 104 /* These numbers control the size of the user name. The values 105 cover the minimum (0), a typical size (8), a large 106 stack-allocated size (100000), and a somewhat large 107 heap-allocated size (largest_base_size). */ 108 static const int base_sizes[] = { 0, 8, 100, 100000, largest_base_size, -1 }; 109 110 for (do_onlydir = 0; do_onlydir < 2; ++do_onlydir) 111 for (do_nocheck = 0; do_nocheck < 2; ++do_nocheck) 112 for (do_mark = 0; do_mark < 2; ++do_mark) 113 for (do_noescape = 0; do_noescape < 2; ++do_noescape) 114 for (int base_idx = 0; base_sizes[base_idx] >= 0; ++base_idx) 115 { 116 for (int size_skew = -max_size_skew; size_skew <= max_size_skew; 117 ++size_skew) 118 { 119 int size = base_sizes[base_idx] + size_skew; 120 if (size < 0) 121 continue; 122 123 const char *user_name = repeating_string (size); 124 one_test ("~", user_name, "/a/b"); 125 one_test ("~", user_name, "x\\x\\x////x\\a"); 126 } 127 128 const char *user_name = repeating_string (base_sizes[base_idx]); 129 one_test ("~", user_name, ""); 130 one_test ("~", user_name, "/"); 131 one_test ("~", user_name, "/a"); 132 one_test ("~", user_name, "/*/*"); 133 one_test ("~", user_name, "\\/"); 134 one_test ("/~", user_name, ""); 135 one_test ("*/~", user_name, "/a/b"); 136 } 137 138 free (repeat); 139 140 return 0; 141 } 142 143 #include <support/test-driver.c> -
sysdeps/gnu/glob64.c
diff -Naur glibc-2.26.orig/sysdeps/gnu/glob64.c glibc-2.26/sysdeps/gnu/glob64.c
old new 15 15 #undef __stat 16 16 #define __stat(file, buf) __xstat64 (_STAT_VER, file, buf) 17 17 18 #define NO_GLOB_PATTERN_P 119 20 18 #define COMPILE_GLOB64 1 21 19 22 20 #include <posix/glob.c> 23 21 24 22 libc_hidden_def (glob64) 25 libc_hidden_def (globfree64) -
sysdeps/gnu/globfree64.c
diff -Naur glibc-2.26.orig/sysdeps/gnu/globfree64.c glibc-2.26/sysdeps/gnu/globfree64.c
old new 1 #include <dirent.h> 2 #include <glob.h> 3 #include <sys/stat.h> 4 5 #define glob_t glob64_t 6 #define globfree(pglob) globfree64 (pglob) 7 8 #include <posix/globfree.c> 9 10 libc_hidden_def (globfree64) -
sysdeps/posix/getaddrinfo.c
diff -Naur glibc-2.26.orig/sysdeps/posix/getaddrinfo.c glibc-2.26/sysdeps/posix/getaddrinfo.c
old new 255 255 break; \ 256 256 if (!scratch_buffer_grow (tmpbuf)) \ 257 257 { \ 258 __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \ 259 __resolv_context_put (res_ctx); \ 258 260 result = -EAI_MEMORY; \ 259 261 goto free_and_return; \ 260 262 } \ -
sysdeps/unix/sysv/linux/Makefile
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/Makefile glibc-2.26/sysdeps/unix/sysv/linux/Makefile
old new 162 162 ifeq ($(subdir),posix) 163 163 sysdep_headers += bits/initspin.h 164 164 165 sysdep_routines += sched_getcpu 165 sysdep_routines += sched_getcpu oldglob 166 166 167 167 tests += tst-affinity tst-affinity-pid 168 168 -
sysdeps/unix/sysv/linux/alpha/Makefile
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/alpha/Makefile glibc-2.26/sysdeps/unix/sysv/linux/alpha/Makefile
old new 1 ifeq ($(subdir),posix)2 sysdep_routines += oldglob3 endif4 5 1 ifeq ($(subdir),stdlib) 6 2 gen-as-const-headers += ucontext-offsets.sym 7 3 endif -
sysdeps/unix/sysv/linux/alpha/glob.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/alpha/glob.c glibc-2.26/sysdeps/unix/sysv/linux/alpha/glob.c
old new 42 42 #undef globfree64 43 43 44 44 versioned_symbol (libc, __new_glob, glob, GLIBC_2_1); 45 versioned_symbol (libc, __new_globfree, globfree, GLIBC_2_1);46 45 libc_hidden_ver (__new_glob, glob) 47 libc_hidden_ver (__new_globfree, globfree)48 46 49 47 weak_alias (__new_glob, glob64) 50 weak_alias (__new_globfree, globfree64)51 libc_hidden_ver (__new_globfree, globfree64) -
sysdeps/unix/sysv/linux/alpha/globfree.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/alpha/globfree.c glibc-2.26/sysdeps/unix/sysv/linux/alpha/globfree.c
old new 1 /* Compat globfree. Linux/alpha version. 2 Copyright (C) 2017 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library. If not, see 17 <http://www.gnu.org/licenses/>. */ 18 19 #define globfree64 __no_globfree64_decl 20 #include <sys/types.h> 21 #include <glob.h> 22 #include <shlib-compat.h> 23 24 #define globfree(pglob) \ 25 __new_globfree (pglob) 26 27 extern void __new_globfree (glob_t *__pglob); 28 29 #include <posix/globfree.c> 30 31 #undef globfree64 32 33 versioned_symbol (libc, __new_globfree, globfree, GLIBC_2_1); 34 libc_hidden_ver (__new_globfree, globfree) 35 36 weak_alias (__new_globfree, globfree64) 37 libc_hidden_ver (__new_globfree, globfree64) -
sysdeps/unix/sysv/linux/arm/glob64.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/arm/glob64.c glibc-2.26/sysdeps/unix/sysv/linux/arm/glob64.c
old new 1 #include <sysdeps/unix/sysv/linux/i386/glob64.c> -
sysdeps/unix/sysv/linux/glob.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/glob.c glibc-2.26/sysdeps/unix/sysv/linux/glob.c
old new 1 /* Find pathnames matching a pattern. Linux version. 2 Copyright (C) 2017 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <http://www.gnu.org/licenses/>. */ 18 19 #include <sys/stat.h> 20 #include <kernel_stat.h> 21 22 #define glob64 __no_glob64_decl 23 #include <posix/glob.c> 24 #undef glob64 25 26 #if XSTAT_IS_XSTAT64 27 weak_alias (glob, glob64) 28 #endif -
sysdeps/unix/sysv/linux/globfree.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/globfree.c glibc-2.26/sysdeps/unix/sysv/linux/globfree.c
old new 1 /* Frees the dynamically allocated storage from an earlier call to glob. 2 Linux version. 3 Copyright (C) 2017 Free Software Foundation, Inc. 4 This file is part of the GNU C Library. 5 6 The GNU C Library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 The GNU C Library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with the GNU C Library; if not, see 18 <http://www.gnu.org/licenses/>. */ 19 20 #include <sys/stat.h> 21 #include <kernel_stat.h> 22 23 #define globfree64 __no_globfree64_decl 24 #include <posix/globfree.c> 25 #undef globfree64 26 27 #if XSTAT_IS_XSTAT64 28 weak_alias (globfree, globfree64) 29 libc_hidden_ver (globfree, globfree64) 30 #endif -
sysdeps/unix/sysv/linux/globfree64.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/globfree64.c glibc-2.26/sysdeps/unix/sysv/linux/globfree64.c
old new 1 /* Frees the dynamically allocated storage from an earlier call to glob. 2 Linux version. 3 Copyright (C) 2017 Free Software Foundation, Inc. 4 This file is part of the GNU C Library. 5 6 The GNU C Library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 The GNU C Library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with the GNU C Library; if not, see 18 <http://www.gnu.org/licenses/>. */ 19 20 #include <sys/stat.h> 21 #include <kernel_stat.h> 22 23 #if !XSTAT_IS_XSTAT64 24 25 # include <glob.h> 26 27 # define glob_t glob64_t 28 # define globfree(pglob) globfree64 (pglob) 29 30 # undef stat 31 # define stat stat64 32 33 # include <posix/globfree.c> 34 35 libc_hidden_def (globfree64) 36 #endif -
sysdeps/unix/sysv/linux/i386/alphasort64.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/i386/alphasort64.c glibc-2.26/sysdeps/unix/sysv/linux/i386/alphasort64.c
old new 30 30 31 31 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) 32 32 33 #include < sysdeps/unix/sysv/linux/i386/olddirent.h>33 #include <olddirent.h> 34 34 35 35 int 36 36 __old_alphasort64 (const struct __old_dirent64 **a, -
sysdeps/unix/sysv/linux/i386/getdents64.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/i386/getdents64.c glibc-2.26/sysdeps/unix/sysv/linux/i386/getdents64.c
old new 28 28 29 29 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) 30 30 31 #include < sysdeps/unix/sysv/linux/i386/olddirent.h>31 #include <olddirent.h> 32 32 33 33 #define __GETDENTS __old_getdents64 34 34 #define DIRENT_TYPE struct __old_dirent64 -
sysdeps/unix/sysv/linux/i386/glob64.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/i386/glob64.c glibc-2.26/sysdeps/unix/sysv/linux/i386/glob64.c
old new 1 /* Two glob variants with 64-bit support, for dirent64 and __olddirent64.2 Copyright (C) 1998-2017 Free Software Foundation, Inc.1 /* Find pathnames matching a pattern. Linux version. 2 Copyright (C) 2017 Free Software Foundation, Inc. 3 3 This file is part of the GNU C Library. 4 4 5 5 The GNU C Library is free software; you can redistribute it and/or … … 16 16 License along with the GNU C Library; if not, see 17 17 <http://www.gnu.org/licenses/>. */ 18 18 19 #include <dirent.h>20 #include <glob.h>21 19 #include <sys/stat.h> 20 #include <kernel_stat.h> 22 21 23 #define dirent dirent64 24 #define __readdir(dirp) __readdir64 (dirp) 22 #if !XSTAT_IS_XSTAT64 23 # include <glob.h> 24 # include <dirent.h> 25 # include <sys/stat.h> 25 26 26 #define glob_t glob64_t 27 #define glob(pattern, flags, errfunc, pglob) \ 28 __glob64 (pattern, flags, errfunc, pglob) 29 #define globfree(pglob) globfree64 (pglob) 30 31 #undef stat 32 #define stat stat64 33 #undef __stat 34 #define __stat(file, buf) __xstat64 (_STAT_VER, file, buf) 27 # define dirent dirent64 28 # define __readdir(dirp) __readdir64 (dirp) 35 29 36 #define NO_GLOB_PATTERN_P 1 30 # define glob_t glob64_t 31 # define glob(pattern, flags, errfunc, pglob) \ 32 __glob64 (pattern, flags, errfunc, pglob) 33 # define globfree(pglob) globfree64 (pglob) 37 34 38 #define COMPILE_GLOB64 1 35 # undef stat 36 # define stat stat64 39 37 40 # include <posix/glob.c>38 # define COMPILE_GLOB64 1 41 39 42 # include "shlib-compat.h"40 # include <posix/glob.c> 43 41 44 libc_hidden_def (globfree64) 42 # include "shlib-compat.h" 45 43 44 # ifdef GLOB_NO_OLD_VERSION 45 strong_alias (__glob64, glob64) 46 libc_hidden_def (glob64) 47 # else 46 48 versioned_symbol (libc, __glob64, glob64, GLIBC_2_2); 47 49 libc_hidden_ver (__glob64, glob64) 48 49 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) 50 51 #include <sysdeps/unix/sysv/linux/i386/olddirent.h> 52 53 int __old_glob64 (const char *__pattern, int __flags, 54 int (*__errfunc) (const char *, int), 55 glob64_t *__pglob); 56 57 #undef dirent 58 #define dirent __old_dirent64 59 #undef GL_READDIR 60 # define GL_READDIR(pglob, stream) \ 61 ((struct __old_dirent64 *) (pglob)->gl_readdir (stream)) 62 #undef __readdir 63 #define __readdir(dirp) __old_readdir64 (dirp) 64 #undef glob 65 #define glob(pattern, flags, errfunc, pglob) \ 66 __old_glob64 (pattern, flags, errfunc, pglob) 67 #define convert_dirent __old_convert_dirent 68 #define glob_in_dir __old_glob_in_dir 69 #define GLOB_ATTRIBUTE attribute_compat_text_section 70 71 #define GLOB_ONLY_P 1 72 73 #include <posix/glob.c> 74 75 compat_symbol (libc, __old_glob64, glob64, GLIBC_2_1); 76 #endif 50 # endif 51 #endif /* XSTAT_IS_XSTAT64 */ -
sysdeps/unix/sysv/linux/i386/readdir64.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/i386/readdir64.c glibc-2.26/sysdeps/unix/sysv/linux/i386/readdir64.c
old new 31 31 32 32 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) 33 33 34 #include < sysdeps/unix/sysv/linux/i386/olddirent.h>34 #include <olddirent.h> 35 35 36 36 #define __READDIR attribute_compat_text_section __old_readdir64 37 37 #define __GETDENTS __old_getdents64 -
sysdeps/unix/sysv/linux/i386/readdir64_r.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/i386/readdir64_r.c glibc-2.26/sysdeps/unix/sysv/linux/i386/readdir64_r.c
old new 31 31 32 32 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) 33 33 34 #include < sysdeps/unix/sysv/linux/i386/olddirent.h>34 #include <olddirent.h> 35 35 36 36 #define __READDIR_R attribute_compat_text_section __old_readdir64_r 37 37 #define __GETDENTS __old_getdents64 -
sysdeps/unix/sysv/linux/i386/versionsort64.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/i386/versionsort64.c glibc-2.26/sysdeps/unix/sysv/linux/i386/versionsort64.c
old new 30 30 31 31 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) 32 32 33 #include < sysdeps/unix/sysv/linux/i386/olddirent.h>33 #include <olddirent.h> 34 34 35 35 int 36 36 __old_versionsort64 (const struct __old_dirent64 **a, -
sysdeps/unix/sysv/linux/m68k/glob64.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/m68k/glob64.c glibc-2.26/sysdeps/unix/sysv/linux/m68k/glob64.c
old new 1 #include <sysdeps/unix/sysv/linux/i386/glob64.c> -
sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c glibc-2.26/sysdeps/unix/sysv/linux/mips/mips64/n64/glob64.c
old new 1 /* glob64 is in glob.c */ -
sysdeps/unix/sysv/linux/oldglob.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/oldglob.c glibc-2.26/sysdeps/unix/sysv/linux/oldglob.c
old new 1 #include <shlib-compat.h> 2 3 #if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) \ 4 && !defined(GLOB_NO_OLD_VERSION) 5 6 #include <dirent.h> 7 #include <glob.h> 8 #include <sys/stat.h> 9 10 #include <olddirent.h> 11 12 int __old_glob64 (const char *__pattern, int __flags, 13 int (*__errfunc) (const char *, int), 14 glob64_t *__pglob); 15 libc_hidden_proto (__old_glob64); 16 17 #define dirent __old_dirent64 18 #define GL_READDIR(pglob, stream) \ 19 ((struct __old_dirent64 *) (pglob)->gl_readdir (stream)) 20 #undef __readdir 21 #define __readdir(dirp) __old_readdir64 (dirp) 22 23 #define glob_t glob64_t 24 #define glob(pattern, flags, errfunc, pglob) \ 25 __old_glob64 (pattern, flags, errfunc, pglob) 26 #define globfree(pglob) globfree64(pglob) 27 28 #define convert_dirent __old_convert_dirent 29 #define glob_in_dir __old_glob_in_dir 30 31 #undef stat 32 #define stat stat64 33 #undef __stat 34 #define __stat(file, buf) __xstat64 (_STAT_VER, file, buf) 35 36 #define GLOB_ATTRIBUTE attribute_compat_text_section 37 38 #include <posix/glob.c> 39 40 libc_hidden_def (__old_glob64); 41 42 compat_symbol (libc, __old_glob64, glob64, GLIBC_2_1); 43 #endif -
sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c glibc-2.26/sysdeps/unix/sysv/linux/powerpc/powerpc32/glob64.c
old new 1 #include <sysdeps/unix/sysv/linux/i386/glob64.c> -
sysdeps/unix/sysv/linux/s390/s390-32/glob64.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/s390/s390-32/glob64.c glibc-2.26/sysdeps/unix/sysv/linux/s390/s390-32/glob64.c
old new 1 #define GLOB_NO_OLD_VERSION 2 #include <sysdeps/unix/sysv/linux/glob64.c> -
sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c glibc-2.26/sysdeps/unix/sysv/linux/s390/s390-32/oldglob.c
old new 1 #define GLOB_NO_OLD_VERSION 2 #include <sysdeps/unix/sysv/linux/oldglob.c> -
sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c glibc-2.26/sysdeps/unix/sysv/linux/sparc/sparc32/glob64.c
old new 1 #include <sysdeps/unix/sysv/linux/i386/glob64.c> -
sysdeps/unix/sysv/linux/wordsize-64/glob64.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/wordsize-64/glob64.c glibc-2.26/sysdeps/unix/sysv/linux/wordsize-64/glob64.c
old new 1 /* This file is here so sysdeps/gnu/glob64.c doesn't take precedence. */2 #include <sysdeps/wordsize-64/glob64.c> -
sysdeps/unix/sysv/linux/x86_64/x32/glob.c
diff -Naur glibc-2.26.orig/sysdeps/unix/sysv/linux/x86_64/x32/glob.c glibc-2.26/sysdeps/unix/sysv/linux/x86_64/x32/glob.c
old new 1 #include <sysdeps/wordsize-64/glob.c> -
sysdeps/wordsize-64/glob.c
diff -Naur glibc-2.26.orig/sysdeps/wordsize-64/glob.c glibc-2.26/sysdeps/wordsize-64/glob.c
old new 1 #define glob64 __no_glob64_decl2 #define globfree64 __no_globfree64_decl3 #include <posix/glob.c>4 #undef glob645 #undef globfree646 weak_alias (glob, glob64)7 weak_alias (globfree, globfree64)8 libc_hidden_ver (globfree, globfree64) -
sysdeps/wordsize-64/glob64.c
diff -Naur glibc-2.26.orig/sysdeps/wordsize-64/glob64.c glibc-2.26/sysdeps/wordsize-64/glob64.c
old new 1 /* glob64 is in glob.c */