From e7668e17500703229c5954e516b36184bd3e8c1c Mon Sep 17 00:00:00 2001 From: chengyechun Date: Tue, 7 Jun 2022 11:13:05 +0800 Subject: [PATCH] Switch from PCRE to PCRE2 --- backport-Switch-from-PCRE-to-PCRE2.patch | 313 +++++++++++++++++++++++ httpd.spec | 13 +- 2 files changed, 323 insertions(+), 3 deletions(-) create mode 100644 backport-Switch-from-PCRE-to-PCRE2.patch diff --git a/backport-Switch-from-PCRE-to-PCRE2.patch b/backport-Switch-from-PCRE-to-PCRE2.patch new file mode 100644 index 0000000..5cb4bcb --- /dev/null +++ b/backport-Switch-from-PCRE-to-PCRE2.patch @@ -0,0 +1,313 @@ +From 12cfcf08fffc6e4ec597e0396016d09afdb89fa8 Mon Sep 17 00:00:00 2001 +From: wrowe, Petr Pisar +Date: Fri, DEC 9 19:06:06 2016 UTC +Subject: [PATCH] backport Switch from PCRE to PCRE2 + +Conflict:NA +Reference:https://github.com/apache/httpd/commit/12cfcf08fffc6e4ec597e0396016d09afdb89fa8 + +--- + configure.in | 26 +++++----- + server/util_pcre.c | 140 +++++++++++++++++++++++++++++++++++++++-------------- + 2 files changed, 118 insertions(+), 48 deletions(-) + +diff --git a/configure.in b/configure.in +index 916377b..db7edc3 100644 +--- a/configure.in ++++ b/configure.in +@@ -214,29 +214,33 @@ fi + + AC_ARG_WITH(pcre, + APACHE_HELP_STRING(--with-pcre=PATH,Use external PCRE library)) +- +-AC_PATH_PROG(PCRE_CONFIG, pcre-config, false) +-if test -d "$with_pcre" && test -x "$with_pcre/bin/pcre-config"; then +- PCRE_CONFIG=$with_pcre/bin/pcre-config +-elif test -x "$with_pcre"; then +- PCRE_CONFIG=$with_pcre ++if test "x$with_pcre" = "x" || test "$with_pcre" = "yes"; then ++ with_pcre="$PATH" ++else if which $with_pcre 2>/dev/null; then :; else ++ with_pcre="$with_pcre/bin:$with_pcre" ++fi + fi ++AC_CHECK_TARGET_TOOLS(PCRE_CONFIG, [pcre2-config pcre-config], ++ [`which $with_pcre 2>/dev/null`], $with_pcre) + +-if test "$PCRE_CONFIG" != "false"; then ++if test "x$PCRE_CONFIG" != "x"; then + if $PCRE_CONFIG --version >/dev/null 2>&1; then :; else +- AC_MSG_ERROR([Did not find pcre-config script at $PCRE_CONFIG]) ++ AC_MSG_ERROR([Did not find working script at $PCRE_CONFIG]) + fi + case `$PCRE_CONFIG --version` in ++ [1[0-9].*]) ++ AC_DEFINE(HAVE_PCRE2, 1, [Detected PCRE2]) ++ ;; + [[1-5].*]) +- AC_MSG_ERROR([Need at least pcre version 6.0]) ++ AC_MSG_ERROR([Need at least pcre version 6.7]) + ;; + esac + AC_MSG_NOTICE([Using external PCRE library from $PCRE_CONFIG]) + APR_ADDTO(PCRE_INCLUDES, [`$PCRE_CONFIG --cflags`]) +- APR_ADDTO(PCRE_LIBS, [`$PCRE_CONFIG --libs`]) ++ APR_ADDTO(PCRE_LIBS, [`$PCRE_CONFIG --libs8 2>/dev/null || $PCRE_CONFIG --libs`]) + APR_ADDTO(HTTPD_LIBS, [\$(PCRE_LIBS)]) + else +- AC_MSG_ERROR([pcre-config for libpcre not found. PCRE is required and available from http://pcre.org/]) ++ AC_MSG_ERROR([pcre(2)-config for libpcre not found. PCRE is required and available from http://pcre.org/]) + fi + APACHE_SUBST(PCRE_LIBS) + +diff --git a/server/util_pcre.c b/server/util_pcre.c +index 78fc983..0fdf5f9 100644 +--- a/server/util_pcre.c ++++ b/server/util_pcre.c +@@ -55,10 +55,18 @@ POSSIBILITY OF SUCH DAMAGE. + #include "httpd.h" + #include "apr_strings.h" + #include "apr_tables.h" ++ ++#ifdef HAVE_PCRE2 ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include "pcre2.h" ++#define PCREn(x) PCRE2_ ## x ++#else + #include "pcre.h" ++#define PCREn(x) PCRE_ ## x ++#endif + + /* PCRE_DUPNAMES is only present since version 6.7 of PCRE */ +-#ifndef PCRE_DUPNAMES ++#if !defined(PCRE_DUPNAMES) && !defined(HAVE_PCRE2) + #error PCRE Version 6.7 or later required! + #else + +@@ -115,7 +123,11 @@ AP_DECLARE(apr_size_t) ap_regerror(int errcode, const ap_regex_t *preg, + + AP_DECLARE(void) ap_regfree(ap_regex_t *preg) + { ++#ifdef HAVE_PCRE2 ++ pcre2_code_free(preg->re_pcre); ++#else + (pcre_free)(preg->re_pcre); ++#endif + } + + +@@ -168,25 +180,37 @@ AP_DECLARE(int) ap_regcomp_default_cflag_by_name(const char *name) + */ + AP_DECLARE(int) ap_regcomp(ap_regex_t * preg, const char *pattern, int cflags) + { ++#ifdef HAVE_PCRE2 ++ uint32_t capcount; ++ size_t erroffset; ++#else + const char *errorptr; + int erroffset; ++#endif + int errcode = 0; +- int options = PCRE_DUPNAMES; ++ int options = PCREn(DUPNAMES); + + if ((cflags & AP_REG_NO_DEFAULT) == 0) + cflags |= default_cflags; + + if ((cflags & AP_REG_ICASE) != 0) +- options |= PCRE_CASELESS; ++ options |= PCREn(CASELESS); + if ((cflags & AP_REG_NEWLINE) != 0) +- options |= PCRE_MULTILINE; ++ options |= PCREn(MULTILINE); + if ((cflags & AP_REG_DOTALL) != 0) +- options |= PCRE_DOTALL; ++ options |= PCREn(DOTALL); + if ((cflags & AP_REG_DOLLAR_ENDONLY) != 0) +- options |= PCRE_DOLLAR_ENDONLY; ++ options |= PCREn(DOLLAR_ENDONLY); ++ ++#ifdef HAVE_PCRE2 ++ preg->re_pcre = pcre2_compile((const unsigned char *)pattern, ++ PCRE2_ZERO_TERMINATED, options, &errcode, ++ &erroffset, NULL); ++#else ++ preg->re_pcre = pcre_compile2(pattern, options, &errcode, ++ &errorptr, &erroffset, NULL); ++#endif + +- preg->re_pcre = +- pcre_compile2(pattern, options, &errcode, &errorptr, &erroffset, NULL); + preg->re_erroffset = erroffset; + + if (preg->re_pcre == NULL) { +@@ -199,8 +223,14 @@ AP_DECLARE(int) ap_regcomp(ap_regex_t * preg, const char *pattern, int cflags) + return AP_REG_INVARG; + } + ++#ifdef HAVE_PCRE2 ++ pcre2_pattern_info((const pcre2_code *)preg->re_pcre, ++ PCRE2_INFO_CAPTURECOUNT, &capcount); ++ preg->re_nsub = capcount; ++#else + pcre_fullinfo((const pcre *)preg->re_pcre, NULL, + PCRE_INFO_CAPTURECOUNT, &(preg->re_nsub)); ++#endif + return 0; + } + +@@ -232,17 +262,29 @@ AP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg, const char *buff, + { + int rc; + int options = 0; +- int *ovector = NULL; ++#ifdef HAVE_PCRE2 ++ pcre2_match_data *matchdata; ++ size_t *ovector; ++#else + int small_ovector[POSIX_MALLOC_THRESHOLD * 3]; + int allocated_ovector = 0; ++ int *ovector = NULL; ++#endif + + if ((eflags & AP_REG_NOTBOL) != 0) +- options |= PCRE_NOTBOL; ++ options |= PCREn(NOTBOL); + if ((eflags & AP_REG_NOTEOL) != 0) +- options |= PCRE_NOTEOL; +- +- ((ap_regex_t *)preg)->re_erroffset = (apr_size_t)(-1); /* Only has meaning after compile */ +- ++ options |= PCREn(NOTEOL); ++ ++#ifdef HAVE_PCRE2 ++ matchdata = pcre2_match_data_create(nmatch, NULL); ++ if (matchdata == NULL) ++ return AP_REG_ESPACE; ++ ovector = pcre2_get_ovector_pointer(matchdata); ++ rc = pcre2_match((const pcre2_code *)preg->re_pcre, ++ (const unsigned char *)buff, len, ++ 0, options, matchdata, NULL); ++#else + if (nmatch > 0) { + if (nmatch <= POSIX_MALLOC_THRESHOLD) { + ovector = &(small_ovector[0]); +@@ -257,49 +299,62 @@ AP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg, const char *buff, + + rc = pcre_exec((const pcre *)preg->re_pcre, NULL, buff, (int)len, + 0, options, ovector, nmatch * 3); ++#endif + + if (rc == 0) + rc = nmatch; /* All captured slots were filled in */ + + if (rc >= 0) { + apr_size_t i; +- for (i = 0; i < (apr_size_t)rc; i++) { ++ apr_size_t nlim = (apr_size_t)rc < nmatch ? (apr_size_t)rc : nmatch; ++ for (i = 0; i < nlim; i++) { + pmatch[i].rm_so = ovector[i * 2]; + pmatch[i].rm_eo = ovector[i * 2 + 1]; + } +- if (allocated_ovector) +- free(ovector); + for (; i < nmatch; i++) + pmatch[i].rm_so = pmatch[i].rm_eo = -1; ++ } ++ ++#ifdef HAVE_PCRE2 ++ pcre2_match_data_free(matchdata); ++#else ++ if (allocated_ovector) ++ free(ovector); ++#endif ++ if (rc >= 0) { + return 0; + } + + else { +- if (allocated_ovector) +- free(ovector); ++#ifdef HAVE_PCRE2 ++ if (rc <= PCRE2_ERROR_UTF8_ERR1 && rc >= PCRE2_ERROR_UTF8_ERR21) ++ return AP_REG_INVARG; ++#endif + switch (rc) { +- case PCRE_ERROR_NOMATCH: ++ case PCREn(ERROR_NOMATCH): + return AP_REG_NOMATCH; +- case PCRE_ERROR_NULL: ++ case PCREn(ERROR_NULL): + return AP_REG_INVARG; +- case PCRE_ERROR_BADOPTION: ++ case PCREn(ERROR_BADOPTION): + return AP_REG_INVARG; +- case PCRE_ERROR_BADMAGIC: ++ case PCREn(ERROR_BADMAGIC): + return AP_REG_INVARG; +- case PCRE_ERROR_UNKNOWN_NODE: +- return AP_REG_ASSERT; +- case PCRE_ERROR_NOMEMORY: ++ case PCREn(ERROR_NOMEMORY): + return AP_REG_ESPACE; +-#ifdef PCRE_ERROR_MATCHLIMIT +- case PCRE_ERROR_MATCHLIMIT: ++#if defined(HAVE_PCRE2) || defined(PCRE_ERROR_MATCHLIMIT) ++ case PCREn(ERROR_MATCHLIMIT): + return AP_REG_ESPACE; + #endif +-#ifdef PCRE_ERROR_BADUTF8 +- case PCRE_ERROR_BADUTF8: ++#if defined(PCRE_ERROR_UNKNOWN_NODE) ++ case PCRE_ERROR_UNKNOWN_NODE: ++ return AP_REG_ASSERT; ++#endif ++#if defined(PCRE_ERROR_BADUTF8) ++ case PCREn(ERROR_BADUTF8): + return AP_REG_INVARG; + #endif +-#ifdef PCRE_ERROR_BADUTF8_OFFSET +- case PCRE_ERROR_BADUTF8_OFFSET: ++#if defined(PCRE_ERROR_BADUTF8_OFFSET) ++ case PCREn(ERROR_BADUTF8_OFFSET): + return AP_REG_INVARG; + #endif + default: +@@ -312,18 +367,29 @@ AP_DECLARE(int) ap_regname(const ap_regex_t *preg, + apr_array_header_t *names, const char *prefix, + int upper) + { ++ char *nametable; ++#ifdef HAVE_PCRE2 ++ uint32_t namecount; ++ uint32_t nameentrysize; ++ uint32_t i; ++ pcre2_pattern_info((const pcre2_code *)preg->re_pcre, ++ PCRE2_INFO_NAMECOUNT, &namecount); ++ pcre2_pattern_info((const pcre2_code *)preg->re_pcre, ++ PCRE2_INFO_NAMEENTRYSIZE, &nameentrysize); ++ pcre2_pattern_info((const pcre2_code *)preg->re_pcre, ++ PCRE2_INFO_NAMETABLE, &nametable); ++#else + int namecount; + int nameentrysize; + int i; +- char *nametable; + + pcre_fullinfo((const pcre *)preg->re_pcre, NULL, +- PCRE_INFO_NAMECOUNT, &namecount); ++ PCRE_INFO_NAMECOUNT, &namecount); + pcre_fullinfo((const pcre *)preg->re_pcre, NULL, +- PCRE_INFO_NAMEENTRYSIZE, &nameentrysize); ++ PCRE_INFO_NAMEENTRYSIZE, &nameentrysize); + pcre_fullinfo((const pcre *)preg->re_pcre, NULL, +- PCRE_INFO_NAMETABLE, &nametable); +- ++ PCRE_INFO_NAMETABLE, &nametable); ++#endif + for (i = 0; i < namecount; i++) { + const char *offset = nametable + i * nameentrysize; + int capture = ((offset[0] << 8) + offset[1]); +-- +1.8.3.1 + diff --git a/httpd.spec b/httpd.spec index 9b977a0..1eee8fd 100644 --- a/httpd.spec +++ b/httpd.spec @@ -8,7 +8,7 @@ Name: httpd Summary: Apache HTTP Server Version: 2.4.51 -Release: 5 +Release: 6 License: ASL 2.0 URL: https://httpd.apache.org/ Source0: https://archive.apache.org/dist/httpd/httpd-%{version}.tar.bz2 @@ -77,10 +77,11 @@ Patch23: backport-002-CVE-2022-23934.patch Patch24: backport-CVE-2021-44790.patch Patch25: backport-001-CVE-2021-44224.patch Patch26: backport-002-CVE-2021-44224.patch +Patch27: backport-Switch-from-PCRE-to-PCRE2.patch BuildRequires: gcc autoconf pkgconfig findutils xmlto perl-interpreter perl-generators systemd-devel BuildRequires: zlib-devel libselinux-devel lua-devel brotli-devel -BuildRequires: apr-devel >= 1.5.0 apr-util-devel >= 1.5.0 pcre-devel >= 5.0 +BuildRequires: apr-devel >= 1.5.0 apr-util-devel >= 1.5.0 pcre2-devel Requires: mailcap system-logos mod_http2 Requires: httpd-tools = %{version}-%{release} httpd-filesystem = %{version}-%{release} Requires(pre): httpd-filesystem @@ -213,7 +214,7 @@ export LYNX_PATH=/usr/bin/links --enable-suexec --with-suexec --enable-suexec-capabilities \ --with-suexec-caller=%{suexec_caller} --with-suexec-docroot=%{docroot} \ --without-suexec-logfile --with-suexec-syslog \ - --with-suexec-bin=%{_sbindir}/suexec --with-brotli --enable-pie --with-pcre \ + --with-suexec-bin=%{_sbindir}/suexec --with-brotli --enable-pie --with-pcre2 \ --with-suexec-uidmin=1000 --with-suexec-gidmin=1000 \ --enable-mods-shared=all --enable-ssl --with-ssl --disable-distcache \ --enable-proxy --enable-proxy-fdpass --enable-cache --enable-disk-cache \ @@ -509,6 +510,12 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Mon May 30 2022 chengyechun - 2.4.51-6 +- Type:bugfix +- ID:NA +- SUG:restart +- DESC:switch from PCRE to PCRE2 + * Fri Mar 18 2022 gaihuiying - 2.4.51-5 - Type:cves - ID:NA -- Gitee