>From b5e099566022dd7390afe58cf84e5b991683776c Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Fri, 22 Sep 2017 14:41:52 -0700 Subject: [PATCH] glob: add compat to not follow dangling symlinks Merged from this proposed change to glibc: https://sourceware.org/ml/libc-alpha/2017-09/msg00848.html * lib/glob.c [_LIBC]: Include . (__glob, GLOB_ATTRIBUTE) [!_LIBC]: New macros. (glob_lstat): New function. (GL_LSTAT, LSTAT64): New macros. (glob): Rename to __glob and add versioned symbol to 2.27. (glob_in_dir): Use glob_lstat. --- ChangeLog | 12 +++++++++++ lib/glob.c | 70 +++++++++++++++++++++++++++++++++++++++----------------------- 2 files changed, 56 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index 82ecf539a..313d359a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2017-09-22 Adhemerval Zanella + + glob: add compat to not follow dangling symlinks + Merged from this proposed change to glibc: + https://sourceware.org/ml/libc-alpha/2017-09/msg00848.html + * lib/glob.c [_LIBC]: Include . + (__glob, GLOB_ATTRIBUTE) [!_LIBC]: New macros. + (glob_lstat): New function. + (GL_LSTAT, LSTAT64): New macros. + (glob): Rename to __glob and add versioned symbol to 2.27. + (glob_in_dir): Use glob_lstat. + 2017-09-21 Paul Eggert mktime: port to OpenVMS diff --git a/lib/glob.c b/lib/glob.c index 2a5e6642e..a9b519c2f 100644 --- a/lib/glob.c +++ b/lib/glob.c @@ -57,7 +57,9 @@ # endif # define struct_stat64 struct stat64 # define FLEXIBLE_ARRAY_MEMBER +# include #else /* !_LIBC */ +# define __glob glob # define __getlogin_r(buf, len) getlogin_r (buf, len) # define __lstat64(fname, buf) lstat (fname, buf) # define __stat64(fname, buf) stat (fname, buf) @@ -179,6 +181,29 @@ convert_dirent64 (const struct dirent64 *source) ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0) #endif +static int +glob_lstat (glob_t *pglob, int flags, const char *fullname) +{ +/* Use on glob-lstat-compat.c to provide a compat symbol which does not + use lstat / gl_lstat. */ +#ifdef GLOB_NO_LSTAT +# define GL_LSTAT gl_stat +# define LSTAT64 __stat64 +#else +# define GL_LSTAT gl_lstat +# define LSTAT64 __lstat64 +#endif + + union + { + struct stat st; + struct_stat64 st64; + } ust; + return (__glibc_unlikely (flags & GLOB_ALTDIRFUNC) + ? pglob->GL_LSTAT (fullname, &ust.st) + : LSTAT64 (fullname, &ust.st64)); +} + /* 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. */ @@ -248,6 +273,9 @@ next_brace_sub (const char *cp, int flags) return *cp != '\0' ? cp : NULL; } +#ifndef GLOB_ATTRIBUTE +# define GLOB_ATTRIBUTE +#endif /* Do glob searching for PATTERN, placing results in PGLOB. The bits defined above may be set in FLAGS. @@ -258,11 +286,9 @@ next_brace_sub (const char *cp, int flags) If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. Otherwise, 'glob' returns zero. */ int -#ifdef GLOB_ATTRIBUTE GLOB_ATTRIBUTE -#endif -glob (const char *pattern, int flags, int (*errfunc) (const char *, int), - glob_t *pglob) +__glob (const char *pattern, int flags, int (*errfunc) (const char *, int), + glob_t *pglob) { const char *filename; char *dirname = NULL; @@ -343,7 +369,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), if (begin != NULL) { /* Allocate working buffer large enough for our work. Note that - we have at least an opening and closing brace. */ + we have at least an opening and closing brace. */ size_t firstc; char *alt_start; const char *p; @@ -406,9 +432,10 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), /* Construct the new glob expression. */ mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len); - result = glob (onealt, - ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC)) - | GLOB_APPEND), errfunc, pglob); + result = __glob (onealt, + ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC)) + | GLOB_APPEND), + errfunc, pglob); /* If we got an error, return it. */ if (result && result != GLOB_NOMATCH) @@ -499,7 +526,6 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), { char *newp; dirlen = filename - pattern; - #if defined __MSDOS__ || defined WINDOWS32 if (*filename == ':' || (filename > pattern + 1 && filename[-1] == ':')) @@ -558,7 +584,7 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC); } } - int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob); + int val = __glob (dirname, flags | GLOB_MARK, errfunc, pglob); if (val == 0) pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK)); @@ -932,11 +958,10 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), dirs.gl_lstat = pglob->gl_lstat; } - status = glob (dirname, - ((flags & (GLOB_ERR | GLOB_NOESCAPE - | GLOB_ALTDIRFUNC)) - | GLOB_NOSORT | GLOB_ONLYDIR), - errfunc, &dirs); + status = __glob (dirname, + ((flags & (GLOB_ERR | GLOB_NOESCAPE | GLOB_ALTDIRFUNC)) + | GLOB_NOSORT | GLOB_ONLYDIR), + errfunc, &dirs); if (status != 0) { if ((flags & GLOB_NOCHECK) == 0 || status != GLOB_NOMATCH) @@ -1134,8 +1159,9 @@ glob (const char *pattern, int flags, int (*errfunc) (const char *, int), return retval; } -#if defined _LIBC && !defined glob -libc_hidden_def (glob) +#if defined _LIBC && !defined __glob +versioned_symbol (libc, __glob, glob, GLIBC_2_27); +libc_hidden_ver (__glob, glob) #endif @@ -1251,11 +1277,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags, } else if (meta == GLOBPAT_NONE) { - union - { - struct stat st; - struct_stat64 st64; - } ust; size_t patlen = strlen (pattern); size_t fullsize; bool alloca_fullname @@ -1274,10 +1295,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags, mempcpy (mempcpy (mempcpy (fullname, directory, dirlen), "/", 1), pattern, patlen + 1); - if (((__builtin_expect (flags & GLOB_ALTDIRFUNC, 0) - ? (*pglob->gl_lstat) (fullname, &ust.st) - : __lstat64 (fullname, &ust.st64)) - == 0) + if (glob_lstat (pglob, flags, fullname) == 0 || errno == EOVERFLOW) /* We found this file to be existing. Now tell the rest of the function to copy this name into the result. */ -- 2.13.5