Patch to detect (and ignore) symlink loops in pcre2grep.

This commit is contained in:
Philip Hazel 2021-08-28 17:37:33 +01:00
parent 6c2fe9da99
commit d5a61ee891
6 changed files with 46 additions and 11 deletions

View File

@ -98,6 +98,7 @@
# 2021-07-05 JWSB modified such both the static and shared library can be # 2021-07-05 JWSB modified such both the static and shared library can be
# build in one go. # build in one go.
# 2021-08-28 PH increased minimum version # 2021-08-28 PH increased minimum version
# 2021-08-28 PH added test for realpath()
PROJECT(PCRE2 C) PROJECT(PCRE2 C)
@ -143,6 +144,7 @@ CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H)
CHECK_SYMBOL_EXISTS(bcopy "strings.h" HAVE_BCOPY) CHECK_SYMBOL_EXISTS(bcopy "strings.h" HAVE_BCOPY)
CHECK_SYMBOL_EXISTS(memfd_create "sys/mman.h" HAVE_MEMFD_CREATE) CHECK_SYMBOL_EXISTS(memfd_create "sys/mman.h" HAVE_MEMFD_CREATE)
CHECK_SYMBOL_EXISTS(memmove "string.h" HAVE_MEMMOVE) CHECK_SYMBOL_EXISTS(memmove "string.h" HAVE_MEMMOVE)
CHECK_SYMBOL_EXISTS(realpath "stdlib.h" HAVE_REALPATH)
CHECK_SYMBOL_EXISTS(secure_getenv "stdlib.h" HAVE_SECURE_GETENV) CHECK_SYMBOL_EXISTS(secure_getenv "stdlib.h" HAVE_SECURE_GETENV)
CHECK_SYMBOL_EXISTS(strerror "string.h" HAVE_STRERROR) CHECK_SYMBOL_EXISTS(strerror "string.h" HAVE_STRERROR)

View File

@ -37,6 +37,10 @@ adding "-static". For example, pcre2-8.lib has become pcre2-8-static.lib.
2.8.12 is deprecated (it was set to 2.8.5) and causes warnings. Even 3.0.0 is 2.8.12 is deprecated (it was set to 2.8.5) and causes warnings. Even 3.0.0 is
quote old; it was released in 2014. quote old; it was released in 2014.
4. Implemented a modified version of Thomas Tempelmann's pcre2grep patch for
detecting symlink loops. This is dependent on the availability of realpath(),
which is now tested for in ./configure and CMakeLists.txt.
Version 10.37 26-May-2021 Version 10.37 26-May-2021

View File

@ -9,9 +9,9 @@ dnl The PCRE2_PRERELEASE feature is for identifying release candidates. It might
dnl be defined as -RC2, for example. For real releases, it should be empty. dnl be defined as -RC2, for example. For real releases, it should be empty.
m4_define(pcre2_major, [10]) m4_define(pcre2_major, [10])
m4_define(pcre2_minor, [37]) m4_define(pcre2_minor, [38])
m4_define(pcre2_prerelease, []) m4_define(pcre2_prerelease, [-RC1])
m4_define(pcre2_date, [2021-05-26]) m4_define(pcre2_date, [2021-08-28])
# Libtool shared library interface versions (current:revision:age) # Libtool shared library interface versions (current:revision:age)
m4_define(libpcre2_8_version, [10:2:10]) m4_define(libpcre2_8_version, [10:2:10])
@ -512,7 +512,7 @@ AC_TYPE_SIZE_T
# Checks for library functions. # Checks for library functions.
AC_CHECK_FUNCS(bcopy memfd_create memmove mkostemp secure_getenv strerror) AC_CHECK_FUNCS(bcopy memfd_create memmove mkostemp realpath secure_getenv strerror)
# Check for the availability of libz (aka zlib) # Check for the availability of libz (aka zlib)

View File

