>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