]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
posix: Use malloc instead of alloca for the glob directory name
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Fri, 31 Jul 2026 16:32:13 +0000 (16:32 +0000)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Sun, 9 Aug 2026 11:53:55 +0000 (08:53 -0300)
Use malloc unconditionally instead.  These are one-off allocations
whose cost is dwarfed by the readdir and fnmatch work that follows.

The amount of stack this can take is not bounded by these calls alone,
glob recursively calls itself per pattern component, and each call
starts a fresh alloca budget.

Checked on x86_64-linux-gnu, aarch64-linux-gnu, and i686-linux-gnu.

Reviewed-by: Collin Funk <collin.funk1@gmail.com>
posix/glob.c

index 17b8b90cde7914dcd761946af03ceebd44b58a58..a81a2285b89242cf95a9c319545e1a0dbbc7ff35 100644 (file)
@@ -557,15 +557,10 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
         }
 #endif
 
-      if (glob_use_alloca (alloca_used, dirlen + 1))
-        newp = alloca_account (dirlen + 1, alloca_used);
-      else
-        {
-          newp = malloc (dirlen + 1);
-          if (newp == NULL)
-            return GLOB_NOSPACE;
-          malloc_dirname = 1;
-        }
+      newp = malloc (dirlen + 1);
+      if (newp == NULL)
+        return GLOB_NOSPACE;
+      malloc_dirname = 1;
       *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
       dirname = newp;
       ++filename;
@@ -719,19 +714,14 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
             {
               char *newp;
               size_t home_len = strlen (home_dir);
-              int use_alloca = glob_use_alloca (alloca_used, home_len + dirlen);
-              if (use_alloca)
-                newp = alloca_account (home_len + dirlen, alloca_used);
-              else
+
+              newp = malloc (home_len + dirlen);
+              if (newp == NULL)
                 {
-                  newp = malloc (home_len + dirlen);
-                  if (newp == NULL)
-                    {
-                      if (__glibc_unlikely (malloc_home_dir))
-                        free (home_dir);
-                      retval = GLOB_NOSPACE;
-                      goto out;
-                    }
+                  if (__glibc_unlikely (malloc_home_dir))
+                    free (home_dir);
+                  retval = GLOB_NOSPACE;
+                  goto out;
                 }
 
               mempcpy (mempcpy (newp, home_dir, home_len),
@@ -742,7 +732,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
 
               dirname = newp;
               dirlen += home_len - 1;
-              malloc_dirname = !use_alloca;
+              malloc_dirname = 1;
 
               if (__glibc_unlikely (malloc_home_dir))
                 free (home_dir);
@@ -855,21 +845,15 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int),
 
                 malloc_dirname = 0;
 
-                if (glob_use_alloca (alloca_used, home_len + rest_len + 1))
-                  dirname = alloca_account (home_len + rest_len + 1,
-                                            alloca_used);
-                else
+                dirname = malloc (home_len + rest_len + 1);
+                if (dirname == NULL)
                   {
-                    dirname = malloc (home_len + rest_len + 1);
-                    if (dirname == NULL)
-                      {
-                        free (prev_dirname);
-                        scratch_buffer_free (&pwtmpbuf);
-                        retval = GLOB_NOSPACE;
-                        goto out;
-                      }
-                    malloc_dirname = 1;
+                    free (prev_dirname);
+                    scratch_buffer_free (&pwtmpbuf);
+                    retval = GLOB_NOSPACE;
+                    goto out;
                   }
+                malloc_dirname = 1;
                 d = mempcpy (dirname, p->pw_dir, home_len);
                 if (end_name != NULL)
                   d = mempcpy (d, end_name, rest_len);