Ticket #1185: glibc-2.26-glob_fixes-1.patch

File glibc-2.26-glob_fixes-1.patch, 82.1 KB (added by William Harrington, 6 years ago)

Updated glob tilde fixes from https://git.launchpad.net/glibc/?h=ibm%2F2.26%2Fmaster

  • 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  
     12017-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
     72017-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
     692017-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
     752017-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
     832017-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
     1162017-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
     1222017-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
    11282017-08-02  Siddhesh Poyarekar  <siddhesh@sourceware.org>
    2129
    3130        * version.h (RELEASE): Set to "stable"
  • glibc-2.26

    diff -Naur glibc-2.26.orig/NEWS glibc-2.26/NEWS
    old new  
    55Please send GNU C library bug reports via <http://sourceware.org/bugzilla/>
    66using `glibc' in the "product" field.
    77
    88
     9Version 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
     20The 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
    925
    1026Version 2.26
  • posix/Makefile

     
     Major new features:
    diff -Naur glibc-2.26.orig/posix/Makefile glibc-2.26/posix/Makefile
    old new  
    4545        getpgid setpgid getpgrp bsd-getpgrp setpgrp getsid setsid             \
    4646        getresuid getresgid setresuid setresgid                               \
    4747        pathconf sysconf fpathconf                                            \
    48         glob glob64 fnmatch regex                                             \
     48        glob glob64 globfree globfree64 glob_pattern_p fnmatch regex          \
    4949        confstr                                                               \
    5050        getopt getopt1                                                        \
    5151        sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax  \
     
    9393                   tst-fnmatch3 bug-regex36 tst-getaddrinfo5 \
    9494                   tst-posix_spawn-fd tst-posix_spawn-setsid \
    9595                   tst-posix_fadvise tst-posix_fadvise64 \
    96                    tst-sysconf-empty-chroot
     96                   tst-sysconf-empty-chroot tst-glob-tilde
    9797tests-internal  := bug-regex5 bug-regex20 bug-regex33 \
    9898                   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3
    9999xtests          := bug-ga2
     
    141141                 $(objpfx)tst-rxspencer-no-utf8-mem.out $(objpfx)tst-pcre-mem.out \
    142142                 $(objpfx)tst-boost-mem.out $(objpfx)tst-getconf.out \
    143143                 $(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
    145146xtests-special += $(objpfx)bug-ga2-mem.out
    146147endif
    147148
     
    350351        $(common-objpfx)malloc/mtrace $(objpfx)bug-glob2.mtrace > $@; \
    351352        $(evaluate-test)
    352353
     354tst-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
    353360$(inst_libexecdir)/getconf: $(inst_bindir)/getconf \
    354361                            $(objpfx)getconf.speclist FORCE
    355362        $(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  
    1515   License along with the GNU C Library; if not, see
    1616   <http://www.gnu.org/licenses/>.  */
    1717
    18 #ifdef  HAVE_CONFIG_H
     18#ifndef _LIBC
    1919# include <config.h>
    2020#endif
    2121
     
    2727#include <stdbool.h>
    2828#include <stddef.h>
    2929#include <stdint.h>
    30 
    31 /* Outcomment the following line for production quality code.  */
    32 /* #define NDEBUG 1 */
    3330#include <assert.h>
     31#include <unistd.h>
    3432
    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
    4535#endif
    4636
    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>
    5339#endif
    5440
    5541#include <errno.h>
     
    5743# define __set_errno(val) errno = (val)
    5844#endif
    5945
    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>
    7847#include <stdlib.h>
    7948#include <string.h>
    8049#include <alloca.h>
     
    8756# define opendir(name) __opendir (name)
    8857# define readdir(str) __readdir64 (str)
    8958# define getpwnam_r(name, bufp, buf, len, res) \
    90    __getpwnam_r (name, bufp, buf, len, res)
     59    __getpwnam_r (name, bufp, buf, len, res)
    9160# ifndef __stat64
    9261#  define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf)
    9362# endif
    9463# define struct_stat64          struct stat64
     64# define FLEXIBLE_ARRAY_MEMBER
    9565#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
    10775#endif /* _LIBC */
    10876
    10977#include <fnmatch.h>
    11078
     79#include <flexmember.h>
     80#include <glob_internal.h>
     81
    11182#ifdef _SC_GETPW_R_SIZE_MAX
    11283# define GETPW_R_SIZE_MAX()     sysconf (_SC_GETPW_R_SIZE_MAX)
    11384#else
     
    12192
    12293
    12394static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
    12495
     96typedef 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
    125109/* A representation of a directory entry which does not depend on the
    126110   layout of struct dirent, or the size of ino_t.  */
    127111struct readdir_result
    128112{
    129113  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
    133118  bool skip_entry;
     119#endif
    134120};
    135121
    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.  */
     123static dirent_type
     124readdir_result_type (struct readdir_result d)
    161125{
    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
    163133}
    164134
     135/* Initialize and return skip_entry member of struct readdir_result.  */
    165136static bool
    166 readdir_result_might_be_dir (struct readdir_result d)
     137readdir_result_skip_entry (struct readdir_result d)
    167138{
    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__
    174139/* Initializer for skip_entry.  POSIX does not require that the d_ino
    175140   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}
    180149
    181150/* 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  
    4343}
    4444libc_hidden_def (glob64)
    4545
    46 void
    47 globfree64 (glob64_t *pglob)
    48 {
    49 }
    50 libc_hidden_def (globfree64)
    51 
    5246stub_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
     22static 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.  */
     28int
     29__glob_pattern_p (const char *pattern, int quote)
     30{
     31  return __glob_pattern_type (pattern, quote) == 1;
     32}
     33weak_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.  */
     27void
     28globfree (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
     40libc_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.  */
     27void
     28globfree64 (glob64_t *pglob)
     29{
     30}
     31libc_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.  */
     29static int do_onlydir;
     30
     31/* Flag which indicates whether to pass the GLOB_NOCHECK flag.  */
     32static int do_nocheck;
     33
     34/* Flag which indicates whether to pass the GLOB_MARK flag.  */
     35static int do_mark;
     36
     37/* Flag which indicates whether to pass the GLOB_NOESCAPE flag.  */
     38static int do_noescape;
     39
     40static void
     41one_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
     60enum
     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'.  */
     76static char *repeat;
     77
     78/* Return a string of SIZE characters.  */
     79const char *
     80repeating_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
     89static int
     90do_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  
    1515#undef __stat
    1616#define __stat(file, buf) __xstat64 (_STAT_VER, file, buf)
    1717
    18 #define NO_GLOB_PATTERN_P 1
    19 
    2018#define COMPILE_GLOB64  1
    2119
    2220#include <posix/glob.c>
    2321
    2422libc_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
     10libc_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  
    255255      break;                                                                  \
    256256    if (!scratch_buffer_grow (tmpbuf))                                        \
    257257      {                                                                       \
     258        __resolv_context_enable_inet6 (res_ctx, res_enable_inet6);            \
     259        __resolv_context_put (res_ctx);                                       \
    258260        result = -EAI_MEMORY;                                                 \
    259261        goto free_and_return;                                                 \
    260262      }                                                                       \
  • 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  
    162162ifeq ($(subdir),posix)
    163163sysdep_headers += bits/initspin.h
    164164
    165 sysdep_routines += sched_getcpu
     165sysdep_routines += sched_getcpu oldglob
    166166
    167167tests += tst-affinity tst-affinity-pid
    168168
  • 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 += oldglob
    3 endif
    4 
    51ifeq ($(subdir),stdlib)
    62gen-as-const-headers += ucontext-offsets.sym
    73endif
  • 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  
    4242#undef globfree64
    4343
    4444versioned_symbol (libc, __new_glob, glob, GLIBC_2_1);
    45 versioned_symbol (libc, __new_globfree, globfree, GLIBC_2_1);
    4645libc_hidden_ver (__new_glob, glob)
    47 libc_hidden_ver (__new_globfree, globfree)
    4846
    4947weak_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
     27extern void __new_globfree (glob_t *__pglob);
     28
     29#include <posix/globfree.c>
     30
     31#undef globfree64
     32
     33versioned_symbol (libc, __new_globfree, globfree, GLIBC_2_1);
     34libc_hidden_ver (__new_globfree, globfree)
     35
     36weak_alias (__new_globfree, globfree64)
     37libc_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
     27weak_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
     28weak_alias (globfree, globfree64)
     29libc_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
     35libc_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  
    3030
    3131#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
    3232
    33 #include <sysdeps/unix/sysv/linux/i386/olddirent.h>
     33#include <olddirent.h>
    3434
    3535int
    3636__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  
    2828
    2929#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
    3030
    31 #include <sysdeps/unix/sysv/linux/i386/olddirent.h>
     31#include <olddirent.h>
    3232
    3333#define __GETDENTS __old_getdents64
    3434#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.
    33   This file is part of the GNU C Library.
    44
    55   The GNU C Library is free software; you can redistribute it and/or
     
    1616   License along with the GNU C Library; if not, see
    1717   <http://www.gnu.org/licenses/>.  */
    1818
    19 #include <dirent.h>
    20 #include <glob.h>
    2119#include <sys/stat.h>
     20#include <kernel_stat.h>
    2221
    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>
    2526
    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)
    3529
    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)
    3734
    38 #define COMPILE_GLOB64  1
     35# undef stat
     36# define stat stat64
    3937
    40 #include <posix/glob.c>
     38# define COMPILE_GLOB64 1
    4139
    42 #include "shlib-compat.h"
     40# include <posix/glob.c>
    4341
    44 libc_hidden_def (globfree64)
     42# include "shlib-compat.h"
    4543
     44# ifdef GLOB_NO_OLD_VERSION
     45strong_alias (__glob64, glob64)
     46libc_hidden_def (glob64)
     47# else
    4648versioned_symbol (libc, __glob64, glob64, GLIBC_2_2);
    4749libc_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  
    3131
    3232#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
    3333
    34 #include <sysdeps/unix/sysv/linux/i386/olddirent.h>
     34#include <olddirent.h>
    3535
    3636#define __READDIR attribute_compat_text_section __old_readdir64
    3737#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  
    3131
    3232#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
    3333
    34 #include <sysdeps/unix/sysv/linux/i386/olddirent.h>
     34#include <olddirent.h>
    3535
    3636#define __READDIR_R attribute_compat_text_section __old_readdir64_r
    3737#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  
    3030
    3131#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2)
    3232
    33 #include <sysdeps/unix/sysv/linux/i386/olddirent.h>
     33#include <olddirent.h>
    3434
    3535int
    3636__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
     12int __old_glob64 (const char *__pattern, int __flags,
     13                  int (*__errfunc) (const char *, int),
     14                  glob64_t *__pglob);
     15libc_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
     40libc_hidden_def (__old_glob64);
     41
     42compat_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_decl
    2 #define globfree64 __no_globfree64_decl
    3 #include <posix/glob.c>
    4 #undef glob64
    5 #undef globfree64
    6 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 */