[v2,1/2] posix: Add compat glob symbol to not follow dangling symbols

Message ID 85e6792f-756b-0077-afb6-96f42c8840a0@cs.ucla.edu
State New, archived
Headers

Commit Message

Paul Eggert Sept. 22, 2017, 9:43 p.m. UTC
  On 09/22/2017 06:02 AM, Adhemerval Zanella wrote:
> +		       ((flags & (GLOB_ERR | GLOB_NOESCAPE | GLOB_ALTDIRFUNC))
> +		       | GLOB_NOSORT | GLOB_ONLYDIR),

The indenting is not quite right here: the "|" should be under the 2nd 
"(" in the previous line, not under the 1st.

> +	      result = __glob (onealt,
> +			       ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
> +			       | GLOB_APPEND), errfunc, pglob);

As long as we're changing indenting anyway, we should fix the indenting 
here to match the usual GNU style. Something like this:

               result = __glob (onealt,
                                ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
                                 | GLOB_APPEND),
                                errfunc, pglob);

Other than these minor indenting things it looks OK. glibc's glob.c is 
wrongly indented elsewhere, but that can be fixed separately.

Proposed corresponding gnulib patch attached; it would keep gnulib 
glob.c in sync with glibc's, except for whitespace and the https: thing. 
CC'ing this to bug-gnulib.
  

Comments

Adhemerval Zanella Sept. 25, 2017, 5:03 p.m. UTC | #1
On 22/09/2017 18:43, Paul Eggert wrote:
> On 09/22/2017 06:02 AM, Adhemerval Zanella wrote:
>> +               ((flags & (GLOB_ERR | GLOB_NOESCAPE | GLOB_ALTDIRFUNC))
>> +               | GLOB_NOSORT | GLOB_ONLYDIR),
>
> The indenting is not quite right here: the "|" should be under the 2nd
> "(" in the previous line, not under the 1st.
Ack.

>
>> +          result = __glob (onealt,
>> +                   ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
>> +                   | GLOB_APPEND), errfunc, pglob);
>
> As long as we're changing indenting anyway, we should fix the
> indenting here to match the usual GNU style. Something like this:
>
>               result = __glob (onealt,
>                                ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC))
>                                 | GLOB_APPEND),
>                                errfunc, pglob);

Ack.

>
> Other than these minor indenting things it looks OK. glibc's glob.c is
> wrongly indented elsewhere, but that can be fixed separately.
>
> Proposed corresponding gnulib patch attached; it would keep gnulib
> glob.c in sync with glibc's, except for whitespace and the https:
> thing. CC'ing this to bug-gnulib.
I will commit both patch shortly, thanks for the review.
  
Andreas Schwab Sept. 26, 2017, 3:29 p.m. UTC | #2
Current version of make won't build against this (undefined reference to
__alloca from included glob sources).

Andreas.
  
Andreas Schwab Sept. 27, 2017, 8:07 a.m. UTC | #3
I can confirm that make works properly with the compat glob symbol.

Andreas.
  

Patch

From b5e099566022dd7390afe58cf84e5b991683776c Mon Sep 17 00:00:00 2001
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
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 <shlib-compat.h>.
(__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  <adhemerval.zanella@linaro.org>
+
+	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 <shlib-compat.h>.
+	(__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  <eggert@cs.ucla.edu>
 
 	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 <shlib-compat.h>
 #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