From: Collin Funk Date: Sat, 11 Oct 2025 05:34:19 +0000 (-0700) Subject: glob: Prevent a stack overflow with many slashes. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f1a18f6f4cb3bb8ddbc930c4568be9e6ba257b72;p=thirdparty%2Fgnulib.git glob: Prevent a stack overflow with many slashes. * lib/glob.c (__glob): Strip trailing slashes before making the recursive call. * m4/glob.m4 (gl_GLOB): Check for the glibc bug. * doc/posix-functions/glob.texi: Mention the bug. --- diff --git a/ChangeLog b/ChangeLog index 0e01db0789..cee84c0bb2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2025-10-13 Collin Funk + + glob: Prevent a stack overflow with many slashes. + * lib/glob.c (__glob): Strip trailing slashes before making the + recursive call. + * m4/glob.m4 (gl_GLOB): Check for the glibc bug. + * doc/posix-functions/glob.texi: Mention the bug. + 2025-10-13 Bruno Haible getline: Fix compilation error in C++ mode (regression 2025-10-10). diff --git a/doc/posix-functions/glob.texi b/doc/posix-functions/glob.texi index c5c423bc1a..c74f62f967 100644 --- a/doc/posix-functions/glob.texi +++ b/doc/posix-functions/glob.texi @@ -20,6 +20,13 @@ glibc 2.26, AIX 7.2, HP-UX 11, Solaris 11.4. On platforms where @code{off_t} is a 32-bit type, this function may not work correctly on huge directories 2 GiB and larger. @xref{Large File Support}. +@item +This function makes a recursive call for every trailing @code{/} and +every @code{/} following a wildcard character on some platforms, which +can cause the stack to overflow: +@c https://sourceware.org/PR30635 +@c https://sourceware.org/PR33537 +glibc 2.42. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/glob.c b/lib/glob.c index 0bd8b4237c..48f10ae0e1 100644 --- a/lib/glob.c +++ b/lib/glob.c @@ -582,6 +582,10 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC); } } + /* Prevent stack overflows with many trailing '/' characters. */ + for (char *p = &dirname[dirlen - 1]; + p > dirname && p[0] == '/' && p[-1] == '/'; --p) + p[0] = '\0'; int val = __glob (dirname, flags | GLOB_MARK, errfunc, pglob); if (val == 0) pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK) diff --git a/m4/glob.m4 b/m4/glob.m4 index ee0320bb10..563e8e4ff8 100644 --- a/m4/glob.m4 +++ b/m4/glob.m4 @@ -1,5 +1,5 @@ # glob.m4 -# serial 30 +# serial 31 dnl Copyright (C) 2005-2007, 2009-2025 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -23,16 +23,45 @@ AC_DEFUN([gl_GLOB], esac else - AC_CACHE_CHECK([for GNU glob interface version 1 or 2], - [gl_cv_gnu_glob_interface_version_1_2], -[ AC_COMPILE_IFELSE([AC_LANG_SOURCE( -[[#include -char a[_GNU_GLOB_INTERFACE_VERSION == 1 || _GNU_GLOB_INTERFACE_VERSION == 2 ? 1 : -1];]])], - [gl_cv_gnu_glob_interface_version_1_2=yes], - [gl_cv_gnu_glob_interface_version_1_2=no])]) - if test "$gl_cv_gnu_glob_interface_version_1_2" = "no"; then - REPLACE_GLOB=1 - fi + AC_CACHE_CHECK([whether glob overflows the stack with recursive calls], + [gl_cv_glob_overflows_stack], + [AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ + #include + #include + #include + #include + int + main (void) + { + /* Test that glob with many trailing slashes or slashes following + a wildcard does not overflow the stack as it did in glibc 2.42 + and earlier. */ + char *p = malloc (10000); + glob_t g; + int res = 0; + if (p != NULL) + { + memset (p, '/', 9999); + p[9999] = '\0'; + res = glob (p, 0, NULL, &g); + globfree (&g); + } + return !(res == 0); + }]])], + [gl_cv_glob_overflows_stack=no], + [gl_cv_glob_overflows_stack=yes], + [case "$host_os" in + # Guess yes on glibc systems. + *-gnu* | gnu*) gl_cv_glob_overflows_stack="guessing yes" ;; + esac + ]) + ]) + + case $gl_cv_glob_overflows_stack in + *yes) REPLACE_GLOB=1 ;; + *) REPLACE_GLOB=0 ;; + esac if test $REPLACE_GLOB = 0; then AC_CACHE_CHECK([whether glob lists broken symlinks],