@ -103,6 +103,9 @@ sure both macros are undefined; an emulation function will then be used. */
/* Define to 1 if you have the <readline/readline.h> header file. */ /* Define to 1 if you have the <readline/readline.h> header file. */
/* #undef HAVE_READLINE_READLINE_H */ /* #undef HAVE_READLINE_READLINE_H */
/* Define to 1 if you have the `realpath' function. */
/* #undef HAVE_REALPATH */
/* Define to 1 if you have the `secure_getenv' function. */ /* Define to 1 if you have the `secure_getenv' function. */
/* #undef HAVE_SECURE_GETENV */ /* #undef HAVE_SECURE_GETENV */
@ -230,7 +233,7 @@ sure both macros are undefined; an emulation function will then be used. */
#define PACKAGE_NAME "PCRE2" #define PACKAGE_NAME "PCRE2"
/* Define to the full name and version of this package. */ /* Define to the full name and version of this package. */
#define PACKAGE_STRING "PCRE2 10.37" #define PACKAGE_STRING "PCRE2 10.38-RC1"
/* Define to the one symbol short name of this package. */ /* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "pcre2" #define PACKAGE_TARNAME "pcre2"
@ -239,7 +242,7 @@ sure both macros are undefined; an emulation function will then be used. */
#define PACKAGE_URL "" #define PACKAGE_URL ""
/* Define to the version of this package. */ /* Define to the version of this package. */
#define PACKAGE_VERSION "10.37" #define PACKAGE_VERSION "10.38-RC1"
/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested /* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested
parentheses (of any kind) in a pattern. This limits the amount of system parentheses (of any kind) in a pattern. This limits the amount of system
@ -432,7 +435,7 @@ sure both macros are undefined; an emulation function will then be used. */
#endif #endif
/* Version number of package */ /* Version number of package */
#define VERSION "10.37" #define VERSION "10.38-RC1"
/* Define to empty if `const' does not conform to ANSI C. */ /* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */ /* #undef const */

View File

@ -103,6 +103,9 @@ sure both macros are undefined; an emulation function will then be used. */
/* Define to 1 if you have the <readline/readline.h> header file. */ /* Define to 1 if you have the <readline/readline.h> header file. */
#undef HAVE_READLINE_READLINE_H #undef HAVE_READLINE_READLINE_H
/* Define to 1 if you have the `realpath' function. */
#undef HAVE_REALPATH
/* Define to 1 if you have the `secure_getenv' function. */ /* Define to 1 if you have the `secure_getenv' function. */
#undef HAVE_SECURE_GETENV #undef HAVE_SECURE_GETENV

View File

@ -63,7 +63,7 @@ POSSIBILITY OF SUCH DAMAGE.
#define WIN32 #define WIN32
#endif #endif
/* Some cmake's define it still */ /* Some CMake's define it still */
#if defined(__CYGWIN__) && defined(WIN32) #if defined(__CYGWIN__) && defined(WIN32)
#undef WIN32 #undef WIN32
#endif #endif
@ -3327,7 +3327,7 @@ if (isdirectory(pathname))
if (dee_action == dee_RECURSE) if (dee_action == dee_RECURSE)
{ {
char buffer[FNBUFSIZ]; char childpath[FNBUFSIZ];
char *nextfile; char *nextfile;
directory_type *dir = opendirectory(pathname); directory_type *dir = opendirectory(pathname);
@ -3349,8 +3349,31 @@ if (isdirectory(pathname))
rc = 2; rc = 2;
break; break;
} }
sprintf(buffer, "%s%c%s", pathname, FILESEP, nextfile); sprintf(childpath, "%s%c%s", pathname, FILESEP, nextfile);
frc = grep_or_recurse(buffer, dir_recurse, FALSE);
/* If the realpath() function is available, we can try to prevent endless
recursion caused by a symlink pointing to a parent directory (GitHub
issue #2 (old Bugzilla #2794). Original patch from Thomas Tempelmann.
Modified to avoid using strlcat() because that isn't a standard C
function, and also modified not to copy back the fully resolved path,
because that affects the output from pcre2grep. */
#ifdef HAVE_REALPATH
char resolvedpath[PATH_MAX];
if (realpath(childpath, resolvedpath) == NULL)
continue; /* This path is invalid - we can skip processing this */
BOOL isSame = strcmp(pathname, resolvedpath) == 0;
if (isSame) continue; /* We have a recursion */
size_t rlen = strlen(resolvedpath);
if (rlen++ < sizeof(resolvedpath) - 3)
{
strcat(resolvedpath, "/");
BOOL contained = strncmp(pathname, resolvedpath, rlen) == 0;
if (contained) continue; /* We have a recursion */
}
#endif /* HAVE_REALPATH */
frc = grep_or_recurse(childpath, dir_recurse, FALSE);
if (frc > 1) rc = frc; if (frc > 1) rc = frc;
else if (frc == 0 && rc == 1) rc = 0; else if (frc == 0 && rc == 1) rc = 0;
} }