diff options
31 files changed, 3676 insertions, 161 deletions
@@ -1,17 +1,16 @@ -===== 7.3.8 (2019-08-01) +===== 7.3.33-13 (2024-04-11) -$ grep -ar 'Tests failed' /var/lib/mock/scl73*/build.log +$ grep -ar 'Tests failed' /var/lib/mock/*/build.log -/var/lib/mock/scl73el6x/build.log:Tests failed : 0 -/var/lib/mock/scl73el7x/build.log:Tests failed : 0 -/var/lib/mock/scl73el8x/build.log:Tests failed : 13 -/var/lib/mock/scl73fc28x/build.log:Tests failed : 0 -/var/lib/mock/scl73fc29x/build.log:Tests failed : 0 -/var/lib/mock/scl73fc30x/build.log:Tests failed : 0 +/var/lib/mock/scl73el7x/build.log:Tests failed : 2 +/var/lib/mock/scl73el8x/build.log:Tests failed : 15 -el8x - 5 buildroot issue (openssl) +el7x: + 5 ext/openssl/tests/openssl_x509_checkpurpose_basic.phpt + 3 Zend/tests/bug74093.phpt +el8x: + 2 buildroot issue with strict openssl policy (fixed in 7.4) (1) proc_open give erratic test results :( @@ -14,3 +14,7 @@ %@SCL@__php @BINDIR@/php +%@SCL@__phpize @BINDIR@/phpize + +%@SCL@__phpconfig @BINDIR@/php-config + diff --git a/php-5.6.3-embed.patch b/php-5.6.3-embed.patch index d9c04f6..38eea1d 100644 --- a/php-5.6.3-embed.patch +++ b/php-5.6.3-embed.patch @@ -18,7 +18,7 @@ diff -up php-5.5.30/scripts/php-config.in.old php-5.5.30/scripts/php-config.in php_cgi_binary=NONE configure_options="@CONFIGURE_OPTIONS@" -php_sapis="@PHP_INSTALLED_SAPIS@" -+php_sapis="apache2handler embed fpm @PHP_INSTALLED_SAPIS@" ++php_sapis="apache2handler embed fpm phpdbg @PHP_INSTALLED_SAPIS@" # Set php_cli_binary and php_cgi_binary if available for sapi in $php_sapis; do diff --git a/php-5.6.3-phpinfo.patch b/php-5.6.3-phpinfo.patch deleted file mode 100644 index 086be15..0000000 --- a/php-5.6.3-phpinfo.patch +++ /dev/null @@ -1,29 +0,0 @@ - -Drop "Configure Command" from phpinfo as it doesn't -provide any useful information. -The available extensions are not related to this command. - -diff -up php-7.0.0RC1/ext/standard/info.c.phpinfo php-7.0.0RC1/ext/standard/info.c ---- php-7.0.0RC1/ext/standard/info.c.phpinfo 2015-08-18 23:39:24.000000000 +0200 -+++ php-7.0.0RC1/ext/standard/info.c 2015-08-22 07:56:18.344761928 +0200 -@@ -870,9 +870,6 @@ PHPAPI void php_print_info(int flag) - #ifdef ARCHITECTURE - php_info_print_table_row(2, "Architecture", ARCHITECTURE); - #endif --#ifdef CONFIGURE_COMMAND -- php_info_print_table_row(2, "Configure Command", CONFIGURE_COMMAND ); --#endif - - if (sapi_module.pretty_name) { - php_info_print_table_row(2, "Server API", sapi_module.pretty_name ); -diff -up php-7.0.0RC1/ext/standard/tests/general_functions/phpinfo.phpt.phpinfo php-7.0.0RC1/ext/standard/tests/general_functions/phpinfo.phpt ---- php-7.0.0RC1/ext/standard/tests/general_functions/phpinfo.phpt.phpinfo 2015-08-18 23:39:22.000000000 +0200 -+++ php-7.0.0RC1/ext/standard/tests/general_functions/phpinfo.phpt 2015-08-22 07:56:18.344761928 +0200 -@@ -20,7 +20,6 @@ PHP Version => %s - - System => %s - Build Date => %s%a --Configure Command => %s - Server API => Command Line Interface - Virtual Directory Support => %s - Configuration File (php.ini) Path => %s diff --git a/php-7.2.0-oci8conf.patch b/php-7.2.0-oci8conf.patch index 0ad16a1..d026575 100644 --- a/php-7.2.0-oci8conf.patch +++ b/php-7.2.0-oci8conf.patch @@ -10,26 +10,4 @@ diff -up ./ext/ldap/php_ldap.h.remi-oci8 ./ext/ldap/php_ldap.h extern zend_module_entry ldap_module_entry; #define ldap_module_ptr &ldap_module_entry -diff -up ./ext/oci8/config.m4.remi-oci8 ./ext/oci8/config.m4 ---- ./ext/oci8/config.m4.remi-oci8 2017-06-20 15:45:39.000000000 +0200 -+++ ./ext/oci8/config.m4 2017-06-20 16:55:01.640203868 +0200 -@@ -372,6 +372,7 @@ if test "$PHP_OCI8" != "no"; then - - dnl Header directory for Instant Client SDK RPM install - OCISDKRPMINC=`echo "$PHP_OCI8_INSTANT_CLIENT" | $PHP_OCI8_SED -e 's!^/usr/lib/oracle/\(.*\)/client\('${PHP_OCI8_IC_LIBDIR_SUFFIX}'\)*/lib[/]*$!/usr/include/oracle/\1/client\2!'` -+ OCISDKRPMINC=`echo "$PHP_OCI8_INSTANT_CLIENT" | $PHP_OCI8_SED -e 's!^/usr/\(lib64\|lib\)/oracle/\(.*\)/\(client64\|client\)/lib[/]*$!/usr/include/oracle/\2/\3!'` - - dnl Header directory for Instant Client SDK zip file install - OCISDKZIPINC=$PHP_OCI8_INSTANT_CLIENT/sdk/include -diff -up ./ext/pdo_oci/config.m4.remi-oci8 ./ext/pdo_oci/config.m4 ---- ./ext/pdo_oci/config.m4.remi-oci8 2017-06-20 16:55:01.640203868 +0200 -+++ ./ext/pdo_oci/config.m4 2017-06-20 17:16:03.053538358 +0200 -@@ -93,7 +93,7 @@ if test "$PHP_PDO_OCI" != "no"; then - - AC_MSG_CHECKING([for oci.h]) - dnl Header directory for Instant Client SDK RPM install -- OCISDKRPMINC=`echo "$PDO_OCI_LIB_DIR" | $PHP_PDO_OCI_SED -e 's!^\(.*\)/lib/oracle/\(.*\)/\('${PDO_OCI_CLIENT_DIR}'\)/lib[/]*$!\1/include/oracle/\2/\3!'` -+ OCISDKRPMINC=`echo "$PDO_OCI_LIB_DIR" | $PHP_PDO_OCI_SED -e 's!^\(.*\)/\(lib64\|lib\)/oracle/\(.*\)/\('${PDO_OCI_CLIENT_DIR}'\)/lib[/]*$!\1/include/oracle/\3/\4!'` - - dnl Header directory for manual installation - OCISDKMANINC=`echo "$PDO_OCI_LIB_DIR" | $PHP_PDO_OCI_SED -e 's!^\(.*\)/lib[/]*$!\1/include!'` + diff --git a/php-7.2.4-fixheader.patch b/php-7.2.4-fixheader.patch deleted file mode 100644 index 52a4121..0000000 --- a/php-7.2.4-fixheader.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up php-7.2.4RC1/configure.ac.fixheader php-7.2.4RC1/configure.ac ---- php-7.2.4RC1/configure.ac.fixheader 2018-03-13 12:42:47.594623100 +0100 -+++ php-7.2.4RC1/configure.ac 2018-03-13 12:43:35.591871825 +0100 -@@ -1275,7 +1275,7 @@ PHP_BUILD_DATE=`date -u +%Y-%m-%d` - fi - AC_DEFINE_UNQUOTED(PHP_BUILD_DATE,"$PHP_BUILD_DATE",[PHP build date]) - --PHP_UNAME=`uname -a | xargs` -+PHP_UNAME=`uname | xargs` - AC_DEFINE_UNQUOTED(PHP_UNAME,"$PHP_UNAME",[uname -a output]) - PHP_OS=`uname | xargs` - AC_DEFINE_UNQUOTED(PHP_OS,"$PHP_OS",[uname output]) diff --git a/php-7.3.20-fixheader.patch b/php-7.3.20-fixheader.patch new file mode 100644 index 0000000..6bbdfbd --- /dev/null +++ b/php-7.3.20-fixheader.patch @@ -0,0 +1,13 @@ +diff -up ./configure.ac.fixheader ./configure.ac +--- ./configure.ac.fixheader 2020-07-06 16:04:56.069183751 +0200 ++++ ./configure.ac 2020-07-06 16:05:52.044046238 +0200 +@@ -1350,7 +1350,8 @@ PHP_BUILD_DATE=`date -u +%Y-%m-%d` + fi + AC_DEFINE_UNQUOTED(PHP_BUILD_DATE,"$PHP_BUILD_DATE",[PHP build date]) + +-PHP_UNAME=`uname -a | xargs` ++UNAME=`uname -a | xargs` ++PHP_UNAME=${PHP_UNAME:-$UNAME} + AC_DEFINE_UNQUOTED(PHP_UNAME,"$PHP_UNAME",[uname -a output]) + PHP_OS=`uname | xargs` + AC_DEFINE_UNQUOTED(PHP_OS,"$PHP_OS",[uname output]) diff --git a/php-7.3.20-phpinfo.patch b/php-7.3.20-phpinfo.patch new file mode 100644 index 0000000..8118732 --- /dev/null +++ b/php-7.3.20-phpinfo.patch @@ -0,0 +1,76 @@ + +Drop "Configure Command" from phpinfo as it doesn't +provide any useful information. +The available extensions are not related to this command. + +diff -up a/ext/standard/info.c.phpinfo v/ext/standard/info.c +--- a/ext/standard/info.c.phpinfo 2015-08-18 23:39:24.000000000 +0200 ++++ b/ext/standard/info.c 2015-08-22 07:56:18.344761928 +0200 +@@ -829,9 +829,6 @@ PHPAPI void php_print_info(int flag) + #ifdef ARCHITECTURE + php_info_print_table_row(2, "Architecture", ARCHITECTURE); + #endif +-#ifdef CONFIGURE_COMMAND +- php_info_print_table_row(2, "Configure Command", CONFIGURE_COMMAND ); +-#endif + + if (sapi_module.pretty_name) { + php_info_print_table_row(2, "Server API", sapi_module.pretty_name ); +diff -up a/ext/standard/tests/general_functions/phpinfo.phpt.phpinfo b/ext/standard/tests/general_functions/phpinfo.phpt +--- a/ext/standard/tests/general_functions/phpinfo.phpt.phpinfo 2015-08-18 23:39:22.000000000 +0200 ++++ b/ext/standard/tests/general_functions/phpinfo.phpt 2015-08-22 07:56:18.344761928 +0200 +@@ -20,7 +20,6 @@ PHP Version => %s + + System => %s + Build Date => %s%a +-Configure Command => %s + Server API => Command Line Interface + Virtual Directory Support => %s + Configuration File (php.ini) Path => %s + + +Backported from 8.0: + +From ad0d2e438fddc089917e71e5d8909d145db9da8a Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Fri, 3 Jul 2020 10:08:09 +0200 +Subject: [PATCH] display info about system used to build and its provider + +--- + configure.ac | 5 +++++ + ext/standard/info.c | 6 ++++++ + 2 files changed, 11 insertions(+) + +diff --git a/configure.ac b/configure.ac +index d9e6329314a3..77f12a55569a 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1355,6 +1355,11 @@ PHP_UNAME=${PHP_UNAME:-$UNAME} + AC_DEFINE_UNQUOTED(PHP_UNAME,"$PHP_UNAME",[uname -a output]) + PHP_OS=`uname | xargs` + AC_DEFINE_UNQUOTED(PHP_OS,"$PHP_OS",[uname output]) ++PHP_BUILD_SYSTEM=${PHP_BUILD_SYSTEM:-$PHP_UNAME} ++AC_DEFINE_UNQUOTED(PHP_BUILD_SYSTEM,"$PHP_BUILD_SYSTEM",[builder uname output]) ++if test -n "${PHP_BUILD_PROVIDER}"; then ++ AC_DEFINE_UNQUOTED(PHP_BUILD_PROVIDER,"$PHP_BUILD_PROVIDER",[build provider]) ++fi + + PHP_SUBST_OLD(PHP_INSTALLED_SAPIS) + +diff --git a/ext/standard/info.c b/ext/standard/info.c +index 262e95ae2731..f652efd23657 100644 +--- a/ext/standard/info.c ++++ b/ext/standard/info.c +@@ -823,6 +823,12 @@ PHPAPI ZEND_COLD void php_print_info(int flag) + php_info_print_table_start(); + php_info_print_table_row(2, "System", ZSTR_VAL(php_uname)); + php_info_print_table_row(2, "Build Date", __DATE__ " " __TIME__); ++#ifdef PHP_BUILD_SYSTEM ++ php_info_print_table_row(2, "Build System", PHP_BUILD_SYSTEM); ++#endif ++#ifdef PHP_BUILD_PROVIDER ++ php_info_print_table_row(2, "Build Provider", PHP_BUILD_PROVIDER); ++#endif + #ifdef COMPILER + php_info_print_table_row(2, "Compiler", COMPILER); + #endif diff --git a/php-7.3.24-fpm.patch b/php-7.3.24-fpm.patch new file mode 100644 index 0000000..1165970 --- /dev/null +++ b/php-7.3.24-fpm.patch @@ -0,0 +1,219 @@ +Fix for https://bugs.php.net/74083 master PHP-fpm is stopped on multiple reloads +backported for 7.4 from + +From ae5154c6c6af7ba7c592f8af006b7cadd0d66d6e Mon Sep 17 00:00:00 2001 +From: Maksim Nikulin <mnikulin@plesk.com> +Date: Wed, 24 Jul 2019 16:50:57 +0700 +Subject: [PATCH] Block signals during fpm master initialization + +From e37bd5dcc2e8f269c6031d86429311c8cf243060 Mon Sep 17 00:00:00 2001 +From: Maksim Nikulin <mnikulin@plesk.com> +Date: Mon, 21 Oct 2019 14:23:29 +0700 +Subject: [PATCH] Do not let PHP-FPM children miss SIGTERM, SIGQUIT + + +diff -up ./sapi/fpm/fpm/fpm_children.c.fpmsig ./sapi/fpm/fpm/fpm_children.c +--- ./sapi/fpm/fpm/fpm_children.c.fpmsig 2020-10-23 10:36:31.423925856 +0200 ++++ ./sapi/fpm/fpm/fpm_children.c 2020-10-23 10:36:38.872900642 +0200 +@@ -404,6 +404,11 @@ int fpm_children_make(struct fpm_worker_ + return 2; + } + ++ zlog(ZLOG_DEBUG, "blocking signals before child birth"); ++ if (0 > fpm_signals_child_block()) { ++ zlog(ZLOG_WARNING, "child may miss signals"); ++ } ++ + pid = fork(); + + switch (pid) { +@@ -415,12 +420,16 @@ int fpm_children_make(struct fpm_worker_ + return 0; + + case -1 : ++ zlog(ZLOG_DEBUG, "unblocking signals"); ++ fpm_signals_unblock(); + zlog(ZLOG_SYSERROR, "fork() failed"); + + fpm_resources_discard(child); + return 2; + + default : ++ zlog(ZLOG_DEBUG, "unblocking signals, child born"); ++ fpm_signals_unblock(); + child->pid = pid; + fpm_clock_get(&child->started); + fpm_parent_resources_use(child); +diff -up ./sapi/fpm/fpm/fpm_main.c.fpmsig ./sapi/fpm/fpm/fpm_main.c +--- ./sapi/fpm/fpm/fpm_main.c.fpmsig 2020-10-13 11:27:02.000000000 +0200 ++++ ./sapi/fpm/fpm/fpm_main.c 2020-10-23 10:36:38.873900639 +0200 +@@ -90,6 +90,7 @@ int __riscosify_control = __RISCOSIFY_ST + #include "fpm.h" + #include "fpm_request.h" + #include "fpm_status.h" ++#include "fpm_signals.h" + #include "fpm_conf.h" + #include "fpm_php.h" + #include "fpm_log.h" +@@ -1584,6 +1585,11 @@ int main(int argc, char *argv[]) + closes it. in apache|apxs mode apache + does that for us! thies@thieso.net + 20000419 */ ++ ++ if (0 > fpm_signals_init_mask() || 0 > fpm_signals_block()) { ++ zlog(ZLOG_WARNING, "Could die in the case of too early reload signal"); ++ } ++ zlog(ZLOG_DEBUG, "Blocked some signals"); + #endif + #endif + +diff -up ./sapi/fpm/fpm/fpm_process_ctl.c.fpmsig ./sapi/fpm/fpm/fpm_process_ctl.c +--- ./sapi/fpm/fpm/fpm_process_ctl.c.fpmsig 2020-10-13 11:27:02.000000000 +0200 ++++ ./sapi/fpm/fpm/fpm_process_ctl.c 2020-10-23 10:36:11.921991864 +0200 +@@ -77,6 +77,10 @@ static void fpm_pctl_exit() /* {{{ */ + + static void fpm_pctl_exec() /* {{{ */ + { ++ zlog(ZLOG_DEBUG, "Blocking some signals before reexec"); ++ if (0 > fpm_signals_block()) { ++ zlog(ZLOG_WARNING, "concurrent reloads may be unstable"); ++ } + + zlog(ZLOG_NOTICE, "reloading: execvp(\"%s\", {\"%s\"" + "%s%s%s" "%s%s%s" "%s%s%s" "%s%s%s" "%s%s%s" +diff -up ./sapi/fpm/fpm/fpm_signals.c.fpmsig ./sapi/fpm/fpm/fpm_signals.c +--- ./sapi/fpm/fpm/fpm_signals.c.fpmsig 2020-10-13 11:27:02.000000000 +0200 ++++ ./sapi/fpm/fpm/fpm_signals.c 2020-10-23 10:36:38.873900639 +0200 +@@ -19,6 +19,8 @@ + #include "zlog.h" + + static int sp[2]; ++static sigset_t block_sigset; ++static sigset_t child_block_sigset; + + const char *fpm_signal_names[NSIG + 1] = { + #ifdef SIGHUP +@@ -165,8 +167,11 @@ static void sig_handler(int signo) /* {{ + int saved_errno; + + if (fpm_globals.parent_pid != getpid()) { +- /* prevent a signal race condition when child process +- have not set up it's own signal handler yet */ ++ /* Avoid using of signal handlers from the master process in a worker ++ before the child sets up its own signal handlers. ++ Normally it is prevented by the sigprocmask() calls ++ around fork(). This execution branch is a last resort trap ++ that has no protection against #76601. */ + return; + } + +@@ -210,6 +215,11 @@ int fpm_signals_init_main() /* {{{ */ + zlog(ZLOG_SYSERROR, "failed to init signals: sigaction()"); + return -1; + } ++ ++ zlog(ZLOG_DEBUG, "Unblocking all signals"); ++ if (0 > fpm_signals_unblock()) { ++ return -1; ++ } + return 0; + } + /* }}} */ +@@ -241,6 +251,10 @@ int fpm_signals_init_child() /* {{{ */ + } + + zend_signal_init(); ++ ++ if (0 > fpm_signals_unblock()) { ++ return -1; ++ } + return 0; + } + /* }}} */ +@@ -250,3 +264,72 @@ int fpm_signals_get_fd() /* {{{ */ + return sp[0]; + } + /* }}} */ ++ ++int fpm_signals_init_mask() /* {{{ */ ++{ ++ /* Subset of signals from fpm_signals_init_main() and fpm_got_signal() ++ blocked to avoid unexpected death during early init ++ or during reload just after execvp() or fork */ ++ int init_signal_array[] = { SIGUSR1, SIGUSR2, SIGCHLD }; ++ size_t size = sizeof(init_signal_array)/sizeof(init_signal_array[0]); ++ size_t i = 0; ++ if (0 > sigemptyset(&block_sigset) || ++ 0 > sigemptyset(&child_block_sigset)) { ++ zlog(ZLOG_SYSERROR, "failed to prepare signal block mask: sigemptyset()"); ++ return -1; ++ } ++ for (i = 0; i < size; ++i) { ++ int sig_i = init_signal_array[i]; ++ if (0 > sigaddset(&block_sigset, sig_i) || ++ 0 > sigaddset(&child_block_sigset, sig_i)) { ++ if (sig_i <= NSIG && fpm_signal_names[sig_i] != NULL) { ++ zlog(ZLOG_SYSERROR, "failed to prepare signal block mask: sigaddset(%s)", ++ fpm_signal_names[sig_i]); ++ } else { ++ zlog(ZLOG_SYSERROR, "failed to prepare signal block mask: sigaddset(%d)", sig_i); ++ } ++ return -1; ++ } ++ } ++ if (0 > sigaddset(&child_block_sigset, SIGTERM) || ++ 0 > sigaddset(&child_block_sigset, SIGQUIT)) { ++ zlog(ZLOG_SYSERROR, "failed to prepare child signal block mask: sigaddset()"); ++ return -1; ++ } ++ return 0; ++} ++/* }}} */ ++ ++int fpm_signals_block() /* {{{ */ ++{ ++ if (0 > sigprocmask(SIG_BLOCK, &block_sigset, NULL)) { ++ zlog(ZLOG_SYSERROR, "failed to block signals"); ++ return -1; ++ } ++ return 0; ++} ++/* }}} */ ++ ++int fpm_signals_child_block() /* {{{ */ ++{ ++ if (0 > sigprocmask(SIG_BLOCK, &child_block_sigset, NULL)) { ++ zlog(ZLOG_SYSERROR, "failed to block child signals"); ++ return -1; ++ } ++ return 0; ++} ++/* }}} */ ++ ++int fpm_signals_unblock() /* {{{ */ ++{ ++ /* Ensure that during reload after upgrade all signals are unblocked. ++ block_sigset could have different value before execve() */ ++ sigset_t all_signals; ++ sigfillset(&all_signals); ++ if (0 > sigprocmask(SIG_UNBLOCK, &all_signals, NULL)) { ++ zlog(ZLOG_SYSERROR, "failed to unblock signals"); ++ return -1; ++ } ++ return 0; ++} ++/* }}} */ +diff -up ./sapi/fpm/fpm/fpm_signals.h.fpmsig ./sapi/fpm/fpm/fpm_signals.h +--- ./sapi/fpm/fpm/fpm_signals.h.fpmsig 2020-10-13 11:27:02.000000000 +0200 ++++ ./sapi/fpm/fpm/fpm_signals.h 2020-10-23 10:36:38.873900639 +0200 +@@ -8,6 +8,10 @@ + int fpm_signals_init_main(); + int fpm_signals_init_child(); + int fpm_signals_get_fd(); ++int fpm_signals_init_mask(); ++int fpm_signals_block(); ++int fpm_signals_child_block(); ++int fpm_signals_unblock(); + + extern const char *fpm_signal_names[NSIG + 1]; + diff --git a/php-7.3.3-systzdata-v18.patch b/php-7.3.3-systzdata-v19.patch index eac3cc3..17a01fe 100644 --- a/php-7.3.3-systzdata-v18.patch +++ b/php-7.3.3-systzdata-v19.patch @@ -5,6 +5,7 @@ Add support for use of the system timezone database, rather than embedding a copy. Discussed upstream but was not desired. History: +r19: retrieve tzdata version from /usr/share/zoneinfo/tzdata.zi r18: adapt for autotool change in 7.3.3RC1 r17: adapt for timelib 2018.01 (in 7.3.2RC1) r16: adapt for timelib 2017.06 (in 7.2.3RC1) @@ -29,10 +30,11 @@ r3: fix a crash if /usr/share/zoneinfo doesn't exist (Raphael Geissert) r2: add filesystem trawl to set up name alias index r1: initial revision -diff -up php-7.3.3RC1/ext/date/config0.m4.systzdata php-7.3.3RC1/ext/date/config0.m4 ---- php-7.3.3RC1/ext/date/config0.m4.systzdata 2019-02-19 14:57:51.314601701 +0100 -+++ php-7.3.3RC1/ext/date/config0.m4 2019-02-19 14:58:29.050812587 +0100 -@@ -9,6 +9,19 @@ io.h +diff --git a/ext/date/config0.m4 b/ext/date/config0.m4 +index 20e4164aaa..a61243646d 100644 +--- a/ext/date/config0.m4 ++++ b/ext/date/config0.m4 +@@ -4,6 +4,19 @@ AC_CHECK_HEADERS([io.h]) dnl Check for strtoll, atoll AC_CHECK_FUNCS(strtoll atoll) @@ -52,10 +54,11 @@ diff -up php-7.3.3RC1/ext/date/config0.m4.systzdata php-7.3.3RC1/ext/date/config PHP_DATE_CFLAGS="-I@ext_builddir@/lib -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 -DHAVE_TIMELIB_CONFIG_H=1" timelib_sources="lib/astro.c lib/dow.c lib/parse_date.c lib/parse_tz.c lib/timelib.c lib/tm2unixtime.c lib/unixtime2tm.c lib/parse_iso_intervals.c lib/interval.c" -diff -up php-7.3.3RC1/ext/date/lib/parse_tz.c.systzdata php-7.3.3RC1/ext/date/lib/parse_tz.c ---- php-7.3.3RC1/ext/date/lib/parse_tz.c.systzdata 2019-02-19 12:18:27.000000000 +0100 -+++ php-7.3.3RC1/ext/date/lib/parse_tz.c 2019-02-19 14:57:20.397428931 +0100 -@@ -25,8 +25,21 @@ +diff --git a/ext/date/lib/parse_tz.c b/ext/date/lib/parse_tz.c +index 020da3135e..12e68ef043 100644 +--- a/ext/date/lib/parse_tz.c ++++ b/ext/date/lib/parse_tz.c +@@ -26,8 +26,21 @@ #include "timelib.h" #include "timelib_private.h" @@ -77,7 +80,7 @@ diff -up php-7.3.3RC1/ext/date/lib/parse_tz.c.systzdata php-7.3.3RC1/ext/date/li #if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)) # if defined(__LITTLE_ENDIAN__) -@@ -87,6 +100,11 @@ static int read_php_preamble(const unsig +@@ -88,6 +101,11 @@ static int read_php_preamble(const unsigned char **tzf, timelib_tzinfo *tz) { uint32_t version; @@ -89,7 +92,7 @@ diff -up php-7.3.3RC1/ext/date/lib/parse_tz.c.systzdata php-7.3.3RC1/ext/date/li /* read ID */ version = (*tzf)[3] - '0'; *tzf += 4; -@@ -411,7 +429,429 @@ void timelib_dump_tzinfo(timelib_tzinfo +@@ -412,7 +430,467 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz) } } @@ -320,6 +323,44 @@ diff -up php-7.3.3RC1/ext/date/lib/parse_tz.c.systzdata php-7.3.3RC1/ext/date/li +} + + ++/* Retrieve tzdata version. */ ++static void retrieve_zone_version(timelib_tzdb *db) ++{ ++ static char buf[30]; ++ char path[PATH_MAX]; ++ FILE *fp; ++ ++ strncpy(path, ZONEINFO_PREFIX "/tzdata.zi", sizeof(path)); ++ ++ fp = fopen(path, "r"); ++ if (fp) { ++ if (fgets(buf, sizeof(buf), fp)) { ++ if (!memcmp(buf, "# version ", 10) && ++ isdigit(buf[10]) && ++ isdigit(buf[11]) && ++ isdigit(buf[12]) && ++ isdigit(buf[13]) && ++ islower(buf[14])) { ++ if (buf[14] >= 't') { /* 2022t = 2022.20 */ ++ buf[17] = 0; ++ buf[16] = buf[14] - 't' + '0'; ++ buf[15] = '2'; ++ } else if (buf[14] >= 'j') { /* 2022j = 2022.10 */ ++ buf[17] = 0; ++ buf[16] = buf[14] - 'j' + '0'; ++ buf[15] = '1'; ++ } else { /* 2022a = 2022.1 */ ++ buf[16] = 0; ++ buf[15] = buf[14] - 'a' + '1'; ++ } ++ buf[14] = '.'; ++ db->version = buf+10; ++ } ++ } ++ fclose(fp); ++ } ++} ++ +/* Create the zone identifier index by trawling the filesystem. */ +static void create_zone_index(timelib_tzdb *db) +{ @@ -411,7 +452,7 @@ diff -up php-7.3.3RC1/ext/date/lib/parse_tz.c.systzdata php-7.3.3RC1/ext/date/li + size_t n; + char *data, *p; + -+ data = malloc(3 * sysdb->index_size + 7); ++ data = malloc(3 * sysdb->index_size + sizeof(FAKE_HEADER) - 1); + + p = mempcpy(data, FAKE_HEADER, sizeof(FAKE_HEADER) - 1); + @@ -520,7 +561,7 @@ diff -up php-7.3.3RC1/ext/date/lib/parse_tz.c.systzdata php-7.3.3RC1/ext/date/li { int left = 0, right = tzdb->index_size - 1; -@@ -437,9 +877,48 @@ static int seek_to_tz_position(const uns +@@ -438,9 +916,49 @@ static int seek_to_tz_position(const unsigned char **tzf, char *timezone, const return 0; } @@ -557,6 +598,7 @@ diff -up php-7.3.3RC1/ext/date/lib/parse_tz.c.systzdata php-7.3.3RC1/ext/date/li + tmp->version = "0.system"; + tmp->data = NULL; + create_zone_index(tmp); ++ retrieve_zone_version(tmp); + system_location_table = create_location_table(); + fake_data_segment(tmp, system_location_table); + timezonedb_system = tmp; @@ -569,7 +611,7 @@ diff -up php-7.3.3RC1/ext/date/lib/parse_tz.c.systzdata php-7.3.3RC1/ext/date/li } const timelib_tzdb_index_entry *timelib_timezone_identifiers_list(const timelib_tzdb *tzdb, int *count) -@@ -451,7 +930,30 @@ const timelib_tzdb_index_entry *timelib_ +@@ -452,7 +970,30 @@ const timelib_tzdb_index_entry *timelib_timezone_identifiers_list(const timelib_ int timelib_timezone_id_is_valid(char *timezone, const timelib_tzdb *tzdb) { const unsigned char *tzf; @@ -601,7 +643,7 @@ diff -up php-7.3.3RC1/ext/date/lib/parse_tz.c.systzdata php-7.3.3RC1/ext/date/li } static int skip_64bit_preamble(const unsigned char **tzf, timelib_tzinfo *tz) -@@ -493,12 +995,14 @@ static timelib_tzinfo* timelib_tzinfo_ct +@@ -494,12 +1035,14 @@ static timelib_tzinfo* timelib_tzinfo_ctor(char *name) timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb, int *error_code) { const unsigned char *tzf; @@ -617,7 +659,7 @@ diff -up php-7.3.3RC1/ext/date/lib/parse_tz.c.systzdata php-7.3.3RC1/ext/date/li tmp = timelib_tzinfo_ctor(timezone); version = read_preamble(&tzf, tmp, &type); -@@ -537,11 +1041,36 @@ timelib_tzinfo *timelib_parse_tzfile(cha +@@ -534,11 +1077,36 @@ timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb, i } skip_posix_string(&tzf, tmp); @@ -654,3 +696,19 @@ diff -up php-7.3.3RC1/ext/date/lib/parse_tz.c.systzdata php-7.3.3RC1/ext/date/li } else { *error_code = TIMELIB_ERROR_NO_SUCH_TIMEZONE; tmp = NULL; +diff --git a/ext/date/php_date.c b/ext/date/php_date.c +index e1a427c5ca..465906fa2b 100644 +--- a/ext/date/php_date.c ++++ b/ext/date/php_date.c +@@ -951,7 +951,11 @@ PHP_MINFO_FUNCTION(date) + php_info_print_table_row(2, "date/time support", "enabled"); + php_info_print_table_row(2, "timelib version", TIMELIB_ASCII_VERSION); + php_info_print_table_row(2, "\"Olson\" Timezone Database Version", tzdb->version); ++#ifdef HAVE_SYSTEM_TZDATA ++ php_info_print_table_row(2, "Timezone Database", "system"); ++#else + php_info_print_table_row(2, "Timezone Database", php_date_global_timezone_db_enabled ? "external" : "internal"); ++#endif + php_info_print_table_row(2, "Default timezone", guess_timezone(tzdb)); + php_info_print_table_end(); + diff --git a/php-bug80682.patch b/php-bug80682.patch new file mode 100644 index 0000000..38f908b --- /dev/null +++ b/php-bug80682.patch @@ -0,0 +1,30 @@ +From 067f7e4150d8f9bddf6b198c9c7826565ee549b0 Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@php.net> +Date: Thu, 28 Jan 2021 16:24:39 +0100 +Subject: [PATCH] Fix #80682 opcache doesn't honour pcre.jit option + +--- + ext/opcache/zend_accelerator_blacklist.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/ext/opcache/zend_accelerator_blacklist.c b/ext/opcache/zend_accelerator_blacklist.c +index 889fcabd7988..5c6bd76821a5 100644 +--- a/ext/opcache/zend_accelerator_blacklist.c ++++ b/ext/opcache/zend_accelerator_blacklist.c +@@ -185,10 +185,12 @@ static void zend_accel_blacklist_update_regexp(zend_blacklist *blacklist) + return; + } + #ifdef HAVE_PCRE_JIT_SUPPORT +- if (0 > pcre2_jit_compile(it->re, PCRE2_JIT_COMPLETE)) { +- /* Don't return here, even JIT could fail to compile, the pattern is still usable. */ +- pcre2_get_error_message(errnumber, pcre_error, sizeof(pcre_error)); +- zend_accel_error(ACCEL_LOG_WARNING, "Blacklist JIT compilation failed, %s\n", pcre_error); ++ if (PCRE_G(jit)) { ++ if (0 > pcre2_jit_compile(it->re, PCRE2_JIT_COMPLETE)) { ++ /* Don't return here, even JIT could fail to compile, the pattern is still usable. */ ++ pcre2_get_error_message(errnumber, pcre_error, sizeof(pcre_error)); ++ zend_accel_error(ACCEL_LOG_WARNING, "Blacklist JIT compilation failed, %s\n", pcre_error); ++ } + } + #endif + /* prepare for the next iteration */ diff --git a/php-bug80783.patch b/php-bug80783.patch new file mode 100644 index 0000000..2da9928 --- /dev/null +++ b/php-bug80783.patch @@ -0,0 +1,185 @@ +From bccca0b53aa60a62e2988c750fc73c02d109e642 Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" <cmbecker69@gmx.de> +Date: Thu, 25 Feb 2021 14:38:42 +0100 +Subject: [PATCH] Fix #80783: PDO ODBC truncates BLOB records at every 256th + byte + +It is not guaranteed, that the driver inserts only a single NUL byte at +the end of the buffer. Apparently, there is no way to find out the +actual data length in the buffer after calling `SQLGetData()`, so we +adjust after the next `SQLGetData()` call. + +We also prevent PDO::ODBC_ATTR_ASSUME_UTF8 from fetching garbage, by +fetching all chunks with the same C type. + +Closes GH-6716. +--- + NEWS | 4 ++++ + ext/pdo_odbc/odbc_stmt.c | 14 +++++++++++-- + ext/pdo_odbc/tests/bug80783.phpt | 32 ++++++++++++++++++++++++++++++ + ext/pdo_odbc/tests/bug80783a.phpt | 33 +++++++++++++++++++++++++++++++ + 4 files changed, 81 insertions(+), 2 deletions(-) + create mode 100644 ext/pdo_odbc/tests/bug80783.phpt + create mode 100644 ext/pdo_odbc/tests/bug80783a.phpt + +diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c +index 18abc475b9eb..7ce0bebdca0d 100644 +--- a/ext/pdo_odbc/odbc_stmt.c ++++ b/ext/pdo_odbc/odbc_stmt.c +@@ -652,6 +652,7 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong + + /* if it is a column containing "long" data, perform late binding now */ + if (C->is_long) { ++ SQLLEN orig_fetched_len = SQL_NULL_DATA; + zend_ulong used = 0; + char *buf; + RETCODE rc; +@@ -662,6 +663,7 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong + + rc = SQLGetData(S->stmt, colno+1, C->is_unicode ? SQL_C_BINARY : SQL_C_CHAR, C->data, + 256, &C->fetched_len); ++ orig_fetched_len = C->fetched_len; + + if (rc == SQL_SUCCESS) { + /* all the data fit into our little buffer; +@@ -673,7 +675,8 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong + /* this is a 'long column' + + read the column in 255 byte blocks until the end of the column is reached, reassembling those blocks +- in order into the output buffer ++ in order into the output buffer; 255 bytes are an optimistic assumption, since the driver may assert ++ more or less NUL bytes at the end; we cater to that later, if actual length information is available + + this loop has to work whether or not SQLGetData() provides the total column length. + calling SQLDescribeCol() or other, specifically to get the column length, then doing a single read +@@ -687,7 +690,14 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong + do { + C->fetched_len = 0; + /* read block. 256 bytes => 255 bytes are actually read, the last 1 is NULL */ +- rc = SQLGetData(S->stmt, colno+1, SQL_C_CHAR, buf2, 256, &C->fetched_len); ++ rc = SQLGetData(S->stmt, colno+1, C->is_unicode ? SQL_C_BINARY : SQL_C_CHAR, buf2, 256, &C->fetched_len); ++ ++ /* adjust `used` in case we have length info from the driver */ ++ if (orig_fetched_len >= 0 && C->fetched_len >= 0) { ++ SQLLEN fixed_used = orig_fetched_len - C->fetched_len; ++ ZEND_ASSERT(fixed_used <= used + 1); ++ used = fixed_used; ++ } + + /* resize output buffer and reassemble block */ + if (rc==SQL_SUCCESS_WITH_INFO) { +diff --git a/ext/pdo_odbc/tests/bug80783.phpt b/ext/pdo_odbc/tests/bug80783.phpt +new file mode 100644 +index 000000000000..9794c25a30ec +--- /dev/null ++++ b/ext/pdo_odbc/tests/bug80783.phpt +@@ -0,0 +1,32 @@ ++--TEST-- ++Bug #80783 (PDO ODBC truncates BLOB records at every 256th byte) ++--SKIPIF-- ++<?php ++if (!extension_loaded('pdo_odbc')) die('skip pdo_odbc extension not available'); ++require 'ext/pdo/tests/pdo_test.inc'; ++PDOTest::skip(); ++?> ++--FILE-- ++<?php ++require 'ext/pdo/tests/pdo_test.inc'; ++$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt'); ++$db->exec("CREATE TABLE bug80783 (name IMAGE)"); ++ ++$string = str_repeat("0123456789", 50); ++$db->exec("INSERT INTO bug80783 VALUES('$string')"); ++ ++$stmt = $db->prepare("SELECT name FROM bug80783"); ++$stmt->bindColumn(1, $data, PDO::PARAM_LOB); ++$stmt->execute(); ++$stmt->fetch(PDO::FETCH_BOUND); ++ ++var_dump($data === bin2hex($string)); ++?> ++--CLEAN-- ++<?php ++require 'ext/pdo/tests/pdo_test.inc'; ++$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt'); ++$db->exec("DROP TABLE bug80783"); ++?> ++--EXPECT-- ++bool(true) +diff --git a/ext/pdo_odbc/tests/bug80783a.phpt b/ext/pdo_odbc/tests/bug80783a.phpt +new file mode 100644 +index 000000000000..f9e123ae5426 +--- /dev/null ++++ b/ext/pdo_odbc/tests/bug80783a.phpt +@@ -0,0 +1,33 @@ ++--TEST-- ++Bug #80783 (PDO ODBC truncates BLOB records at every 256th byte) ++--SKIPIF-- ++<?php ++if (!extension_loaded('pdo_odbc')) die('skip pdo_odbc extension not available'); ++require 'ext/pdo/tests/pdo_test.inc'; ++PDOTest::skip(); ++?> ++--FILE-- ++<?php ++require 'ext/pdo/tests/pdo_test.inc'; ++$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt'); ++$db->exec("CREATE TABLE bug80783a (name NVARCHAR(MAX))"); ++ ++$string = str_repeat("0123456789", 50); ++$db->exec("INSERT INTO bug80783a VALUES('$string')"); ++ ++$stmt = $db->prepare("SELECT name FROM bug80783a"); ++$stmt->setAttribute(PDO::ODBC_ATTR_ASSUME_UTF8, true); ++$stmt->bindColumn(1, $data, PDO::PARAM_STR); ++$stmt->execute(); ++$stmt->fetch(PDO::FETCH_BOUND); ++ ++var_dump($data === $string); ++?> ++--CLEAN-- ++<?php ++require 'ext/pdo/tests/pdo_test.inc'; ++$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt'); ++$db->exec("DROP TABLE bug80783a"); ++?> ++--EXPECT-- ++bool(true) +From 25f5a1b2e15344e75d69a7140631d467e8b3f966 Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Thu, 8 Apr 2021 11:04:33 +0200 +Subject: [PATCH] Improve fix for #80783 + +--- + ext/pdo_odbc/odbc_stmt.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c +index 7ce0bebdca0d..368648c36ae2 100644 +--- a/ext/pdo_odbc/odbc_stmt.c ++++ b/ext/pdo_odbc/odbc_stmt.c +@@ -665,13 +665,13 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong + 256, &C->fetched_len); + orig_fetched_len = C->fetched_len; + +- if (rc == SQL_SUCCESS) { ++ if (rc == SQL_SUCCESS && C->fetched_len < 256) { + /* all the data fit into our little buffer; + * jump down to the generic bound data case */ + goto in_data; + } + +- if (rc == SQL_SUCCESS_WITH_INFO) { ++ if (rc == SQL_SUCCESS_WITH_INFO || rc == SQL_SUCCESS) { + /* this is a 'long column' + + read the column in 255 byte blocks until the end of the column is reached, reassembling those blocks +@@ -700,7 +700,7 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, zend_ulong + } + + /* resize output buffer and reassemble block */ +- if (rc==SQL_SUCCESS_WITH_INFO) { ++ if (rc==SQL_SUCCESS_WITH_INFO || (rc==SQL_SUCCESS && C->fetched_len > 255)) { + /* point 5, in section "Retrieving Data with SQLGetData" in http://msdn.microsoft.com/en-us/library/windows/desktop/ms715441(v=vs.85).aspx + states that if SQL_SUCCESS_WITH_INFO, fetched_len will be > 255 (greater than buf2's size) + (if a driver fails to follow that and wrote less than 255 bytes to buf2, this will AV or read garbage into buf) */ diff --git a/php-bug81719.patch b/php-bug81719.patch new file mode 100644 index 0000000..c40e1ba --- /dev/null +++ b/php-bug81719.patch @@ -0,0 +1,60 @@ +From 9433de72e291db518357fe55531cc15432d43ec4 Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <smalyshev@gmail.com> +Date: Mon, 6 Jun 2022 00:56:51 -0600 +Subject: [PATCH 2/3] Fix bug #81719: mysqlnd/pdo password buffer overflow + +(cherry picked from commit 58006537fc5f133ae8549efe5118cde418b3ace9) +--- + ext/mysqlnd/mysqlnd_wireprotocol.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c +index 6459fe4964..1aee62c64e 100644 +--- a/ext/mysqlnd/mysqlnd_wireprotocol.c ++++ b/ext/mysqlnd/mysqlnd_wireprotocol.c +@@ -768,7 +768,8 @@ php_mysqlnd_change_auth_response_write(MYSQLND_CONN_DATA * conn, void * _packet) + MYSQLND_VIO * vio = conn->vio; + MYSQLND_STATS * stats = conn->stats; + MYSQLND_CONNECTION_STATE * connection_state = &conn->state; +- zend_uchar * buffer = pfc->cmd_buffer.length >= packet->auth_data_len? pfc->cmd_buffer.buffer : mnd_emalloc(packet->auth_data_len); ++ size_t total_packet_size = packet->auth_data_len + MYSQLND_HEADER_SIZE; ++ zend_uchar * const buffer = pfc->cmd_buffer.length >= total_packet_size? pfc->cmd_buffer.buffer : mnd_emalloc(total_packet_size); + zend_uchar * p = buffer + MYSQLND_HEADER_SIZE; /* start after the header */ + + DBG_ENTER("php_mysqlnd_change_auth_response_write"); +-- +2.35.3 + +From f451082baf14ee9ea86cdd19870e906adb368f02 Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Tue, 7 Jun 2022 09:57:15 +0200 +Subject: [PATCH 3/3] NEWS + +--- + NEWS | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/NEWS b/NEWS +index ffbe82d7aa..fd227bd33a 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,5 +1,16 @@ + PHP NEWS + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ++ ++Backported from 7.4.30 ++ ++- mysqlnd: ++ . Fixed bug #81719: mysqlnd/pdo password buffer overflow. ++ (CVE-2022-31626) (c dot fol at ambionics dot io) ++ ++- pgsql ++ . Fixed bug #81720: Uninitialized array in pg_query_params(). ++ (CVE-2022-31625) (cmb) ++ + 18 Nov 2021, PHP 7.3.33 + + - XML: +-- +2.35.3 + diff --git a/php-bug81720.patch b/php-bug81720.patch new file mode 100644 index 0000000..8580d7a --- /dev/null +++ b/php-bug81720.patch @@ -0,0 +1,76 @@ +From 6f979c832c861fb32e2dbad5e0cc29edcee7c500 Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" <cmbecker69@gmx.de> +Date: Tue, 17 May 2022 12:59:23 +0200 +Subject: [PATCH 1/3] Fix #81720: Uninitialized array in pg_query_params() + leading to RCE + +We must not free parameters which we haven't initialized yet. + +We also fix the not directly related issue, that we checked for the +wrong value being `NULL`, potentially causing a segfault. + +(cherry picked from commit 55f6895f4b4c677272fd4ee1113acdbd99c4b5ab) +--- + ext/pgsql/pgsql.c | 4 ++-- + ext/pgsql/tests/bug81720.phpt | 27 +++++++++++++++++++++++++++ + 2 files changed, 29 insertions(+), 2 deletions(-) + create mode 100644 ext/pgsql/tests/bug81720.phpt + +diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c +index 27462bc336..1dd892d359 100644 +--- a/ext/pgsql/pgsql.c ++++ b/ext/pgsql/pgsql.c +@@ -1994,7 +1994,7 @@ PHP_FUNCTION(pg_query_params) + if (Z_TYPE(tmp_val) != IS_STRING) { + php_error_docref(NULL, E_WARNING,"Error converting parameter"); + zval_ptr_dtor(&tmp_val); +- _php_pgsql_free_params(params, num_params); ++ _php_pgsql_free_params(params, i); + RETURN_FALSE; + } + params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val)); +@@ -5179,7 +5179,7 @@ PHP_FUNCTION(pg_send_execute) + if (Z_TYPE(tmp_val) != IS_STRING) { + php_error_docref(NULL, E_WARNING,"Error converting parameter"); + zval_ptr_dtor(&tmp_val); +- _php_pgsql_free_params(params, num_params); ++ _php_pgsql_free_params(params, i); + RETURN_FALSE; + } + params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val)); +diff --git a/ext/pgsql/tests/bug81720.phpt b/ext/pgsql/tests/bug81720.phpt +new file mode 100644 +index 0000000000..d79f1fcdd6 +--- /dev/null ++++ b/ext/pgsql/tests/bug81720.phpt +@@ -0,0 +1,27 @@ ++--TEST-- ++Bug #81720 (Uninitialized array in pg_query_params() leading to RCE) ++--SKIPIF-- ++<?php include("skipif.inc"); ?> ++--FILE-- ++<?php ++include('config.inc'); ++ ++$conn = pg_connect($conn_str); ++ ++try { ++ pg_query_params($conn, 'SELECT $1, $2', [1, new stdClass()]); ++} catch (Throwable $ex) { ++ echo $ex->getMessage(), PHP_EOL; ++} ++ ++try { ++ pg_send_prepare($conn, "my_query", 'SELECT $1, $2'); ++ pg_get_result($conn); ++ pg_send_execute($conn, "my_query", [1, new stdClass()]); ++} catch (Throwable $ex) { ++ echo $ex->getMessage(), PHP_EOL; ++} ++?> ++--EXPECT-- ++Object of class stdClass could not be converted to string ++Object of class stdClass could not be converted to string +-- +2.35.3 + diff --git a/php-bug81726.patch b/php-bug81726.patch new file mode 100644 index 0000000..fd43dac --- /dev/null +++ b/php-bug81726.patch @@ -0,0 +1,179 @@ +From 96fda78bcddd1d793cf2d0ee463dbb49621b577f Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" <cmbecker69@gmx.de> +Date: Mon, 25 Jul 2022 15:58:59 +0200 +Subject: [PATCH] Fix #81726: phar wrapper: DOS when using quine gzip file + +The phar wrapper needs to uncompress the file; the uncompressed file +might be compressed, so the wrapper implementation loops. This raises +potential DOS issues regarding too deep or even infinite recursion (the +latter are called compressed file quines[1]). We avoid that by +introducing a recursion limit; we choose the somewhat arbitrary limit +`3`. + +This issue has been reported by real_as3617 and gPayl0ad. + +[1] <https://honno.dev/gzip-quine/> + +(cherry picked from commit 404e8bdb68350931176a5bdc86fc417b34fb583d) +--- + NEWS | 2 ++ + ext/phar/phar.c | 16 +++++++++++----- + ext/phar/tests/bug81726.gz | Bin 0 -> 204 bytes + ext/phar/tests/bug81726.phpt | 14 ++++++++++++++ + 4 files changed, 27 insertions(+), 5 deletions(-) + create mode 100644 ext/phar/tests/bug81726.gz + create mode 100644 ext/phar/tests/bug81726.phpt + +diff --git a/NEWS b/NEWS +index 87b67643f3..fe4cb9c484 100644 +--- a/NEWS ++++ b/NEWS +@@ -4,6 +4,8 @@ PHP NEWS + Backported from 7.4.31 + + - Core: ++ . Fixed bug #81726: phar wrapper: DOS when using quine gzip file. ++ (CVE-2022-31628). (cmb) + . Fixed bug #81727: Don't mangle HTTP variable names that clash with ones + that have a specific semantic meaning. (CVE-2022-31629). (Derick) + +diff --git a/ext/phar/phar.c b/ext/phar/phar.c +index 44e40d98d1..9360658cd7 100644 +--- a/ext/phar/phar.c ++++ b/ext/phar/phar.c +@@ -1593,7 +1593,8 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char + const char zip_magic[] = "PK\x03\x04"; + const char gz_magic[] = "\x1f\x8b\x08"; + const char bz_magic[] = "BZh"; +- char *pos, test = '\0'; ++ char *pos; ++ int recursion_count = 3; // arbitrary limit to avoid too deep or even infinite recursion + const int window_size = 1024; + char buffer[1024 + sizeof(token)]; /* a 1024 byte window + the size of the halt_compiler token (moving window) */ + const zend_long readsize = sizeof(buffer) - sizeof(token); +@@ -1621,8 +1622,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char + MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (truncated entry)") + } + +- if (!test) { +- test = '\1'; ++ if (recursion_count) { + pos = buffer+tokenlen; + if (!memcmp(pos, gz_magic, 3)) { + char err = 0; +@@ -1682,7 +1682,10 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char + compression = PHAR_FILE_COMPRESSED_GZ; + + /* now, start over */ +- test = '\0'; ++ if (!--recursion_count) { ++ MAPPHAR_ALLOC_FAIL("unable to decompress gzipped phar archive \"%s\""); ++ break; ++ } + continue; + } else if (!memcmp(pos, bz_magic, 3)) { + php_stream_filter *filter; +@@ -1720,7 +1723,10 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char + compression = PHAR_FILE_COMPRESSED_BZ2; + + /* now, start over */ +- test = '\0'; ++ if (!--recursion_count) { ++ MAPPHAR_ALLOC_FAIL("unable to decompress bzipped phar archive \"%s\""); ++ break; ++ } + continue; + } + +From 535c3f592d020a3a43f4ce3577e505d64297b6e8 Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" <cmbecker69@gmx.de> +Date: Tue, 27 Sep 2022 17:43:40 +0200 +Subject: [PATCH] Fix regression introduced by fixing bug 81726 + +When a tar phar is created, `phar_open_from_fp()` is also called, but +since the file has just been created, none of the format checks can +succeed, so we continue to loop, but must not check again for the +format. Therefore, we bring back the old `test` variable. + +Closes GH-9620. + +(cherry picked from commit 432bf196d59bcb661fcf9cb7029cea9b43f490af) +--- + ext/phar/phar.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/ext/phar/phar.c b/ext/phar/phar.c +index 9360658cd7..1437525245 100644 +--- a/ext/phar/phar.c ++++ b/ext/phar/phar.c +@@ -1593,7 +1593,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char + const char zip_magic[] = "PK\x03\x04"; + const char gz_magic[] = "\x1f\x8b\x08"; + const char bz_magic[] = "BZh"; +- char *pos; ++ char *pos, test = '\0'; + int recursion_count = 3; // arbitrary limit to avoid too deep or even infinite recursion + const int window_size = 1024; + char buffer[1024 + sizeof(token)]; /* a 1024 byte window + the size of the halt_compiler token (moving window) */ +@@ -1622,7 +1622,8 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char + MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (truncated entry)") + } + +- if (recursion_count) { ++ if (!test && recursion_count) { ++ test = '\1'; + pos = buffer+tokenlen; + if (!memcmp(pos, gz_magic, 3)) { + char err = 0; +@@ -1682,6 +1683,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char + compression = PHAR_FILE_COMPRESSED_GZ; + + /* now, start over */ ++ test = '\0'; + if (!--recursion_count) { + MAPPHAR_ALLOC_FAIL("unable to decompress gzipped phar archive \"%s\""); + break; +@@ -1723,6 +1725,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, size_t fname_len, char + compression = PHAR_FILE_COMPRESSED_BZ2; + + /* now, start over */ ++ test = '\0'; + if (!--recursion_count) { + MAPPHAR_ALLOC_FAIL("unable to decompress bzipped phar archive \"%s\""); + break; +-- +2.37.3 + +From 9d32d284b25f5df75780911a47b3c23cbaac1761 Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Fri, 30 Sep 2022 09:22:14 +0200 +Subject: [PATCH] fix NEWS + +--- + NEWS | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/NEWS b/NEWS +index fe4cb9c484..b7a19aea19 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,14 +1,16 @@ + PHP NEWS + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + +-Backported from 7.4.31 ++Backported from 7.4.32 + + - Core: +- . Fixed bug #81726: phar wrapper: DOS when using quine gzip file. +- (CVE-2022-31628). (cmb) + . Fixed bug #81727: Don't mangle HTTP variable names that clash with ones + that have a specific semantic meaning. (CVE-2022-31629). (Derick) + ++- Phar: ++ . Fixed bug #81726: phar wrapper: DOS when using quine gzip file. ++ (CVE-2022-31628). (cmb) ++ + Backported from 7.4.30 + + - mysqlnd: diff --git a/php-bug81727.patch b/php-bug81727.patch new file mode 100644 index 0000000..381a9e8 --- /dev/null +++ b/php-bug81727.patch @@ -0,0 +1,77 @@ +From 8b300e157e92b0e945ad813d608f076b5323d721 Mon Sep 17 00:00:00 2001 +From: Derick Rethans <github@derickrethans.nl> +Date: Fri, 9 Sep 2022 16:54:03 +0100 +Subject: [PATCH] Fix #81727: Don't mangle HTTP variable names that clash with + ones that have a specific semantic meaning. + +(cherry picked from commit 0611be4e82887cee0de6c4cbae320d34eec946ca) +--- + NEWS | 6 ++++++ + ext/standard/tests/bug81727.phpt | 15 +++++++++++++++ + main/php_variables.c | 14 ++++++++++++++ + 3 files changed, 35 insertions(+) + create mode 100644 ext/standard/tests/bug81727.phpt + +diff --git a/NEWS b/NEWS +index fd227bd33a..87b67643f3 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,6 +1,12 @@ + PHP NEWS + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + ++Backported from 7.4.31 ++ ++- Core: ++ . Fixed bug #81727: Don't mangle HTTP variable names that clash with ones ++ that have a specific semantic meaning. (CVE-2022-31629). (Derick) ++ + Backported from 7.4.30 + + - mysqlnd: +diff --git a/ext/standard/tests/bug81727.phpt b/ext/standard/tests/bug81727.phpt +new file mode 100644 +index 0000000000..71a9cb46c8 +--- /dev/null ++++ b/ext/standard/tests/bug81727.phpt +@@ -0,0 +1,15 @@ ++--TEST-- ++Bug #81727: $_COOKIE name starting with ..Host/..Secure should be discarded ++--COOKIE-- ++..Host-test=ignore; __Host-test=correct; . Secure-test=ignore; . Elephpant=Awesome; ++--FILE-- ++<?php ++var_dump($_COOKIE); ++?> ++--EXPECT-- ++array(2) { ++ ["__Host-test"]=> ++ string(7) "correct" ++ ["__Elephpant"]=> ++ string(7) "Awesome" ++} +diff --git a/main/php_variables.c b/main/php_variables.c +index ca015352d2..f2d0c3bd98 100644 +--- a/main/php_variables.c ++++ b/main/php_variables.c +@@ -115,6 +115,20 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars + } + var_len = p - var; + ++ /* Discard variable if mangling made it start with __Host-, where pre-mangling it did not start with __Host- */ ++ if (strncmp(var, "__Host-", sizeof("__Host-")-1) == 0 && strncmp(var_name, "__Host-", sizeof("__Host-")-1) != 0) { ++ zval_ptr_dtor_nogc(val); ++ free_alloca(var_orig, use_heap); ++ return; ++ } ++ ++ /* Discard variable if mangling made it start with __Secure-, where pre-mangling it did not start with __Secure- */ ++ if (strncmp(var, "__Secure-", sizeof("__Secure-")-1) == 0 && strncmp(var_name, "__Secure-", sizeof("__Secure-")-1) != 0) { ++ zval_ptr_dtor_nogc(val); ++ free_alloca(var_orig, use_heap); ++ return; ++ } ++ + if (var_len==0) { /* empty variable name, or variable name with a space in it */ + zval_ptr_dtor_nogc(val); + free_alloca(var_orig, use_heap); diff --git a/php-bug81738.patch b/php-bug81738.patch new file mode 100644 index 0000000..0c6aaa8 --- /dev/null +++ b/php-bug81738.patch @@ -0,0 +1,128 @@ +From de4517ad607df8d4cb3735228b39e4a48f95556c Mon Sep 17 00:00:00 2001 +From: Stanislav Malyshev <smalyshev@gmail.com> +Date: Thu, 20 Oct 2022 23:57:35 -0600 +Subject: [PATCH] Fix bug #81738 (buffer overflow in hash_update() on long + parameter) + +--- + NEWS | 6 ++++++ + ext/hash/sha3/generic32lc/KeccakSponge.inc | 14 ++++++++------ + ext/hash/sha3/generic64lc/KeccakSponge.inc | 14 ++++++++------ + 3 files changed, 22 insertions(+), 12 deletions(-) + +diff --git a/NEWS b/NEWS +index b7a19aea19..ce48558ad1 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,6 +1,12 @@ + PHP NEWS + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + ++Backported from 7.4.33 ++ ++- Hash: ++ . Fixed bug #81738: buffer overflow in hash_update() on long parameter. ++ (CVE-2022-37454) (nicky at mouha dot be) ++ + Backported from 7.4.32 + + - Core: +diff --git a/ext/hash/sha3/generic32lc/KeccakSponge.inc b/ext/hash/sha3/generic32lc/KeccakSponge.inc +index 42a15aac6d..f8c42ff788 100644 +--- a/ext/hash/sha3/generic32lc/KeccakSponge.inc ++++ b/ext/hash/sha3/generic32lc/KeccakSponge.inc +@@ -160,7 +160,7 @@ int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dat + i = 0; + curData = data; + while(i < dataByteLen) { +- if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) { ++ if ((instance->byteIOIndex == 0) && (dataByteLen-i >= rateInBytes)) { + #ifdef SnP_FastLoop_Absorb + /* processing full blocks first */ + if ((rateInBytes % (SnP_width/200)) == 0) { +@@ -186,9 +186,10 @@ int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dat + } + else { + /* normal lane: using the message queue */ +- partialBlock = (unsigned int)(dataByteLen - i); +- if (partialBlock+instance->byteIOIndex > rateInBytes) ++ if (dataByteLen-i > rateInBytes-instance->byteIOIndex) + partialBlock = rateInBytes-instance->byteIOIndex; ++ else ++ partialBlock = (unsigned int)(dataByteLen - i); + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed (part)", curData, partialBlock); + #endif +@@ -263,7 +264,7 @@ int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByte + i = 0; + curData = data; + while(i < dataByteLen) { +- if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) { ++ if ((instance->byteIOIndex == rateInBytes) && (dataByteLen-i >= rateInBytes)) { + for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { + SnP_Permute(instance->state); + SnP_ExtractBytes(instance->state, curData, 0, rateInBytes); +@@ -280,9 +281,10 @@ int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByte + SnP_Permute(instance->state); + instance->byteIOIndex = 0; + } +- partialBlock = (unsigned int)(dataByteLen - i); +- if (partialBlock+instance->byteIOIndex > rateInBytes) ++ if (dataByteLen-i > rateInBytes-instance->byteIOIndex) + partialBlock = rateInBytes-instance->byteIOIndex; ++ else ++ partialBlock = (unsigned int)(dataByteLen - i); + i += partialBlock; + + SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock); +diff --git a/ext/hash/sha3/generic64lc/KeccakSponge.inc b/ext/hash/sha3/generic64lc/KeccakSponge.inc +index 42a15aac6d..f8c42ff788 100644 +--- a/ext/hash/sha3/generic64lc/KeccakSponge.inc ++++ b/ext/hash/sha3/generic64lc/KeccakSponge.inc +@@ -160,7 +160,7 @@ int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dat + i = 0; + curData = data; + while(i < dataByteLen) { +- if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) { ++ if ((instance->byteIOIndex == 0) && (dataByteLen-i >= rateInBytes)) { + #ifdef SnP_FastLoop_Absorb + /* processing full blocks first */ + if ((rateInBytes % (SnP_width/200)) == 0) { +@@ -186,9 +186,10 @@ int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dat + } + else { + /* normal lane: using the message queue */ +- partialBlock = (unsigned int)(dataByteLen - i); +- if (partialBlock+instance->byteIOIndex > rateInBytes) ++ if (dataByteLen-i > rateInBytes-instance->byteIOIndex) + partialBlock = rateInBytes-instance->byteIOIndex; ++ else ++ partialBlock = (unsigned int)(dataByteLen - i); + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed (part)", curData, partialBlock); + #endif +@@ -263,7 +264,7 @@ int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByte + i = 0; + curData = data; + while(i < dataByteLen) { +- if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) { ++ if ((instance->byteIOIndex == rateInBytes) && (dataByteLen-i >= rateInBytes)) { + for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { + SnP_Permute(instance->state); + SnP_ExtractBytes(instance->state, curData, 0, rateInBytes); +@@ -280,9 +281,10 @@ int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByte + SnP_Permute(instance->state); + instance->byteIOIndex = 0; + } +- partialBlock = (unsigned int)(dataByteLen - i); +- if (partialBlock+instance->byteIOIndex > rateInBytes) ++ if (dataByteLen-i > rateInBytes-instance->byteIOIndex) + partialBlock = rateInBytes-instance->byteIOIndex; ++ else ++ partialBlock = (unsigned int)(dataByteLen - i); + i += partialBlock; + + SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock); +-- +2.37.3 + diff --git a/php-bug81740.patch b/php-bug81740.patch new file mode 100644 index 0000000..73bc74a --- /dev/null +++ b/php-bug81740.patch @@ -0,0 +1,86 @@ +From 5a0e763a3dcf5ae22dbd6d35757255d6c33dbdde Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" <cmbecker69@gmx.de> +Date: Mon, 31 Oct 2022 17:20:23 +0100 +Subject: [PATCH 1/2] Fix #81740: PDO::quote() may return unquoted string + +`sqlite3_snprintf()` expects its first parameter to be `int`; we need +to avoid overflow. + +(cherry picked from commit 921b6813da3237a83e908998483f46ae3d8bacba) +(cherry picked from commit 7cb160efe19d3dfb8b92629805733ea186b55050) +--- + ext/pdo_sqlite/sqlite_driver.c | 3 +++ + ext/pdo_sqlite/tests/bug81740.phpt | 17 +++++++++++++++++ + 2 files changed, 20 insertions(+) + create mode 100644 ext/pdo_sqlite/tests/bug81740.phpt + +diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c +index a0f3e104f2..77720c618f 100644 +--- a/ext/pdo_sqlite/sqlite_driver.c ++++ b/ext/pdo_sqlite/sqlite_driver.c +@@ -233,6 +233,9 @@ static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t + /* NB: doesn't handle binary strings... use prepared stmts for that */ + static int sqlite_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype ) + { ++ if (unquotedlen > (INT_MAX - 3) / 2) { ++ return 0; ++ } + *quoted = safe_emalloc(2, unquotedlen, 3); + sqlite3_snprintf(2*unquotedlen + 3, *quoted, "'%q'", unquoted); + *quotedlen = strlen(*quoted); +diff --git a/ext/pdo_sqlite/tests/bug81740.phpt b/ext/pdo_sqlite/tests/bug81740.phpt +new file mode 100644 +index 0000000000..99fb07c304 +--- /dev/null ++++ b/ext/pdo_sqlite/tests/bug81740.phpt +@@ -0,0 +1,17 @@ ++--TEST-- ++Bug #81740 (PDO::quote() may return unquoted string) ++--SKIPIF-- ++<?php ++if (!extension_loaded('pdo_sqlite')) print 'skip not loaded'; ++if (getenv("SKIP_SLOW_TESTS")) die("skip slow test"); ++?> ++--INI-- ++memory_limit=-1 ++--FILE-- ++<?php ++$pdo = new PDO("sqlite::memory:"); ++$string = str_repeat("a", 0x80000000); ++var_dump($pdo->quote($string)); ++?> ++--EXPECT-- ++bool(false) +-- +2.38.1 + +From 144d79977c7e2a410a705f550dbc8ee754dd1cb3 Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Mon, 19 Dec 2022 09:24:02 +0100 +Subject: [PATCH 2/2] NEWS + +(cherry picked from commit 7328f3a0344806b846bd05657bdce96e47810bf0) +--- + NEWS | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/NEWS b/NEWS +index ce48558ad1..4de34f7876 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,6 +1,12 @@ + PHP NEWS + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + ++Backported from 8.0.27 ++ ++- PDO/SQLite: ++ . Fixed bug #81740 (PDO::quote() may return unquoted string). ++ (CVE-2022-31631) (cmb) ++ + Backported from 7.4.33 + + - Hash: +-- +2.38.1 + diff --git a/php-bug81744.patch b/php-bug81744.patch new file mode 100644 index 0000000..e11afe1 --- /dev/null +++ b/php-bug81744.patch @@ -0,0 +1,190 @@ +From e78b2696c7baf48e5d0898420368555ff4b99830 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= <tim@bastelstu.be> +Date: Mon, 23 Jan 2023 21:15:24 +0100 +Subject: [PATCH 1/8] crypt: Fix validation of malformed BCrypt hashes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +PHP’s implementation of crypt_blowfish differs from the upstream Openwall +version by adding a “PHP Hack”, which allows one to cut short the BCrypt salt +by including a `$` character within the characters that represent the salt. + +Hashes that are affected by the “PHP Hack” may erroneously validate any +password as valid when used with `password_verify` and when comparing the +return value of `crypt()` against the input. + +The PHP Hack exists since the first version of PHP’s own crypt_blowfish +implementation that was added in 1e820eca02dcf322b41fd2fe4ed2a6b8309f8ab5. + +No clear reason is given for the PHP Hack’s existence. This commit removes it, +because BCrypt hashes containing a `$` character in their salt are not valid +BCrypt hashes. + +(cherry picked from commit c840f71524067aa474c00c3eacfb83bd860bfc8a) +(cherry picked from commit 7437aaae38cf4b3357e7580f9e22fd4a403b6c23) +--- + ext/standard/crypt_blowfish.c | 8 -- + .../tests/crypt/bcrypt_salt_dollar.phpt | 82 +++++++++++++++++++ + 2 files changed, 82 insertions(+), 8 deletions(-) + create mode 100644 ext/standard/tests/crypt/bcrypt_salt_dollar.phpt + +diff --git a/ext/standard/crypt_blowfish.c b/ext/standard/crypt_blowfish.c +index c1f945f29e..aa7e1bc2e6 100644 +--- a/ext/standard/crypt_blowfish.c ++++ b/ext/standard/crypt_blowfish.c +@@ -376,7 +376,6 @@ static unsigned char BF_atoi64[0x60] = { + #define BF_safe_atoi64(dst, src) \ + { \ + tmp = (unsigned char)(src); \ +- if (tmp == '$') break; /* PHP hack */ \ + if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ + tmp = BF_atoi64[tmp]; \ + if (tmp > 63) return -1; \ +@@ -404,13 +403,6 @@ static int BF_decode(BF_word *dst, const char *src, int size) + *dptr++ = ((c3 & 0x03) << 6) | c4; + } while (dptr < end); + +- if (end - dptr == size) { +- return -1; +- } +- +- while (dptr < end) /* PHP hack */ +- *dptr++ = 0; +- + return 0; + } + +diff --git a/ext/standard/tests/crypt/bcrypt_salt_dollar.phpt b/ext/standard/tests/crypt/bcrypt_salt_dollar.phpt +new file mode 100644 +index 0000000000..32e335f4b0 +--- /dev/null ++++ b/ext/standard/tests/crypt/bcrypt_salt_dollar.phpt +@@ -0,0 +1,82 @@ ++--TEST-- ++bcrypt correctly rejects salts containing $ ++--FILE-- ++<?php ++for ($i = 0; $i < 23; $i++) { ++ $salt = '$2y$04$' . str_repeat('0', $i) . '$'; ++ $result = crypt("foo", $salt); ++ var_dump($salt); ++ var_dump($result); ++ var_dump($result === $salt); ++} ++?> ++--EXPECT-- ++string(8) "$2y$04$$" ++string(2) "*0" ++bool(false) ++string(9) "$2y$04$0$" ++string(2) "*0" ++bool(false) ++string(10) "$2y$04$00$" ++string(2) "*0" ++bool(false) ++string(11) "$2y$04$000$" ++string(2) "*0" ++bool(false) ++string(12) "$2y$04$0000$" ++string(2) "*0" ++bool(false) ++string(13) "$2y$04$00000$" ++string(2) "*0" ++bool(false) ++string(14) "$2y$04$000000$" ++string(2) "*0" ++bool(false) ++string(15) "$2y$04$0000000$" ++string(2) "*0" ++bool(false) ++string(16) "$2y$04$00000000$" ++string(2) "*0" ++bool(false) ++string(17) "$2y$04$000000000$" ++string(2) "*0" ++bool(false) ++string(18) "$2y$04$0000000000$" ++string(2) "*0" ++bool(false) ++string(19) "$2y$04$00000000000$" ++string(2) "*0" ++bool(false) ++string(20) "$2y$04$000000000000$" ++string(2) "*0" ++bool(false) ++string(21) "$2y$04$0000000000000$" ++string(2) "*0" ++bool(false) ++string(22) "$2y$04$00000000000000$" ++string(2) "*0" ++bool(false) ++string(23) "$2y$04$000000000000000$" ++string(2) "*0" ++bool(false) ++string(24) "$2y$04$0000000000000000$" ++string(2) "*0" ++bool(false) ++string(25) "$2y$04$00000000000000000$" ++string(2) "*0" ++bool(false) ++string(26) "$2y$04$000000000000000000$" ++string(2) "*0" ++bool(false) ++string(27) "$2y$04$0000000000000000000$" ++string(2) "*0" ++bool(false) ++string(28) "$2y$04$00000000000000000000$" ++string(2) "*0" ++bool(false) ++string(29) "$2y$04$000000000000000000000$" ++string(2) "*0" ++bool(false) ++string(30) "$2y$04$0000000000000000000000$" ++string(60) "$2y$04$000000000000000000000u2a2UpVexIt9k3FMJeAVr3c04F5tcI8K" ++bool(false) +-- +2.39.1 + +From ae619b4ba0b325650d09447a48e18c578d52c681 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= <tim@bastelstu.be> +Date: Mon, 23 Jan 2023 22:13:57 +0100 +Subject: [PATCH 2/8] crypt: Fix possible buffer overread in php_crypt() + +(cherry picked from commit a92acbad873a05470af1a47cb785a18eadd827b5) +(cherry picked from commit ed0281b588a6840cb95f3134a4e68847a3be5bb7) +--- + ext/standard/crypt.c | 1 + + ext/standard/tests/password/password_bcrypt_short.phpt | 8 ++++++++ + 2 files changed, 9 insertions(+) + create mode 100644 ext/standard/tests/password/password_bcrypt_short.phpt + +diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c +index fec04ec584..9787b92f57 100644 +--- a/ext/standard/crypt.c ++++ b/ext/standard/crypt.c +@@ -154,6 +154,7 @@ PHPAPI zend_string *php_crypt(const char *password, const int pass_len, const ch + } else if ( + salt[0] == '$' && + salt[1] == '2' && ++ salt[2] != 0 && + salt[3] == '$') { + char output[PHP_MAX_SALT_LEN + 1]; + +diff --git a/ext/standard/tests/password/password_bcrypt_short.phpt b/ext/standard/tests/password/password_bcrypt_short.phpt +new file mode 100644 +index 0000000000..085bc8a239 +--- /dev/null ++++ b/ext/standard/tests/password/password_bcrypt_short.phpt +@@ -0,0 +1,8 @@ ++--TEST-- ++Test that password_hash() does not overread buffers when a short hash is passed ++--FILE-- ++<?php ++var_dump(password_verify("foo", '$2')); ++?> ++--EXPECT-- ++bool(false) +-- +2.39.1 + diff --git a/php-bug81746.patch b/php-bug81746.patch new file mode 100644 index 0000000..06f6dbb --- /dev/null +++ b/php-bug81746.patch @@ -0,0 +1,100 @@ +From 31090aae8ff1f150cb822e69e0871af166d463c5 Mon Sep 17 00:00:00 2001 +From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> +Date: Fri, 27 Jan 2023 19:28:27 +0100 +Subject: [PATCH 3/8] Fix array overrun when appending slash to paths + +Fix it by extending the array sizes by one character. As the input is +limited to the maximum path length, there will always be place to append +the slash. As the php_check_specific_open_basedir() simply uses the +strings to compare against each other, no new failures related to too +long paths are introduced. +We'll let the DOM and XML case handle a potentially too long path in the +library code. + +(cherry picked from commit ec10b28d64decbc54aa1e585dce580f0bd7a5953) +(cherry picked from commit 887cd0710ad856a0d22c329b6ea6c71ebd8621ae) +--- + ext/dom/document.c | 2 +- + ext/xmlreader/php_xmlreader.c | 2 +- + main/fopen_wrappers.c | 6 +++--- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/ext/dom/document.c b/ext/dom/document.c +index 0e15e7a110..3f34e5370d 100644 +--- a/ext/dom/document.c ++++ b/ext/dom/document.c +@@ -1357,7 +1357,7 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, size_t so + int validate, recover, resolve_externals, keep_blanks, substitute_ent; + int resolved_path_len; + int old_error_reporting = 0; +- char *directory=NULL, resolved_path[MAXPATHLEN]; ++ char *directory=NULL, resolved_path[MAXPATHLEN + 1]; + + if (id != NULL) { + intern = Z_DOMOBJ_P(id); +diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c +index 4d4e7348c9..e03273709f 100644 +--- a/ext/xmlreader/php_xmlreader.c ++++ b/ext/xmlreader/php_xmlreader.c +@@ -1029,7 +1029,7 @@ PHP_METHOD(xmlreader, XML) + xmlreader_object *intern = NULL; + char *source, *uri = NULL, *encoding = NULL; + int resolved_path_len, ret = 0; +- char *directory=NULL, resolved_path[MAXPATHLEN]; ++ char *directory=NULL, resolved_path[MAXPATHLEN + 1]; + xmlParserInputBufferPtr inputbfr; + xmlTextReaderPtr reader; + +diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c +index 1509c006d7..4b15f052ef 100644 +--- a/main/fopen_wrappers.c ++++ b/main/fopen_wrappers.c +@@ -133,10 +133,10 @@ PHPAPI ZEND_INI_MH(OnUpdateBaseDir) + */ + PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path) + { +- char resolved_name[MAXPATHLEN]; +- char resolved_basedir[MAXPATHLEN]; ++ char resolved_name[MAXPATHLEN + 1]; ++ char resolved_basedir[MAXPATHLEN + 1]; + char local_open_basedir[MAXPATHLEN]; +- char path_tmp[MAXPATHLEN]; ++ char path_tmp[MAXPATHLEN + 1]; + char *path_file; + size_t resolved_basedir_len; + size_t resolved_name_len; +-- +2.39.1 + +From f251242c25493685d7030588f99c17193d3f667d Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Mon, 13 Feb 2023 11:46:47 +0100 +Subject: [PATCH 4/8] NEWS + +(cherry picked from commit 614468ce4056c0ef93aae09532dcffdf65b594b5) +--- + NEWS | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/NEWS b/NEWS +index 4de34f7876..80d589e4d9 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,6 +1,14 @@ + PHP NEWS + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + ++Backported from 8.0.28 ++ ++- Core: ++ . Fixed bug #81744 (Password_verify() always return true with some hash). ++ (CVE-2023-0567). (Tim Düsterhus) ++ . Fixed bug #81746 (1-byte array overrun in common path resolve code). ++ (CVE-2023-0568). (Niels Dossche) ++ + Backported from 8.0.27 + + - PDO/SQLite: +-- +2.39.1 + diff --git a/php-cve-2023-0662.patch b/php-cve-2023-0662.patch new file mode 100644 index 0000000..fea49a2 --- /dev/null +++ b/php-cve-2023-0662.patch @@ -0,0 +1,148 @@ +From 49bef9efd65ab7456210f8c23b74fdd0f3a8292a Mon Sep 17 00:00:00 2001 +From: Jakub Zelenka <bukka@php.net> +Date: Thu, 19 Jan 2023 14:11:18 +0000 +Subject: [PATCH 5/8] Fix repeated warning for file uploads limit exceeding + +(cherry picked from commit 3a2fdef1ae38881110006616ee1f0534b082ca45) +--- + main/rfc1867.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/main/rfc1867.c b/main/rfc1867.c +index 3f91fe6fb4..bf28334a34 100644 +--- a/main/rfc1867.c ++++ b/main/rfc1867.c +@@ -930,7 +930,10 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ + skip_upload = 1; + } else if (upload_cnt <= 0) { + skip_upload = 1; +- sapi_module.sapi_error(E_WARNING, "Maximum number of allowable file uploads has been exceeded"); ++ if (upload_cnt == 0) { ++ --upload_cnt; ++ sapi_module.sapi_error(E_WARNING, "Maximum number of allowable file uploads has been exceeded"); ++ } + } + + /* Return with an error if the posted data is garbled */ +-- +2.39.1 + +From d380b11cb9b73e154dc79955a73139cc6f26dd71 Mon Sep 17 00:00:00 2001 +From: Jakub Zelenka <bukka@php.net> +Date: Thu, 19 Jan 2023 14:31:25 +0000 +Subject: [PATCH 6/8] Introduce max_multipart_body_parts INI + +This fixes GHSA-54hq-v5wp-fqgv DOS vulnerabality by limitting number of +parsed multipart body parts as currently all parts were always parsed. + +(cherry picked from commit 8ec78d28d20c82c75c4747f44c52601cfdb22516) +--- + main/main.c | 1 + + main/rfc1867.c | 11 +++++++++++ + 2 files changed, 12 insertions(+) + +diff --git a/main/main.c b/main/main.c +index f20a786743..c3939b3cb5 100644 +--- a/main/main.c ++++ b/main/main.c +@@ -782,6 +782,7 @@ PHP_INI_BEGIN() + PHP_INI_ENTRY("disable_functions", "", PHP_INI_SYSTEM, NULL) + PHP_INI_ENTRY("disable_classes", "", PHP_INI_SYSTEM, NULL) + PHP_INI_ENTRY("max_file_uploads", "20", PHP_INI_SYSTEM|PHP_INI_PERDIR, NULL) ++ PHP_INI_ENTRY("max_multipart_body_parts", "-1", PHP_INI_SYSTEM|PHP_INI_PERDIR, NULL) + + STD_PHP_INI_BOOLEAN("allow_url_fopen", "1", PHP_INI_SYSTEM, OnUpdateBool, allow_url_fopen, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("allow_url_include", "0", PHP_INI_SYSTEM, OnUpdateBool, allow_url_include, php_core_globals, core_globals) +diff --git a/main/rfc1867.c b/main/rfc1867.c +index bf28334a34..d33809514e 100644 +--- a/main/rfc1867.c ++++ b/main/rfc1867.c +@@ -702,6 +702,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ + void *event_extra_data = NULL; + unsigned int llen = 0; + int upload_cnt = INI_INT("max_file_uploads"); ++ int body_parts_cnt = INI_INT("max_multipart_body_parts"); + const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(); + php_rfc1867_getword_t getword; + php_rfc1867_getword_conf_t getword_conf; +@@ -723,6 +724,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ + return; + } + ++ if (body_parts_cnt < 0) { ++ body_parts_cnt = PG(max_input_vars) + upload_cnt; ++ } ++ int body_parts_limit = body_parts_cnt; ++ + /* Get the boundary */ + boundary = strstr(content_type_dup, "boundary"); + if (!boundary) { +@@ -807,6 +813,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ + char *pair = NULL; + int end = 0; + ++ if (--body_parts_cnt < 0) { ++ php_error_docref(NULL, E_WARNING, "Multipart body parts limit exceeded %d. To increase the limit change max_multipart_body_parts in php.ini.", body_parts_limit); ++ goto fileupload_done; ++ } ++ + while (isspace(*cd)) { + ++cd; + } +-- +2.39.1 + +From 981935217e6d7112ffa1e7a467bed446faa4ffbd Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Tue, 14 Feb 2023 09:14:47 +0100 +Subject: [PATCH 7/8] NEWS + +(cherry picked from commit 472db3ee3a00ac00d36019eee0b3b7362334481c) +--- + NEWS | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/NEWS b/NEWS +index 80d589e4d9..45743bf7f0 100644 +--- a/NEWS ++++ b/NEWS +@@ -9,6 +9,10 @@ Backported from 8.0.28 + . Fixed bug #81746 (1-byte array overrun in common path resolve code). + (CVE-2023-0568). (Niels Dossche) + ++- FPM: ++ . Fixed bug GHSA-54hq-v5wp-fqgv (DOS vulnerability when parsing multipart ++ request body). (CVE-2023-0662) (Jakub Zelenka) ++ + Backported from 8.0.27 + + - PDO/SQLite: +-- +2.39.1 + +From 3cdb8167a4a86dc371321542f272cd220807482e Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Tue, 14 Feb 2023 11:47:22 +0100 +Subject: [PATCH 8/8] fix NEWS, not FPM specific + +(cherry picked from commit c04f310440a906fc4ca885f4ecf6e3e4cd36edc7) +--- + NEWS | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/NEWS b/NEWS +index 45743bf7f0..a9d7871ba3 100644 +--- a/NEWS ++++ b/NEWS +@@ -8,8 +8,6 @@ Backported from 8.0.28 + (CVE-2023-0567). (Tim Düsterhus) + . Fixed bug #81746 (1-byte array overrun in common path resolve code). + (CVE-2023-0568). (Niels Dossche) +- +-- FPM: + . Fixed bug GHSA-54hq-v5wp-fqgv (DOS vulnerability when parsing multipart + request body). (CVE-2023-0662) (Jakub Zelenka) + +-- +2.39.1 + diff --git a/php-cve-2023-3247.patch b/php-cve-2023-3247.patch new file mode 100644 index 0000000..497b53e --- /dev/null +++ b/php-cve-2023-3247.patch @@ -0,0 +1,150 @@ +From 0cfca9aa1395271833848daec0bace51d965531d Mon Sep 17 00:00:00 2001 +From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> +Date: Sun, 16 Apr 2023 15:05:03 +0200 +Subject: [PATCH] Fix missing randomness check and insufficient random bytes + for SOAP HTTP Digest +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If php_random_bytes_throw fails, the nonce will be uninitialized, but +still sent to the server. The client nonce is intended to protect +against a malicious server. See section 5.10 and 5.12 of RFC 7616 [1], +and bullet point 2 below. + +Tim pointed out that even though it's the MD5 of the nonce that gets sent, +enumerating 31 bits is trivial. So we have still a stack information leak +of 31 bits. + +Furthermore, Tim found the following issues: +* The small size of cnonce might cause the server to erroneously reject + a request due to a repeated (cnonce, nc) pair. As per the birthday + problem 31 bits of randomness will return a duplication with 50% + chance after less than 55000 requests and nc always starts counting at 1. +* The cnonce is intended to protect the client and password against a + malicious server that returns a constant server nonce where the server + precomputed a rainbow table between passwords and correct client response. + As storage is fairly cheap, a server could precompute the client responses + for (a subset of) client nonces and still have a chance of reversing the + client response with the same probability as the cnonce duplication. + + Precomputing the rainbow table for all 2^31 cnonces increases the rainbow + table size by factor 2 billion, which is infeasible. But precomputing it + for 2^14 cnonces only increases the table size by factor 16k and the server + would still have a 10% chance of successfully reversing a password with a + single client request. + +This patch fixes the issues by increasing the nonce size, and checking +the return value of php_random_bytes_throw(). In the process we also get +rid of the MD5 hashing of the nonce. + +[1] RFC 7616: https://www.rfc-editor.org/rfc/rfc7616 + +Co-authored-by: Tim Düsterhus <timwolla@php.net> +(cherry picked from commit 126d517ce240e9f638d9a5eaa509eaca49ef562a) +--- + NEWS | 6 ++++++ + ext/soap/php_http.c | 21 +++++++++++++-------- + 2 files changed, 19 insertions(+), 8 deletions(-) + +diff --git a/NEWS b/NEWS +index 3f8739eae7..7c07635cad 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,6 +1,12 @@ + PHP NEWS + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + ++Backported from 8.0.29 ++ ++- Soap: ++ . Fixed bug GHSA-76gg-c692-v2mw (Missing error check and insufficient random ++ bytes in HTTP Digest authentication for SOAP). (nielsdos, timwolla) ++ + Backported from 8.0.28 + + - Core: +diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c +index ee3dcbdc9a..e3a9afdbe9 100644 +--- a/ext/soap/php_http.c ++++ b/ext/soap/php_http.c +@@ -666,18 +666,23 @@ int make_http_soap_request(zval *this_ptr, + if ((digest = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest")-1)) != NULL) { + if (Z_TYPE_P(digest) == IS_ARRAY) { + char HA1[33], HA2[33], response[33], cnonce[33], nc[9]; +- zend_long nonce; ++ unsigned char nonce[16]; + PHP_MD5_CTX md5ctx; + unsigned char hash[16]; + +- php_random_bytes_throw(&nonce, sizeof(nonce)); +- nonce &= 0x7fffffff; ++ if (UNEXPECTED(php_random_bytes_throw(&nonce, sizeof(nonce)) != SUCCESS)) { ++ ZEND_ASSERT(EG(exception)); ++ php_stream_close(stream); ++ zend_hash_str_del(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl")-1); ++ zend_hash_str_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")-1); ++ zend_hash_str_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy")-1); ++ smart_str_free(&soap_headers_z); ++ smart_str_free(&soap_headers); ++ return FALSE; ++ } + +- PHP_MD5Init(&md5ctx); +- snprintf(cnonce, sizeof(cnonce), ZEND_LONG_FMT, nonce); +- PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, strlen(cnonce)); +- PHP_MD5Final(hash, &md5ctx); +- make_digest(cnonce, hash); ++ php_hash_bin2hex(cnonce, nonce, sizeof(nonce)); ++ cnonce[32] = 0; + + if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "nc", sizeof("nc")-1)) != NULL && + Z_TYPE_P(tmp) == IS_LONG) { +From 40439039c224bb8cdebd1b7b3d03b8cc11e7cce7 Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Tue, 6 Jun 2023 18:05:22 +0200 +Subject: [PATCH] Fix GH-11382 add missing hash header for bin2hex + +--- + ext/soap/php_http.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c +index e3a9afdbe9..912b8e341d 100644 +--- a/ext/soap/php_http.c ++++ b/ext/soap/php_http.c +@@ -22,6 +22,7 @@ + #include "ext/standard/base64.h" + #include "ext/standard/md5.h" + #include "ext/standard/php_random.h" ++#include "ext/hash/php_hash.h" + + static char *get_http_header_value_nodup(char *headers, char *type, size_t *len); + static char *get_http_header_value(char *headers, char *type); +From ec8afe8e559342b61a0498dcab8ce59dc6319d3e Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Thu, 15 Jun 2023 08:47:55 +0200 +Subject: [PATCH] add cve + +(cherry picked from commit f3021d66d7bb42d2578530cc94f9bde47e58eb10) +--- + NEWS | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/NEWS b/NEWS +index 7ccc61e6e4..1950d841a5 100644 +--- a/NEWS ++++ b/NEWS +@@ -5,7 +5,8 @@ Backported from 8.0.29 + + - Soap: + . Fixed bug GHSA-76gg-c692-v2mw (Missing error check and insufficient random +- bytes in HTTP Digest authentication for SOAP). (nielsdos, timwolla) ++ bytes in HTTP Digest authentication for SOAP). ++ (CVE-2023-3247) (nielsdos, timwolla) + + Backported from 8.0.28 + +-- +2.40.1 + diff --git a/php-cve-2023-3823.patch b/php-cve-2023-3823.patch new file mode 100644 index 0000000..604438c --- /dev/null +++ b/php-cve-2023-3823.patch @@ -0,0 +1,90 @@ +From 3f14261065e4c0552afa9cb16411475050a41c2c Mon Sep 17 00:00:00 2001 +From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> +Date: Mon, 10 Jul 2023 13:25:34 +0200 +Subject: [PATCH 1/4] Fix buffer mismanagement in phar_dir_read() + +Fixes GHSA-jqcx-ccgc-xwhv. + +(cherry picked from commit 80316123f3e9dcce8ac419bd9dd43546e2ccb5ef) +(cherry picked from commit c398fe98c044c8e7c23135acdc38d4ef7bedc983) +--- + ext/phar/dirstream.c | 15 ++++++++------ + ext/phar/tests/GHSA-jqcx-ccgc-xwhv.phpt | 27 +++++++++++++++++++++++++ + 2 files changed, 36 insertions(+), 6 deletions(-) + create mode 100644 ext/phar/tests/GHSA-jqcx-ccgc-xwhv.phpt + +diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c +index 70e696a167..b60af236ef 100644 +--- a/ext/phar/dirstream.c ++++ b/ext/phar/dirstream.c +@@ -92,25 +92,28 @@ static int phar_dir_seek(php_stream *stream, zend_off_t offset, int whence, zend + */ + static size_t phar_dir_read(php_stream *stream, char *buf, size_t count) /* {{{ */ + { +- size_t to_read; + HashTable *data = (HashTable *)stream->abstract; + zend_string *str_key; + zend_ulong unused; + ++ if (count != sizeof(php_stream_dirent)) { ++ return -1; ++ } ++ + if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key(data, &str_key, &unused)) { + return 0; + } + + zend_hash_move_forward(data); +- to_read = MIN(ZSTR_LEN(str_key), count); + +- if (to_read == 0 || count < ZSTR_LEN(str_key)) { ++ php_stream_dirent *dirent = (php_stream_dirent *) buf; ++ ++ if (sizeof(dirent->d_name) <= ZSTR_LEN(str_key)) { + return 0; + } + +- memset(buf, 0, sizeof(php_stream_dirent)); +- memcpy(((php_stream_dirent *) buf)->d_name, ZSTR_VAL(str_key), to_read); +- ((php_stream_dirent *) buf)->d_name[to_read + 1] = '\0'; ++ memset(dirent, 0, sizeof(php_stream_dirent)); ++ PHP_STRLCPY(dirent->d_name, ZSTR_VAL(str_key), sizeof(dirent->d_name), ZSTR_LEN(str_key)); + + return sizeof(php_stream_dirent); + } +diff --git a/ext/phar/tests/GHSA-jqcx-ccgc-xwhv.phpt b/ext/phar/tests/GHSA-jqcx-ccgc-xwhv.phpt +new file mode 100644 +index 0000000000..4e12f05fb6 +--- /dev/null ++++ b/ext/phar/tests/GHSA-jqcx-ccgc-xwhv.phpt +@@ -0,0 +1,27 @@ ++--TEST-- ++GHSA-jqcx-ccgc-xwhv (Buffer overflow and overread in phar_dir_read()) ++--SKIPIF-- ++<?php if (!extension_loaded("phar")) die("skip"); ?> ++--INI-- ++phar.readonly=0 ++--FILE-- ++<?php ++$phar = new Phar(__DIR__. '/GHSA-jqcx-ccgc-xwhv.phar'); ++$phar->startBuffering(); ++$phar->addFromString(str_repeat('A', PHP_MAXPATHLEN - 1), 'This is the content of file 1.'); ++$phar->addFromString(str_repeat('B', PHP_MAXPATHLEN - 1).'C', 'This is the content of file 2.'); ++$phar->stopBuffering(); ++ ++$handle = opendir('phar://' . __DIR__ . '/GHSA-jqcx-ccgc-xwhv.phar'); ++var_dump(strlen(readdir($handle))); ++// Must not be a string of length PHP_MAXPATHLEN+1 ++var_dump(readdir($handle)); ++closedir($handle); ++?> ++--CLEAN-- ++<?php ++unlink(__DIR__. '/GHSA-jqcx-ccgc-xwhv.phar'); ++?> ++--EXPECTF-- ++int(%d) ++bool(false) +-- +2.41.0 + diff --git a/php-cve-2023-3824.patch b/php-cve-2023-3824.patch new file mode 100644 index 0000000..8eea6f1 --- /dev/null +++ b/php-cve-2023-3824.patch @@ -0,0 +1,647 @@ +From 4fb61f06b1aff89a4d7e548c37ffa5bf573270c3 Mon Sep 17 00:00:00 2001 +From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> +Date: Sat, 15 Jul 2023 17:33:52 +0200 +Subject: [PATCH 2/4] Sanitize libxml2 globals before parsing + +Fixes GHSA-3qrf-m4j2-pcrr. + +To parse a document with libxml2, you first need to create a parsing context. +The parsing context contains parsing options (e.g. XML_NOENT to substitute +entities) that the application (in this case PHP) can set. +Unfortunately, libxml2 also supports providing default set options. +For example, if you call xmlSubstituteEntitiesDefault(1) then the XML_NOENT +option will be added to the parsing options every time you create a parsing +context **even if the application never requested XML_NOENT**. + +Third party extensions can override these globals, in particular the +substitute entity global. This causes entity substitution to be +unexpectedly active. + +Fix it by setting the parsing options to a sane known value. +For API calls that depend on global state we introduce +PHP_LIBXML_SANITIZE_GLOBALS() and PHP_LIBXML_RESTORE_GLOBALS(). +For other APIs that work directly with a context we introduce +php_libxml_sanitize_parse_ctxt_options(). + +(cherry picked from commit c283c3ab0ba45d21b2b8745c1f9c7cbfe771c975) +(cherry picked from commit b3758bd21223b97c042cae7bd26a66cde081ea98) +--- + ext/dom/document.c | 15 ++++++++ + ext/dom/documentfragment.c | 2 ++ + ...xml_global_state_entity_loader_bypass.phpt | 36 +++++++++++++++++++ + ext/libxml/php_libxml.h | 36 +++++++++++++++++++ + ext/simplexml/simplexml.c | 6 ++++ + ...xml_global_state_entity_loader_bypass.phpt | 36 +++++++++++++++++++ + ext/soap/php_xml.c | 2 ++ + ext/xml/compat.c | 2 ++ + ext/xmlreader/php_xmlreader.c | 9 +++++ + ...xml_global_state_entity_loader_bypass.phpt | 35 ++++++++++++++++++ + ext/xsl/xsltprocessor.c | 9 +++-- + 11 files changed, 183 insertions(+), 5 deletions(-) + create mode 100644 ext/dom/tests/libxml_global_state_entity_loader_bypass.phpt + create mode 100644 ext/simplexml/tests/libxml_global_state_entity_loader_bypass.phpt + create mode 100644 ext/xmlreader/tests/libxml_global_state_entity_loader_bypass.phpt + +diff --git a/ext/dom/document.c b/ext/dom/document.c +index 3f34e5370d..238b1381cc 100644 +--- a/ext/dom/document.c ++++ b/ext/dom/document.c +@@ -1436,6 +1436,7 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, size_t so + options |= XML_PARSE_NOBLANKS; + } + ++ php_libxml_sanitize_parse_ctxt_options(ctxt); + xmlCtxtUseOptions(ctxt, options); + + ctxt->recovery = recover; +@@ -1733,7 +1734,9 @@ PHP_FUNCTION(dom_document_xinclude) + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + ++ PHP_LIBXML_SANITIZE_GLOBALS(xinclude); + err = xmlXIncludeProcessFlags(docp, (int)flags); ++ PHP_LIBXML_RESTORE_GLOBALS(xinclude); + + /* XML_XINCLUDE_START and XML_XINCLUDE_END nodes need to be removed as these + are added via xmlXIncludeProcess to mark beginning and ending of xincluded document +@@ -1772,6 +1775,7 @@ PHP_FUNCTION(dom_document_validate) + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + ++ PHP_LIBXML_SANITIZE_GLOBALS(validate); + cvp = xmlNewValidCtxt(); + + cvp->userData = NULL; +@@ -1783,6 +1787,7 @@ PHP_FUNCTION(dom_document_validate) + } else { + RETVAL_FALSE; + } ++ PHP_LIBXML_RESTORE_GLOBALS(validate); + + xmlFreeValidCtxt(cvp); + +@@ -1816,14 +1821,18 @@ static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type + + DOM_GET_OBJ(docp, id, xmlDocPtr, intern); + ++ PHP_LIBXML_SANITIZE_GLOBALS(new_parser_ctxt); ++ + switch (type) { + case DOM_LOAD_FILE: + if (CHECK_NULL_PATH(source, source_len)) { ++ PHP_LIBXML_RESTORE_GLOBALS(new_parser_ctxt); + php_error_docref(NULL, E_WARNING, "Invalid Schema file source"); + RETURN_FALSE; + } + valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN); + if (!valid_file) { ++ PHP_LIBXML_RESTORE_GLOBALS(new_parser_ctxt); + php_error_docref(NULL, E_WARNING, "Invalid Schema file source"); + RETURN_FALSE; + } +@@ -1844,6 +1853,7 @@ static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type + parser); + sptr = xmlSchemaParse(parser); + xmlSchemaFreeParserCtxt(parser); ++ PHP_LIBXML_RESTORE_GLOBALS(new_parser_ctxt); + if (!sptr) { + php_error_docref(NULL, E_WARNING, "Invalid Schema"); + RETURN_FALSE; +@@ -1864,11 +1874,13 @@ static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type + } + #endif + ++ PHP_LIBXML_SANITIZE_GLOBALS(validate); + xmlSchemaSetValidOptions(vptr, valid_opts); + xmlSchemaSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr); + is_valid = xmlSchemaValidateDoc(vptr, docp); + xmlSchemaFree(sptr); + xmlSchemaFreeValidCtxt(vptr); ++ PHP_LIBXML_RESTORE_GLOBALS(validate); + + if (is_valid == 0) { + RETURN_TRUE; +@@ -1938,12 +1950,14 @@ static void _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int typ + return; + } + ++ PHP_LIBXML_SANITIZE_GLOBALS(parse); + xmlRelaxNGSetParserErrors(parser, + (xmlRelaxNGValidityErrorFunc) php_libxml_error_handler, + (xmlRelaxNGValidityWarningFunc) php_libxml_error_handler, + parser); + sptr = xmlRelaxNGParse(parser); + xmlRelaxNGFreeParserCtxt(parser); ++ PHP_LIBXML_RESTORE_GLOBALS(parse); + if (!sptr) { + php_error_docref(NULL, E_WARNING, "Invalid RelaxNG"); + RETURN_FALSE; +@@ -2042,6 +2056,7 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ + ctxt->sax->error = php_libxml_ctx_error; + ctxt->sax->warning = php_libxml_ctx_warning; + } ++ php_libxml_sanitize_parse_ctxt_options(ctxt); + if (options) { + htmlCtxtUseOptions(ctxt, (int)options); + } +diff --git a/ext/dom/documentfragment.c b/ext/dom/documentfragment.c +index 0c289565a2..f12d191ddf 100644 +--- a/ext/dom/documentfragment.c ++++ b/ext/dom/documentfragment.c +@@ -132,7 +132,9 @@ PHP_METHOD(domdocumentfragment, appendXML) { + } + + if (data) { ++ PHP_LIBXML_SANITIZE_GLOBALS(parse); + err = xmlParseBalancedChunkMemory(nodep->doc, NULL, NULL, 0, (xmlChar *) data, &lst); ++ PHP_LIBXML_RESTORE_GLOBALS(parse); + if (err != 0) { + RETURN_FALSE; + } +diff --git a/ext/dom/tests/libxml_global_state_entity_loader_bypass.phpt b/ext/dom/tests/libxml_global_state_entity_loader_bypass.phpt +new file mode 100644 +index 0000000000..b28afd4694 +--- /dev/null ++++ b/ext/dom/tests/libxml_global_state_entity_loader_bypass.phpt +@@ -0,0 +1,36 @@ ++--TEST-- ++GHSA-3qrf-m4j2-pcrr (libxml global state entity loader bypass) ++--SKIPIF-- ++<?php ++if (!extension_loaded('libxml')) die('skip libxml extension not available'); ++if (!extension_loaded('dom')) die('skip dom extension not available'); ++if (!extension_loaded('zend-test')) die('skip zend-test extension not available'); ++?> ++--FILE-- ++<?php ++ ++$xml = "<?xml version='1.0'?><!DOCTYPE root [<!ENTITY % bork SYSTEM \"php://nope\"> %bork;]><nothing/>"; ++ ++libxml_use_internal_errors(true); ++ ++function parseXML($xml) { ++ $doc = new DOMDocument(); ++ @$doc->loadXML($xml); ++ $doc->createDocumentFragment()->appendXML("&bork;"); ++ foreach (libxml_get_errors() as $error) { ++ var_dump(trim($error->message)); ++ } ++} ++ ++parseXML($xml); ++zend_test_override_libxml_global_state(); ++parseXML($xml); ++ ++echo "Done\n"; ++ ++?> ++--EXPECT-- ++string(25) "Entity 'bork' not defined" ++string(25) "Entity 'bork' not defined" ++string(25) "Entity 'bork' not defined" ++Done +diff --git a/ext/libxml/php_libxml.h b/ext/libxml/php_libxml.h +index 7cc7271db2..bb2ef2d606 100644 +--- a/ext/libxml/php_libxml.h ++++ b/ext/libxml/php_libxml.h +@@ -120,6 +120,42 @@ PHP_LIBXML_API void php_libxml_shutdown(void); + ZEND_TSRMLS_CACHE_EXTERN() + #endif + ++/* Other extension may override the global state options, these global options ++ * are copied initially to ctxt->options. Set the options to a known good value. ++ * See libxml2 globals.c and parserInternals.c. ++ * The unique_name argument allows multiple sanitizes and restores within the ++ * same function, even nested is necessary. */ ++#define PHP_LIBXML_SANITIZE_GLOBALS(unique_name) \ ++ int xml_old_loadsubset_##unique_name = xmlLoadExtDtdDefaultValue; \ ++ xmlLoadExtDtdDefaultValue = 0; \ ++ int xml_old_validate_##unique_name = xmlDoValidityCheckingDefaultValue; \ ++ xmlDoValidityCheckingDefaultValue = 0; \ ++ int xml_old_pedantic_##unique_name = xmlPedanticParserDefault(0); \ ++ int xml_old_substitute_##unique_name = xmlSubstituteEntitiesDefault(0); \ ++ int xml_old_linenrs_##unique_name = xmlLineNumbersDefault(0); \ ++ int xml_old_blanks_##unique_name = xmlKeepBlanksDefault(1); ++ ++#define PHP_LIBXML_RESTORE_GLOBALS(unique_name) \ ++ xmlLoadExtDtdDefaultValue = xml_old_loadsubset_##unique_name; \ ++ xmlDoValidityCheckingDefaultValue = xml_old_validate_##unique_name; \ ++ (void) xmlPedanticParserDefault(xml_old_pedantic_##unique_name); \ ++ (void) xmlSubstituteEntitiesDefault(xml_old_substitute_##unique_name); \ ++ (void) xmlLineNumbersDefault(xml_old_linenrs_##unique_name); \ ++ (void) xmlKeepBlanksDefault(xml_old_blanks_##unique_name); ++ ++/* Alternative for above, working directly on the context and not setting globals. ++ * Generally faster because no locking is involved, and this has the advantage that it sets the options to a known good value. */ ++static zend_always_inline void php_libxml_sanitize_parse_ctxt_options(xmlParserCtxtPtr ctxt) ++{ ++ ctxt->loadsubset = 0; ++ ctxt->validate = 0; ++ ctxt->pedantic = 0; ++ ctxt->replaceEntities = 0; ++ ctxt->linenumbers = 0; ++ ctxt->keepBlanks = 1; ++ ctxt->options = 0; ++} ++ + #else /* HAVE_LIBXML */ + #define libxml_module_ptr NULL + #endif +diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c +index ab394b5c83..de718ced93 100644 +--- a/ext/simplexml/simplexml.c ++++ b/ext/simplexml/simplexml.c +@@ -2175,7 +2175,9 @@ PHP_FUNCTION(simplexml_load_file) + RETURN_FALSE; + } + ++ PHP_LIBXML_SANITIZE_GLOBALS(read_file); + docp = xmlReadFile(filename, NULL, (int)options); ++ PHP_LIBXML_RESTORE_GLOBALS(read_file); + + if (!docp) { + RETURN_FALSE; +@@ -2229,7 +2231,9 @@ PHP_FUNCTION(simplexml_load_string) + RETURN_FALSE; + } + ++ PHP_LIBXML_SANITIZE_GLOBALS(read_memory); + docp = xmlReadMemory(data, (int)data_len, NULL, NULL, (int)options); ++ PHP_LIBXML_RESTORE_GLOBALS(read_memory); + + if (!docp) { + RETURN_FALSE; +@@ -2279,7 +2283,9 @@ SXE_METHOD(__construct) + return; + } + ++ PHP_LIBXML_SANITIZE_GLOBALS(read_file_or_memory); + docp = is_url ? xmlReadFile(data, NULL, (int)options) : xmlReadMemory(data, (int)data_len, NULL, NULL, (int)options); ++ PHP_LIBXML_RESTORE_GLOBALS(read_file_or_memory); + + if (!docp) { + ((php_libxml_node_object *)sxe)->document = NULL; +diff --git a/ext/simplexml/tests/libxml_global_state_entity_loader_bypass.phpt b/ext/simplexml/tests/libxml_global_state_entity_loader_bypass.phpt +new file mode 100644 +index 0000000000..2152e01232 +--- /dev/null ++++ b/ext/simplexml/tests/libxml_global_state_entity_loader_bypass.phpt +@@ -0,0 +1,36 @@ ++--TEST-- ++GHSA-3qrf-m4j2-pcrr (libxml global state entity loader bypass) ++--SKIPIF-- ++<?php ++if (!extension_loaded('libxml')) die('skip libxml extension not available'); ++if (!extension_loaded('simplexml')) die('skip simplexml extension not available'); ++if (!extension_loaded('zend-test')) die('skip zend-test extension not available'); ++?> ++--FILE-- ++<?php ++ ++$xml = "<?xml version='1.0'?><!DOCTYPE root [<!ENTITY % bork SYSTEM \"php://nope\"> %bork;]><nothing/>"; ++ ++libxml_use_internal_errors(true); ++zend_test_override_libxml_global_state(); ++ ++echo "--- String test ---\n"; ++simplexml_load_string($xml); ++echo "--- Constructor test ---\n"; ++new SimpleXMLElement($xml); ++echo "--- File test ---\n"; ++file_put_contents("libxml_global_state_entity_loader_bypass.tmp", $xml); ++simplexml_load_file("libxml_global_state_entity_loader_bypass.tmp"); ++ ++echo "Done\n"; ++ ++?> ++--CLEAN-- ++<?php ++@unlink("libxml_global_state_entity_loader_bypass.tmp"); ++?> ++--EXPECT-- ++--- String test --- ++--- Constructor test --- ++--- File test --- ++Done +diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c +index a1ab525de3..7ebfbc2f71 100644 +--- a/ext/soap/php_xml.c ++++ b/ext/soap/php_xml.c +@@ -93,6 +93,7 @@ xmlDocPtr soap_xmlParseFile(const char *filename) + if (ctxt) { + zend_bool old; + ++ php_libxml_sanitize_parse_ctxt_options(ctxt); + ctxt->keepBlanks = 0; + ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace; + ctxt->sax->comment = soap_Comment; +@@ -143,6 +144,7 @@ xmlDocPtr soap_xmlParseMemory(const void *buf, size_t buf_size) + if (ctxt) { + zend_bool old; + ++ php_libxml_sanitize_parse_ctxt_options(ctxt); + ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace; + ctxt->sax->comment = soap_Comment; + ctxt->sax->warning = NULL; +diff --git a/ext/xml/compat.c b/ext/xml/compat.c +index 450bb1b52c..82dff1f75a 100644 +--- a/ext/xml/compat.c ++++ b/ext/xml/compat.c +@@ -19,6 +19,7 @@ + #include "php.h" + #if defined(HAVE_LIBXML) && (defined(HAVE_XML) || defined(HAVE_XMLRPC)) && !defined(HAVE_LIBEXPAT) + #include "expat_compat.h" ++#include "ext/libxml/php_libxml.h" + + typedef struct _php_xml_ns { + xmlNsPtr nsptr; +@@ -476,6 +477,7 @@ XML_ParserCreate_MM(const XML_Char *encoding, const XML_Memory_Handling_Suite *m + parser->parser->charset = XML_CHAR_ENCODING_NONE; + #endif + ++ php_libxml_sanitize_parse_ctxt_options(parser->parser); + #if LIBXML_VERSION >= 20703 + xmlCtxtUseOptions(parser->parser, XML_PARSE_OLDSAX); + #endif +diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c +index e03273709f..ee219aea36 100644 +--- a/ext/xmlreader/php_xmlreader.c ++++ b/ext/xmlreader/php_xmlreader.c +@@ -290,6 +290,7 @@ static xmlRelaxNGPtr _xmlreader_get_relaxNG(char *source, size_t source_len, siz + return NULL; + } + ++ PHP_LIBXML_SANITIZE_GLOBALS(parse); + if (error_func || warn_func) { + xmlRelaxNGSetParserErrors(parser, + (xmlRelaxNGValidityErrorFunc) error_func, +@@ -298,6 +299,7 @@ static xmlRelaxNGPtr _xmlreader_get_relaxNG(char *source, size_t source_len, siz + } + sptr = xmlRelaxNGParse(parser); + xmlRelaxNGFreeParserCtxt(parser); ++ PHP_LIBXML_RESTORE_GLOBALS(parse); + + return sptr; + } +@@ -870,7 +872,9 @@ PHP_METHOD(xmlreader, open) + valid_file = _xmlreader_get_valid_file_path(source, resolved_path, MAXPATHLEN ); + + if (valid_file) { ++ PHP_LIBXML_SANITIZE_GLOBALS(reader_for_file); + reader = xmlReaderForFile(valid_file, encoding, options); ++ PHP_LIBXML_RESTORE_GLOBALS(reader_for_file); + } + + if (reader == NULL) { +@@ -948,7 +952,9 @@ PHP_METHOD(xmlreader, setSchema) + + intern = Z_XMLREADER_P(id); + if (intern && intern->ptr) { ++ PHP_LIBXML_SANITIZE_GLOBALS(schema); + retval = xmlTextReaderSchemaValidate(intern->ptr, source); ++ PHP_LIBXML_RESTORE_GLOBALS(schema); + + if (retval == 0) { + RETURN_TRUE; +@@ -1068,6 +1074,7 @@ PHP_METHOD(xmlreader, XML) + } + uri = (char *) xmlCanonicPath((const xmlChar *) resolved_path); + } ++ PHP_LIBXML_SANITIZE_GLOBALS(text_reader); + reader = xmlNewTextReader(inputbfr, uri); + + if (reader != NULL) { +@@ -1088,9 +1095,11 @@ PHP_METHOD(xmlreader, XML) + xmlFree(uri); + } + ++ PHP_LIBXML_RESTORE_GLOBALS(text_reader); + return; + } + } ++ PHP_LIBXML_RESTORE_GLOBALS(text_reader); + } + + if (uri) { +diff --git a/ext/xmlreader/tests/libxml_global_state_entity_loader_bypass.phpt b/ext/xmlreader/tests/libxml_global_state_entity_loader_bypass.phpt +new file mode 100644 +index 0000000000..e9ffb04c2b +--- /dev/null ++++ b/ext/xmlreader/tests/libxml_global_state_entity_loader_bypass.phpt +@@ -0,0 +1,35 @@ ++--TEST-- ++GHSA-3qrf-m4j2-pcrr (libxml global state entity loader bypass) ++--SKIPIF-- ++<?php ++if (!extension_loaded('libxml')) die('skip libxml extension not available'); ++if (!extension_loaded('xmlreader')) die('skip xmlreader extension not available'); ++if (!extension_loaded('zend-test')) die('skip zend-test extension not available'); ++?> ++--FILE-- ++<?php ++ ++$xml = "<?xml version='1.0'?><!DOCTYPE root [<!ENTITY % bork SYSTEM \"php://nope\"> %bork;]><nothing/>"; ++ ++libxml_use_internal_errors(true); ++zend_test_override_libxml_global_state(); ++ ++echo "--- String test ---\n"; ++$reader = XMLReader::xml($xml); ++$reader->read(); ++echo "--- File test ---\n"; ++file_put_contents("libxml_global_state_entity_loader_bypass.tmp", $xml); ++$reader = XMLReader::open("libxml_global_state_entity_loader_bypass.tmp"); ++$reader->read(); ++ ++echo "Done\n"; ++ ++?> ++--CLEAN-- ++<?php ++@unlink("libxml_global_state_entity_loader_bypass.tmp"); ++?> ++--EXPECT-- ++--- String test --- ++--- File test --- ++Done +diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c +index 182aab68d6..af72dab248 100644 +--- a/ext/xsl/xsltprocessor.c ++++ b/ext/xsl/xsltprocessor.c +@@ -395,7 +395,7 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet) + xmlDoc *doc = NULL, *newdoc = NULL; + xsltStylesheetPtr sheetp, oldsheetp; + xsl_object *intern; +- int prevSubstValue, prevExtDtdValue, clone_docu = 0; ++ int clone_docu = 0; + xmlNode *nodep = NULL; + zval *cloneDocu, member, rv; + +@@ -417,13 +417,12 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet) + stylesheet document otherwise the node proxies will be a mess */ + newdoc = xmlCopyDoc(doc, 1); + xmlNodeSetBase((xmlNodePtr) newdoc, (xmlChar *)doc->URL); +- prevSubstValue = xmlSubstituteEntitiesDefault(1); +- prevExtDtdValue = xmlLoadExtDtdDefaultValue; ++ PHP_LIBXML_SANITIZE_GLOBALS(parse); ++ xmlSubstituteEntitiesDefault(1); + xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS; + + sheetp = xsltParseStylesheetDoc(newdoc); +- xmlSubstituteEntitiesDefault(prevSubstValue); +- xmlLoadExtDtdDefaultValue = prevExtDtdValue; ++ PHP_LIBXML_RESTORE_GLOBALS(parse); + + if (!sheetp) { + xmlFreeDoc(newdoc); +-- +2.41.0 + +From 79a97d0e2b93c40c3728d587046266989c5acc42 Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Tue, 1 Aug 2023 07:37:25 +0200 +Subject: [PATCH 3/4] backport zend_test changes + (zend_test_override_libxml_global_state) + +(cherry picked from commit 24e669e790e6aebd219c9a9fa19017455c8646b4) +--- + ...xml_global_state_entity_loader_bypass.phpt | 1 + + ...xml_global_state_entity_loader_bypass.phpt | 1 + + ...xml_global_state_entity_loader_bypass.phpt | 5 +++-- + ext/zend_test/test.c | 22 +++++++++++++++++++ + 4 files changed, 27 insertions(+), 2 deletions(-) + +diff --git a/ext/dom/tests/libxml_global_state_entity_loader_bypass.phpt b/ext/dom/tests/libxml_global_state_entity_loader_bypass.phpt +index b28afd4694..7fc2a249ac 100644 +--- a/ext/dom/tests/libxml_global_state_entity_loader_bypass.phpt ++++ b/ext/dom/tests/libxml_global_state_entity_loader_bypass.phpt +@@ -5,6 +5,7 @@ GHSA-3qrf-m4j2-pcrr (libxml global state entity loader bypass) + if (!extension_loaded('libxml')) die('skip libxml extension not available'); + if (!extension_loaded('dom')) die('skip dom extension not available'); + if (!extension_loaded('zend-test')) die('skip zend-test extension not available'); ++if (!function_exists('zend_test_override_libxml_global_state')) die('skip not for Windows'); + ?> + --FILE-- + <?php +diff --git a/ext/simplexml/tests/libxml_global_state_entity_loader_bypass.phpt b/ext/simplexml/tests/libxml_global_state_entity_loader_bypass.phpt +index 2152e01232..54f9d4941e 100644 +--- a/ext/simplexml/tests/libxml_global_state_entity_loader_bypass.phpt ++++ b/ext/simplexml/tests/libxml_global_state_entity_loader_bypass.phpt +@@ -5,6 +5,7 @@ GHSA-3qrf-m4j2-pcrr (libxml global state entity loader bypass) + if (!extension_loaded('libxml')) die('skip libxml extension not available'); + if (!extension_loaded('simplexml')) die('skip simplexml extension not available'); + if (!extension_loaded('zend-test')) die('skip zend-test extension not available'); ++if (!function_exists('zend_test_override_libxml_global_state')) die('skip not for Windows'); + ?> + --FILE-- + <?php +diff --git a/ext/xmlreader/tests/libxml_global_state_entity_loader_bypass.phpt b/ext/xmlreader/tests/libxml_global_state_entity_loader_bypass.phpt +index e9ffb04c2b..b0120b325e 100644 +--- a/ext/xmlreader/tests/libxml_global_state_entity_loader_bypass.phpt ++++ b/ext/xmlreader/tests/libxml_global_state_entity_loader_bypass.phpt +@@ -5,6 +5,7 @@ GHSA-3qrf-m4j2-pcrr (libxml global state entity loader bypass) + if (!extension_loaded('libxml')) die('skip libxml extension not available'); + if (!extension_loaded('xmlreader')) die('skip xmlreader extension not available'); + if (!extension_loaded('zend-test')) die('skip zend-test extension not available'); ++if (!function_exists('zend_test_override_libxml_global_state')) die('skip not for Windows'); + ?> + --FILE-- + <?php +@@ -15,11 +16,11 @@ libxml_use_internal_errors(true); + zend_test_override_libxml_global_state(); + + echo "--- String test ---\n"; +-$reader = XMLReader::xml($xml); ++$reader = @XMLReader::xml($xml); + $reader->read(); + echo "--- File test ---\n"; + file_put_contents("libxml_global_state_entity_loader_bypass.tmp", $xml); +-$reader = XMLReader::open("libxml_global_state_entity_loader_bypass.tmp"); ++$reader = @XMLReader::open("libxml_global_state_entity_loader_bypass.tmp"); + $reader->read(); + + echo "Done\n"; +diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c +index 87dcc90220..7f605773b7 100644 +--- a/ext/zend_test/test.c ++++ b/ext/zend_test/test.c +@@ -25,6 +25,11 @@ + #include "ext/standard/info.h" + #include "php_test.h" + ++#if defined(HAVE_LIBXML) && !defined(PHP_WIN32) ++# include <libxml/globals.h> ++# include <libxml/parser.h> ++#endif ++ + static zend_class_entry *zend_test_interface; + static zend_class_entry *zend_test_class; + static zend_class_entry *zend_test_child_class; +@@ -48,6 +53,20 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_leak_variable, 0, 0, 1) + ZEND_ARG_INFO(0, variable) + ZEND_END_ARG_INFO() + ++#if defined(HAVE_LIBXML) && !defined(PHP_WIN32) ++static ZEND_FUNCTION(zend_test_override_libxml_global_state) ++{ ++ ZEND_PARSE_PARAMETERS_NONE(); ++ ++ xmlLoadExtDtdDefaultValue = 1; ++ xmlDoValidityCheckingDefaultValue = 1; ++ (void) xmlPedanticParserDefault(1); ++ (void) xmlSubstituteEntitiesDefault(1); ++ (void) xmlLineNumbersDefault(1); ++ (void) xmlKeepBlanksDefault(0); ++} ++#endif ++ + ZEND_FUNCTION(zend_test_func) + { + /* dummy */ +@@ -266,6 +285,9 @@ static const zend_function_entry zend_test_functions[] = { + ZEND_FE(zend_terminate_string, arginfo_zend_terminate_string) + ZEND_FE(zend_leak_bytes, NULL) + ZEND_FE(zend_leak_variable, arginfo_zend_leak_variable) ++#if defined(HAVE_LIBXML) && !defined(PHP_WIN32) ++ ZEND_FE(zend_test_override_libxml_global_state, NULL) ++#endif + ZEND_FE_END + }; + +-- +2.41.0 + +From 3cf7c2b10e577136b267f2d90bfdff6743271c5c Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Tue, 1 Aug 2023 07:22:33 +0200 +Subject: [PATCH 4/4] NEWS + +(cherry picked from commit ef1d507acf7be23d7624dc3c891683b2218feb51) +--- + NEWS | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/NEWS b/NEWS +index 1950d841a5..05d9ca8f4c 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,6 +1,16 @@ + PHP NEWS + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + ++Backported from 8.0.30 ++ ++- Libxml: ++ . Fixed bug GHSA-3qrf-m4j2-pcrr (Security issue with external entity loading ++ in XML without enabling it). (CVE-2023-3823) (nielsdos, ilutov) ++ ++- Phar: ++ . Fixed bug GHSA-jqcx-ccgc-xwhv (Buffer mismanagement in phar_dir_read()). ++ (CVE-2023-3824) (nielsdos) ++ + Backported from 8.0.29 + + - Soap: +-- +2.41.0 + diff --git a/php-cve-2024-2756.patch b/php-cve-2024-2756.patch new file mode 100644 index 0000000..a8607d9 --- /dev/null +++ b/php-cve-2024-2756.patch @@ -0,0 +1,195 @@ +From 46b570a1e4aeb4a414898fcc09503ac388d16256 Mon Sep 17 00:00:00 2001 +From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> +Date: Sun, 17 Mar 2024 21:04:47 +0100 +Subject: [PATCH 1/4] Fix GHSA-wpj3-hf5j-x4v4: __Host-/__Secure- cookie bypass + due to partial CVE-2022-31629 fix + +The check happened too early as later code paths may perform more +mangling rules. Move the check downwards right before adding the actual +variable. + +(cherry picked from commit 093c08af25fb323efa0c8e6154aa9fdeae3d3b53) +(cherry picked from commit 2e07a3acd7a6b53c55325b94bed97748d7697b53) +(cherry picked from commit a6c1c62a25ac23b08a86af11d68f0e2eaafc102b) +--- + ext/standard/tests/ghsa-wpj3-hf5j-x4v4.phpt | 63 +++++++++++++++++++++ + main/php_variables.c | 41 +++++++++----- + 2 files changed, 90 insertions(+), 14 deletions(-) + create mode 100644 ext/standard/tests/ghsa-wpj3-hf5j-x4v4.phpt + +diff --git a/ext/standard/tests/ghsa-wpj3-hf5j-x4v4.phpt b/ext/standard/tests/ghsa-wpj3-hf5j-x4v4.phpt +new file mode 100644 +index 0000000000..77fcb68089 +--- /dev/null ++++ b/ext/standard/tests/ghsa-wpj3-hf5j-x4v4.phpt +@@ -0,0 +1,63 @@ ++--TEST-- ++ghsa-wpj3-hf5j-x4v4 (__Host-/__Secure- cookie bypass due to partial CVE-2022-31629 fix) ++--COOKIE-- ++..Host-test=ignore_1; ++._Host-test=ignore_2; ++.[Host-test=ignore_3; ++_.Host-test=ignore_4; ++__Host-test=ignore_5; ++_[Host-test=ignore_6; ++[.Host-test=ignore_7; ++[_Host-test=ignore_8; ++[[Host-test=ignore_9; ++..Host-test[]=ignore_10; ++._Host-test[]=ignore_11; ++.[Host-test[]=ignore_12; ++_.Host-test[]=ignore_13; ++__Host-test[]=legitimate_14; ++_[Host-test[]=legitimate_15; ++[.Host-test[]=ignore_16; ++[_Host-test[]=ignore_17; ++[[Host-test[]=ignore_18; ++..Secure-test=ignore_1; ++._Secure-test=ignore_2; ++.[Secure-test=ignore_3; ++_.Secure-test=ignore_4; ++__Secure-test=ignore_5; ++_[Secure-test=ignore_6; ++[.Secure-test=ignore_7; ++[_Secure-test=ignore_8; ++[[Secure-test=ignore_9; ++..Secure-test[]=ignore_10; ++._Secure-test[]=ignore_11; ++.[Secure-test[]=ignore_12; ++_.Secure-test[]=ignore_13; ++__Secure-test[]=legitimate_14; ++_[Secure-test[]=legitimate_15; ++[.Secure-test[]=ignore_16; ++[_Secure-test[]=ignore_17; ++[[Secure-test[]=ignore_18; ++--FILE-- ++<?php ++var_dump($_COOKIE); ++?> ++--EXPECT-- ++array(3) { ++ ["__Host-test"]=> ++ array(1) { ++ [0]=> ++ string(13) "legitimate_14" ++ } ++ ["_"]=> ++ array(2) { ++ ["Host-test["]=> ++ string(13) "legitimate_15" ++ ["Secure-test["]=> ++ string(13) "legitimate_15" ++ } ++ ["__Secure-test"]=> ++ array(1) { ++ [0]=> ++ string(13) "legitimate_14" ++ } ++} +diff --git a/main/php_variables.c b/main/php_variables.c +index f2d0c3bd98..d0ebd50ec8 100644 +--- a/main/php_variables.c ++++ b/main/php_variables.c +@@ -65,6 +65,21 @@ static zend_always_inline void php_register_variable_quick(const char *name, siz + zend_string_release_ex(key, 0); + } + ++/* Discard variable if mangling made it start with __Host-, where pre-mangling it did not start with __Host- ++ * Discard variable if mangling made it start with __Secure-, where pre-mangling it did not start with __Secure- */ ++static zend_bool php_is_forbidden_variable_name(const char *mangled_name, size_t mangled_name_len, const char *pre_mangled_name) ++{ ++ if (mangled_name_len >= sizeof("__Host-")-1 && strncmp(mangled_name, "__Host-", sizeof("__Host-")-1) == 0 && strncmp(pre_mangled_name, "__Host-", sizeof("__Host-")-1) != 0) { ++ return 1; ++ } ++ ++ if (mangled_name_len >= sizeof("__Secure-")-1 && strncmp(mangled_name, "__Secure-", sizeof("__Secure-")-1) == 0 && strncmp(pre_mangled_name, "__Secure-", sizeof("__Secure-")-1) != 0) { ++ return 1; ++ } ++ ++ return 0; ++} ++ + PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars_array) + { + char *p = NULL; +@@ -115,20 +130,6 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars + } + var_len = p - var; + +- /* Discard variable if mangling made it start with __Host-, where pre-mangling it did not start with __Host- */ +- if (strncmp(var, "__Host-", sizeof("__Host-")-1) == 0 && strncmp(var_name, "__Host-", sizeof("__Host-")-1) != 0) { +- zval_ptr_dtor_nogc(val); +- free_alloca(var_orig, use_heap); +- return; +- } +- +- /* Discard variable if mangling made it start with __Secure-, where pre-mangling it did not start with __Secure- */ +- if (strncmp(var, "__Secure-", sizeof("__Secure-")-1) == 0 && strncmp(var_name, "__Secure-", sizeof("__Secure-")-1) != 0) { +- zval_ptr_dtor_nogc(val); +- free_alloca(var_orig, use_heap); +- return; +- } +- + if (var_len==0) { /* empty variable name, or variable name with a space in it */ + zval_ptr_dtor_nogc(val); + free_alloca(var_orig, use_heap); +@@ -226,6 +227,12 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars + return; + } + } else { ++ if (php_is_forbidden_variable_name(index, index_len, var_name)) { ++ zval_ptr_dtor_nogc(val); ++ free_alloca(var_orig, use_heap); ++ return; ++ } ++ + gpc_element_p = zend_symtable_str_find(symtable1, index, index_len); + if (!gpc_element_p) { + zval tmp; +@@ -263,6 +270,12 @@ plain_var: + zval_ptr_dtor_nogc(val); + } + } else { ++ if (php_is_forbidden_variable_name(index, index_len, var_name)) { ++ zval_ptr_dtor_nogc(val); ++ free_alloca(var_orig, use_heap); ++ return; ++ } ++ + zend_ulong idx; + + /* +-- +2.44.0 + +From 8642473b624f809b768180b104c013f74e3a99a0 Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Wed, 10 Apr 2024 08:59:32 +0200 +Subject: [PATCH 2/4] NEWS + +(cherry picked from commit 366cc249b7d54707572beb7096e8f6c65ee79719) +(cherry picked from commit dcdd49ef3bfbd8ccc778850d6a0f9b98adf625d4) +--- + NEWS | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/NEWS b/NEWS +index 05d9ca8f4c..e26f978213 100644 +--- a/NEWS ++++ b/NEWS +@@ -1,6 +1,12 @@ + PHP NEWS + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + ++Backported from 8.1.28 ++ ++- Standard: ++ . Fixed bug GHSA-wpj3-hf5j-x4v4 (__Host-/__Secure- cookie bypass due to ++ partial CVE-2022-31629 fix). (CVE-2024-2756) (nielsdos) ++ + Backported from 8.0.30 + + - Libxml: +-- +2.44.0 + diff --git a/php-cve-2024-3096.patch b/php-cve-2024-3096.patch new file mode 100644 index 0000000..7b2cc15 --- /dev/null +++ b/php-cve-2024-3096.patch @@ -0,0 +1,83 @@ +From 747100905eceffb1f67096b437001e42900eb6bb Mon Sep 17 00:00:00 2001 +From: Jakub Zelenka <bukka@php.net> +Date: Fri, 29 Mar 2024 15:27:59 +0000 +Subject: [PATCH 3/4] Fix bug GHSA-q6x7-frmf-grcw: password_verify can + erroneously return true + +Disallow null character in bcrypt password + +(cherry picked from commit 0ba5229a3f7572846e91c8f5382e87785f543826) +(cherry picked from commit 81794c73068d9a44bf109bbcc9793e7b56a1c051) +(cherry picked from commit 4a7ceb9d6427f8d368f1a8739267b1f8310ec201) +--- + ext/standard/password.c | 5 +++++ + ext/standard/tests/password/password_bcrypt_errors.phpt | 6 ++++++ + 2 files changed, 11 insertions(+) + +diff --git a/ext/standard/password.c b/ext/standard/password.c +index 5cf0d397f5..79454e0a1e 100644 +--- a/ext/standard/password.c ++++ b/ext/standard/password.c +@@ -467,6 +467,11 @@ PHP_FUNCTION(password_hash) + cost = zval_get_long(option_buffer); + } + ++ if (memchr(ZSTR_VAL(password), '\0', ZSTR_LEN(password))) { ++ php_error_docref(NULL, E_WARNING, "Bcrypt password must not contain null character"); ++ RETURN_NULL(); ++ } ++ + if (cost < 4 || cost > 31) { + php_error_docref(NULL, E_WARNING, "Invalid bcrypt cost parameter specified: " ZEND_LONG_FMT, cost); + RETURN_NULL(); +diff --git a/ext/standard/tests/password/password_bcrypt_errors.phpt b/ext/standard/tests/password/password_bcrypt_errors.phpt +index a0826080e6..f95b72670a 100644 +--- a/ext/standard/tests/password/password_bcrypt_errors.phpt ++++ b/ext/standard/tests/password/password_bcrypt_errors.phpt +@@ -16,6 +16,8 @@ var_dump(password_hash("foo", PASSWORD_BCRYPT, array("salt" => 123))); + + var_dump(password_hash("foo", PASSWORD_BCRYPT, array("cost" => "foo"))); + ++var_dump(password_hash("null\0password", PASSWORD_BCRYPT)); ++ + ?> + --EXPECTF-- + Warning: password_hash(): Invalid bcrypt cost parameter specified: 3 in %s on line %d +@@ -41,3 +43,7 @@ NULL + + Warning: password_hash(): Invalid bcrypt cost parameter specified: 0 in %s on line %d + NULL ++ ++Warning: password_hash(): Bcrypt password must not contain null character in %s on line %d ++NULL ++ +-- +2.44.0 + +From fbeed182bb0b0c4c453e064198b5cc3814a10de0 Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Wed, 10 Apr 2024 09:01:09 +0200 +Subject: [PATCH 4/4] NEWS + +(cherry picked from commit 24f77904ee2259d722559f129f96a1f145a2367b) +(cherry picked from commit 027bdbc636632be49ecfad8d4191509faacb34ac) +--- + NEWS | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/NEWS b/NEWS +index e26f978213..6ad89d2e8e 100644 +--- a/NEWS ++++ b/NEWS +@@ -6,6 +6,8 @@ Backported from 8.1.28 + - Standard: + . Fixed bug GHSA-wpj3-hf5j-x4v4 (__Host-/__Secure- cookie bypass due to + partial CVE-2022-31629 fix). (CVE-2024-2756) (nielsdos) ++ . Fixed bug GHSA-h746-cjrr-wfmr (password_verify can erroneously return true, ++ opening ATO risk). (CVE-2024-3096) (Jakub Zelenka) + + Backported from 8.0.30 + +-- +2.44.0 + diff --git a/php-keyring.gpg b/php-keyring.gpg new file mode 100644 index 0000000..870d816 --- /dev/null +++ b/php-keyring.gpg @@ -0,0 +1,415 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +bh57GXdFtudEaKvQbGW9yalYwuj7Yip5XJGttg== +=XZOV +-----END PGP PUBLIC KEY BLOCK----- diff --git a/php-net-snmp.patch b/php-net-snmp.patch new file mode 100644 index 0000000..e30b223 --- /dev/null +++ b/php-net-snmp.patch @@ -0,0 +1,38 @@ +Backported from 8.0 for 7.3 by Remi + + +From f9fd3595ecb36c8dc6add0515782a18f15216d77 Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Thu, 27 May 2021 14:20:07 +0200 +Subject: [PATCH] Fix snmp build without DES + +--- + ext/snmp/snmp.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c +index 35d19c8738828..d31995827880d 100644 +--- a/ext/snmp/snmp.c ++++ b/ext/snmp/snmp.c +@@ -1229,15 +1229,19 @@ static int netsnmp_session_set_auth_prot + Set the security protocol in the snmpv3 session */ + static int netsnmp_session_set_sec_protocol(struct snmp_session *s, char *prot) + { ++#ifndef NETSNMP_DISABLE_DES + if (!strcasecmp(prot, "DES")) { + s->securityPrivProto = usmDESPrivProtocol; + s->securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN; ++ } else ++#endif + #ifdef HAVE_AES +- } else if (!strcasecmp(prot, "AES128") || !strcasecmp(prot, "AES")) { ++ if (!strcasecmp(prot, "AES128") || !strcasecmp(prot, "AES")) { + s->securityPrivProto = usmAESPrivProtocol; + s->securityPrivProtoLen = USM_PRIV_PROTO_AES_LEN; ++ } else + #endif +- } else { ++ { + php_error_docref(NULL, E_WARNING, "Unknown security protocol '%s'", prot); + return (-1); + } diff --git a/php-pcre1038.patch b/php-pcre1038.patch new file mode 100644 index 0000000..404db72 --- /dev/null +++ b/php-pcre1038.patch @@ -0,0 +1,27 @@ +From 56495ac031005f8b64e75c94e86ec942dd15aa74 Mon Sep 17 00:00:00 2001 +From: Remi Collet <remi@remirepo.net> +Date: Thu, 21 Oct 2021 10:38:16 +0200 +Subject: [PATCH] fix for pcre2 10.38 + +--- + ext/pcre/php_pcre.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c +index 19ea92713875..9d01b328228d 100644 +--- a/ext/pcre/php_pcre.c ++++ b/ext/pcre/php_pcre.c +@@ -169,7 +169,13 @@ static void php_pcre_free(void *block, void *data) + pefree(block, 1); + }/*}}}*/ + ++#ifdef PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK ++ /* pcre 10.38 needs PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK, disabled by default */ ++#define PHP_PCRE_DEFAULT_EXTRA_COPTIONS (PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL|PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) ++#else + #define PHP_PCRE_DEFAULT_EXTRA_COPTIONS PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL ++#endif ++ + #define PHP_PCRE_PREALLOC_MDATA_SIZE 32 + + static void php_pcre_init_pcre2(uint8_t jit) @@ -1322,7 +1322,8 @@ session.cookie_domain = session.cookie_httponly = ; Add SameSite attribute to cookie to help mitigate Cross-Site Request Forgery (CSRF/XSRF) -; Current valid values are "Lax" or "Strict" +; Current valid values are "Strict", "Lax" or "None". When using "None", +; make sure to include the quotes, as `none` is interpreted like `false` in ini files. ; https://tools.ietf.org/html/draft-west-first-party-cookies-07 session.cookie_samesite = @@ -1365,8 +1366,8 @@ session.gc_maxlifetime = 1440 ; (see session.save_path above), then garbage collection does *not* ; happen automatically. You will need to do your own garbage ; collection through a shell script, cron entry, or some other method. -; For example, the following script would is the equivalent of -; setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes): +; For example, the following script is the equivalent of setting +; session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes): ; find /path/to/sessions -cmin +24 -type f | xargs rm ; Check HTTP Referer to invalidate externally stored URLs containing ids. @@ -55,12 +55,14 @@ %global mysql_sock %(mysql_config --socket 2>/dev/null || echo /var/lib/mysql/mysql.sock) -%if 0%{?rhel} == 6 -%global oraclever 18.3 -%global oraclelib 18.1 -%else -%global oraclever 19.3 +%ifarch aarch64 +%global oraclever 19.19 %global oraclelib 19.1 +%global oracledir 19.19 +%else +%global oraclever 21.13 +%global oraclelib 21.1 +%global oracledir 21 %endif # Build for LiteSpeed Web Server (LSAPI) @@ -77,12 +79,7 @@ # Optional components; pass "--with mssql" etc to rpmbuild. %global with_oci8 %{?_with_oci8:1}%{!?_with_oci8:0} %global with_imap 1 -# until firebird available in EPEL -%if 0%{?rhel} == 8 -%global with_interbase 0 -%else %global with_interbase 1 -%endif %global with_freetds 1 %global with_tidy 1 %global with_sqlite3 1 @@ -131,13 +128,12 @@ %global db_devel libdb-devel %endif -%global upver 7.3.8 -#global rcver RC1 +%global upver 7.3.33 Summary: PHP scripting language for creating dynamic web sites Name: %{?scl_prefix}php Version: %{upver}%{?rcver:~%{rcver}} -Release: 1%{?dist} +Release: 13%{?dist} # All files licensed under PHP version 3.01, except # Zend is licensed under Zend # TSRM is licensed under BSD @@ -148,7 +144,7 @@ License: PHP and Zend and BSD and MIT and ASL 1.0 and NCSA Group: Development/Languages URL: http://www.php.net/ -Source0: http://www.php.net/distributions/php-%{upver}%{?rcver}.tar.xz +Source0: https://www.php.net/distributions/php-%{upver}%{?rcver}.tar.xz Source1: php.conf Source2: php.ini Source3: macros.php @@ -161,6 +157,9 @@ Source9: php.modconf Source10: php.conf2 Source11: php-fpm.init Source12: php-fpm.wants +# See https://secure.php.net/gpg-keys.php +Source20: https://www.php.net/distributions/php-keyring.gpg +Source21: https://www.php.net/distributions/php-%{upver}%{?rcver}.tar.xz.asc # Configuration files for some extensions Source50: 10-opcache.ini Source51: opcache-default.blacklist @@ -173,27 +172,53 @@ Patch6: php-5.6.3-embed.patch Patch7: php-5.3.0-recode.patch Patch8: php-7.2.0-libdb.patch Patch9: php-7.0.7-curl.patch +# backported from 8.0 +Patch10: php-net-snmp.patch # Functional changes Patch40: php-7.2.4-dlopen.patch -Patch42: php-7.3.3-systzdata-v18.patch +Patch42: php-7.3.3-systzdata-v19.patch # See http://bugs.php.net/53436 Patch43: php-7.3.0-phpize.patch # Use -lldap_r for OpenLDAP Patch45: php-7.2.3-ldap_r.patch -# Make php_config.h constant across builds -Patch46: php-7.2.4-fixheader.patch +# Make php_config.h constant across builds (from 7.4) +Patch46: php-7.3.20-fixheader.patch # drop "Configure command" from phpinfo output -Patch47: php-5.6.3-phpinfo.patch +# and add build system and provider (from 8.0) +Patch47: php-7.3.20-phpinfo.patch # backport PDOStatement::getColumnMeta from 7.4 Patch48: php-7.3.3-pdooci.patch +# backport FPM signals changes from 7.4 +# https://bugs.php.net/74083 master PHP-fpm is stopped on multiple reloads +Patch49: php-7.3.24-fpm.patch # RC Patch Patch91: php-7.2.0-oci8conf.patch # Upstream fixes (100+) +# Backported from 7.4.16 - opcache and pcre.jit +Patch100: php-bug80682.patch +# Backported from 7.4.18 - pdo_odbc +Patch101: php-bug80783.patch +# Backported from 7.4.26 for pcre >= 10.38 +Patch102: php-pcre1038.patch # Security fixes (200+) +Patch200: php-bug81719.patch +Patch201: php-bug81720.patch +Patch202: php-bug81727.patch +Patch203: php-bug81726.patch +Patch204: php-bug81738.patch +Patch205: php-bug81740.patch +Patch206: php-bug81744.patch +Patch207: php-bug81746.patch +Patch208: php-cve-2023-0662.patch +Patch209: php-cve-2023-3247.patch +Patch210: php-cve-2023-3823.patch +Patch211: php-cve-2023-3824.patch +Patch212: php-cve-2024-2756.patch +Patch213: php-cve-2024-3096.patch # Fixes for tests (300+) # Factory is droped from system tzdata @@ -201,6 +226,7 @@ Patch300: php-7.0.10-datetests.patch # WIP +BuildRequires: gnupg2 BuildRequires: bzip2-devel, curl-devel >= 7.9, %{db_devel} BuildRequires: httpd-devel >= 2.0.46-1, pam-devel %if %{with_httpd2410} @@ -219,12 +245,13 @@ BuildRequires: zlib-devel, smtpdaemon, libedit-devel %if %{with_libpcre} BuildRequires: pcre2-devel >= 10.30 %else -Provides: Provides: bundled(pcre2) = 10.32 +Provides: bundled(pcre2) = 10.32 %endif BuildRequires: bzip2 BuildRequires: perl BuildRequires: autoconf BuildRequires: automake +BuildRequires: make BuildRequires: %{?dtsprefix}gcc BuildRequires: %{?dtsprefix}gcc-c++ BuildRequires: libtool @@ -308,7 +335,6 @@ The %{?scl_prefix}php-dbg package contains the interactive PHP debugger. Group: Development/Languages Summary: PHP FastCGI Process Manager BuildRequires: libacl-devel -Requires(pre): %{_root_sbindir}/useradd Requires: %{?scl_prefix}php-common%{?_isa} = %{version}-%{release} %if %{with_systemd} BuildRequires: systemd-devel @@ -328,6 +354,8 @@ Requires(pre): httpd-filesystem # For php.conf in /etc/httpd/conf.d # and version 2.4.10 for proxy support in SetHandler Requires: httpd-filesystem >= 2.4.10 +%else +Requires(pre): %{_root_sbindir}/useradd %endif %description fpm @@ -367,6 +395,12 @@ Summary: Common files for PHP # fileinfo is licensed under PHP version 3.0 # regex, libmagic are licensed under BSD License: PHP and BSD + +%if %{with_libpcre} +%global pcre2_buildver %(pkg-config --silence-errors --modversion libpcre2-8 2>/dev/null || echo 10.30) +Requires: pcre2%{?_isa} >= %{pcre2_buildver} +%endif + # ABI/API check - Arch specific Provides: %{?scl_prefix}php(api) = %{apiver}%{isasuffix} Provides: %{?scl_prefix}php(zend-abi) = %{zendver}%{isasuffix} @@ -416,6 +450,7 @@ Requires: %{?scl_prefix}php-cli%{?_isa} = %{version}-%{release} # always needed to build extension Requires: autoconf Requires: automake +Requires: make Requires: gcc Requires: gcc-c++ Requires: libtool @@ -620,7 +655,14 @@ Summary: A module for PHP applications that use OCI8 databases Group: Development/Languages # All files licensed under PHP version 3.01 License: PHP +%ifarch aarch64 +BuildRequires: oracle-instantclient%{oraclever}-devel +# Should requires libclntsh.so.19.1()(aarch-64), but it's not provided by Oracle RPM. +Requires: libclntsh.so.%{oraclelib} +AutoReq: 0 +%else BuildRequires: oracle-instantclient-devel >= %{oraclever} +%endif Requires: %{?scl_prefix}php-pdo%{?_isa} = %{version}-%{release} Provides: %{?scl_prefix}php_database Provides: %{?scl_prefix}php-pdo_oci @@ -629,8 +671,6 @@ Obsoletes: %{?scl_prefix}php-pecl-oci8 <= %{oci8ver} Conflicts: %{?scl_prefix}php-pecl-oci8 > %{oci8ver} Provides: %{?scl_prefix}php-pecl(oci8) = %{oci8ver} Provides: %{?scl_prefix}php-pecl(oci8)%{?_isa} = %{oci8ver} -# Should requires libclntsh.so.18.3, but it's not provided by Oracle RPM. -AutoReq: 0 %description oci8 The %{?scl_prefix}php-oci8 packages provides the OCI8 extension version %{oci8ver} @@ -640,13 +680,9 @@ The extension is linked with Oracle client libraries %{oraclever} (Oracle Instant Client). For details, see Oracle's note "Oracle Client / Server Interoperability Support" (ID 207303.1). -You must install libclntsh.so.%{oraclelib} to use this package, provided -in the database installation, or in the free Oracle Instant Client -available from Oracle. - -Notice: -- %{?scl_prefix}php-oci8 provides oci8 and pdo_oci extensions from php sources. -- %{?scl_prefix}php-pecl-oci8 only provides oci8 extension. +You must install libclntsh.so.%{oraclelib} to use this package, +provided by Oracle Instant Client RPM available from Oracle on: +https://www.oracle.com/database/technologies/instant-client/downloads.html Documentation is at http://php.net/oci8 and http://php.net/pdo_oci %endif @@ -706,8 +742,11 @@ Group: Development/Languages # ucgendat is licensed under OpenLDAP License: PHP and LGPLv2 and BSD and OpenLDAP %if %{with_onig} -# ensure we have soname 5 -BuildRequires: oniguruma-devel >= 6.8 +%if 0%{?rhel} +BuildRequires: oniguruma5php-devel +%else +BuildRequires: oniguruma-devel +%endif %else Provides: bundled(oniguruma) = 6.9.0 %endif @@ -733,12 +772,7 @@ Requires: %{?scl_prefix}php-common%{?_isa} = %{version}-%{release} BuildRequires: libjpeg-devel, libpng-devel, freetype-devel BuildRequires: libXpm-devel %if %{with_libgd} -BuildRequires: gd-devel >= 2.1.1 -%if 0%{?fedora} <= 19 && 0%{?rhel} <= 7 -Requires: gd-last%{?_isa} >= 2.1.1 -%else -Requires: gd%{?_isa} >= 2.1.1 -%endif +BuildRequires: gd-devel >= 2.3.3 %else BuildRequires: libwebp-devel Provides: bundled(gd) = 2.0.35 @@ -849,8 +883,8 @@ Group: System Environment/Libraries # All files licensed under PHP version 3.01 License: PHP Requires: %{?scl_prefix}php-common%{?_isa} = %{version}-%{release} -# Upstream requires 4.0, we require 50 to ensure use of libicu-last / libicu62 -BuildRequires: libicu-devel >= 50 +# Upstream requires 4.0, we require 69.1 to ensure use of libicu69 +BuildRequires: libicu-devel = 69.1 %description intl @@ -920,6 +954,8 @@ low-level PHP extension for the libsodium cryptographic library. %prep +%{?gpgverify:%{gpgverify} --keyring='%{SOURCE20}' --signature='%{SOURCE21}' --data='%{SOURCE0}'} + : Building %{name}-%{version}-%{release} with systemd=%{with_systemd} imap=%{with_imap} interbase=%{with_interbase} freetds=%{with_freetds} sqlite3=%{with_sqlite3} tidy=%{with_tidy} zip=%{with_zip} %if 0%{?gh_date} %setup -q -n %{gh_project}-%{gh_commit} @@ -927,41 +963,60 @@ low-level PHP extension for the libsodium cryptographic library. %setup -q -n php-%{upver}%{?rcver} %endif -%patch1 -p1 -b .mpmcheck -%patch5 -p1 -b .includedir -%patch6 -p1 -b .embed -%patch7 -p1 -b .recode -%patch8 -p1 -b .libdb +%patch -P1 -p1 -b .mpmcheck +%patch -P5 -p1 -b .includedir +%patch -P6 -p1 -b .embed +%patch -P7 -p1 -b .recode +%patch -P8 -p1 -b .libdb %if 0%{?rhel} -%patch9 -p1 -b .curltls +%patch -P9 -p1 -b .curltls %endif +%patch -P10 -p1 -b .nodes -%patch40 -p1 -b .dlopen +%patch -P40 -p1 -b .dlopen %if 0%{?fedora} >= 28 || 0%{?rhel} >= 6 -%patch42 -p1 -b .systzdata +%patch -P42 -p1 -b .systzdata %endif -%patch43 -p1 -b .headers +%patch -P43 -p1 -b .headers sed -e 's/php-devel/%{?scl_prefix}php-devel/' -i scripts/phpize.in %if 0%{?fedora} >= 18 || 0%{?rhel} >= 7 -%patch45 -p1 -b .ldap_r +%patch -P45 -p1 -b .ldap_r %endif -%patch46 -p1 -b .fixheader -%patch47 -p1 -b .phpinfo -%patch48 -p1 -b .pdooci +%patch -P46 -p1 -b .fixheader +%patch -P47 -p1 -b .phpinfo +%patch -P48 -p1 -b .pdooci +%patch -P49 -p1 -b .fpmsig -%patch91 -p1 -b .remi-oci8 +%patch -P91 -p1 -b .remi-oci8 # upstream patches +%patch -P100 -p1 -b .bug80682 +%patch -P101 -p1 -b .bug80783 +%patch -P102 -p1 -b .pcre1038 # security patches +%patch -P200 -p1 -b .bug81719 +%patch -P201 -p1 -b .bug81720 +%patch -P202 -p1 -b .bug81727 +%patch -P203 -p1 -b .bug81726 +%patch -P204 -p1 -b .bug81738 +%patch -P205 -p1 -b .bug81740 +%patch -P206 -p1 -b .bug81744 +%patch -P207 -p1 -b .bug81746 +%patch -P208 -p1 -b .cve0662 +%patch -P209 -p1 -b .cve3247 +%patch -P210 -p1 -b .cve3823 +%patch -P211 -p1 -b .cve3824 +%patch -P212 -p1 -b .cve2756 +%patch -P213 -p1 -b .cve3096 # Fixes for tests -%patch300 -p1 -b .datetests +%patch -P300 -p1 -b .datetests # WIP patch # Prevent %%doc confusion over LICENSE files -cp Zend/LICENSE Zend/ZEND_LICENSE +cp Zend/LICENSE ZEND_LICENSE cp TSRM/LICENSE TSRM_LICENSE %if ! %{with_libgd} cp ext/gd/libgd/README libgd_README @@ -985,14 +1040,11 @@ mkdir \ # ----- Manage known as failed test ------- # affected by systzdata patch rm ext/date/tests/timezone_location_get.phpt -rm ext/date/tests/timezone_version_get.phpt -rm ext/date/tests/timezone_version_get_basic1.phpt -%if 0%{?fedora} < 28 -# need tzdata 2018i rm ext/date/tests/bug33414-1.phpt rm ext/date/tests/bug33415-2.phpt rm ext/date/tests/date_modify-1.phpt -%endif +# too fast builder +rm ext/date/tests/bug73837.phpt # fails sometime rm ext/sockets/tests/mcast_ipv?_recv.phpt # Should be skipped but fails sometime @@ -1100,10 +1152,21 @@ exit 1 %build +# This package fails to build with LTO due to undefined symbols. LTO +# was disabled in OpenSuSE as well, but with no real explanation why +# beyond the undefined symbols. It really shold be investigated further. +# Disable LTO +%define _lto_cflags %{nil} + %{?dtsenable} # Set build date from https://reproducible-builds.org/specs/source-date-epoch/ export SOURCE_DATE_EPOCH=$(date +%s -r NEWS) +export PHP_UNAME=$(uname) +export PHP_BUILD_SYSTEM=$(cat /etc/redhat-release | sed -e 's/ Beta//') +%if 0%{?vendor:1} +export PHP_BUILD_PROVIDER="%{vendor}" +%endif # aclocal workaround - to be improved cat $(aclocal --print-ac-dir)/{libtool,ltoptions,ltsugar,ltversion,lt~obsolete}.m4 >>aclocal.m4 @@ -1235,8 +1298,8 @@ build --libdir=%{_libdir}/php \ --with-mysqli=shared,mysqlnd \ --with-mysql-sock=%{mysql_sock} \ %if %{with_oci8} - --with-oci8=shared,instantclient,%{_root_libdir}/oracle/%{oraclever}/client64/lib,%{oraclever} \ - --with-pdo-oci=shared,instantclient,%{_root_libdir}/oracle/%{oraclever}/client64/lib,%{oraclever} \ + --with-oci8=shared,instantclient,%{_root_prefix}/lib/oracle/%{oracledir}/client64/lib,%{oraclever} \ + --with-pdo-oci=shared,instantclient,%{_root_prefix}/lib/oracle/%{oracledir}/client64/lib,%{oraclever} \ %endif %if %{with_interbase} --with-interbase=shared \ @@ -1298,6 +1361,7 @@ popd without_shared="--without-gd \ --disable-dom --disable-dba --without-unixODBC \ --disable-opcache \ + --disable-phpdbg \ --disable-json \ --disable-xmlreader --disable-xmlwriter \ --without-sodium \ @@ -1347,7 +1411,7 @@ popd %check %if %runselftest -cd build-apache +cd build-fpm # Run tests, using the CLI SAPI export NO_INTERACTION=1 REPORT_EXIT_STATUS=1 MALLOC_CHECK_=2 @@ -1462,8 +1526,8 @@ mv $RPM_BUILD_ROOT%{_sysconfdir}/php-fpm.d/www.conf.default . %if %{with_systemd} install -Dm 644 %{SOURCE6} $RPM_BUILD_ROOT%{_unitdir}/%{?scl_prefix}php-fpm.service %if 0%{?fedora} >= 27 || 0%{?rhel} >= 8 -install -Dm 644 %{SOURCE12} $RPM_BUILD_ROOT%{_unitdir}/httpd.service.d/%{?scl_prefix}php-fpm.conf -install -Dm 644 %{SOURCE12} $RPM_BUILD_ROOT%{_unitdir}/nginx.service.d/%{?scl_prefix}php-fpm.conf +install -Dm 644 %{SOURCE12} $RPM_BUILD_ROOT%{_root_sysconfdir}/systemd/system/httpd.service.d/%{?scl_prefix}php-fpm.conf +install -Dm 644 %{SOURCE12} $RPM_BUILD_ROOT%{_root_sysconfdir}/systemd/system/nginx.service.d/%{?scl_prefix}php-fpm.conf %endif sed -e 's:/run:%{_localstatedir}/run:' \ -e 's:/etc/sysconfig:%{_sysconfdir}/sysconfig:' \ @@ -1717,6 +1781,19 @@ fi %endif +%posttrans common +cat << EOF +===================================================================== + + WARNING : PHP 7.3 have reached its "End of Life" in + December 2021. Even, if this package includes some of + the important security fixes, backported from 8.0, the + UPGRADE to a maintained version is very strongly RECOMMENDED. + +===================================================================== +EOF + + %{!?_licensedir:%global license %%doc} %files @@ -1737,7 +1814,7 @@ fi %files common -f files.common %doc CODING_STANDARDS CREDITS EXTENSIONS NEWS README* -%license LICENSE TSRM_LICENSE +%license LICENSE TSRM_LICENSE ZEND_LICENSE %license libmagic_LICENSE %license timelib_LICENSE %doc php.ini-* @@ -1801,8 +1878,8 @@ fi %{_unitdir}/%{?scl_prefix}php-fpm.service %dir %{_root_sysconfdir}/systemd/system/%{?scl_prefix}php-fpm.service.d %if 0%{?fedora} >= 27 || 0%{?rhel} >= 8 -%{_unitdir}/httpd.service.d/%{?scl_prefix}php-fpm.conf -%{_unitdir}/nginx.service.d/%{?scl_prefix}php-fpm.conf +%config(noreplace) %{_root_sysconfdir}/systemd/system/httpd.service.d/%{?scl_prefix}php-fpm.conf +%config(noreplace) %{_root_sysconfdir}/systemd/system/nginx.service.d/%{?scl_prefix}php-fpm.conf %endif %else %{_root_initddir}/%{?scl_prefix}php-fpm @@ -1891,6 +1968,233 @@ fi %changelog +* Wed Apr 10 2024 Remi Collet <remi@remirepo.net> - 7.3.33-13 +- use oracle client library version 21.13 on x86_64, 19.19 on aarch64 +- Fix __Host-/__Secure- cookie bypass due to partial CVE-2022-31629 fix + CVE-2024-2756 +- Fix password_verify can erroneously return true opening ATO risk + CVE-2024-3096 + +* Thu Sep 21 2023 Remi Collet <remi@remirepo.net> - 7.3.33-12 +- use oracle client library version 21.11 on x86_64, 19.19 on aarch64 +- use official Oracle Instant Client RPM + +* Tue Aug 1 2023 Remi Collet <remi@remirepo.net> - 7.3.33-11 +- Fix Security issue with external entity loading in XML without enabling it + GHSA-3qrf-m4j2-pcrr CVE-2023-3823 +- Fix Buffer mismanagement in phar_dir_read() + GHSA-jqcx-ccgc-xwhv CVE-2023-3824 +- move httpd/nginx wants directive to config files in /etc + +* Tue Jun 20 2023 Remi Collet <remi@remirepo.net> - 7.3.33-10 +- fix possible buffer overflow in date +- define %%php73___phpize and %%php73___phpconfig + +* Wed Jun 7 2023 Remi Collet <remi@remirepo.net> - 7.3.33-9 +- Fix Missing error check and insufficient random bytes in HTTP Digest + authentication for SOAP + GHSA-76gg-c692-v2mw CVE-2023-3247 +- use oracle client library version 21.10 + +* Tue Feb 14 2023 Remi Collet <remi@remirepo.net> - 7.3.33-8 +- fix #81744: Password_verify() always return true with some hash + CVE-2023-0567 +- fix #81746: 1-byte array overrun in common path resolve code + CVE-2023-0568 +- fix DOS vulnerability when parsing multipart request body + CVE-2023-0662 +- add dependency on pcre2 minimal version + +* Mon Dec 19 2022 Remi Collet <remi@remirepo.net> - 7.3.33-7 +- pdo: fix #81740: PDO::quote() may return unquoted string + CVE-2022-31631 +- use oracle client library version 21.8 + +* Mon Oct 24 2022 Remi Collet <remi@remirepo.net> - 7.3.33-6 +- hash: fix #81738: buffer overflow in hash_update() on long parameter. + CVE-2022-37454 + +* Tue Sep 27 2022 Remi Collet <remi@remirepo.net> - 7.3.33-5 +- phar: fix #81726 DOS when using quine gzip file. CVE-2022-31628 +- core: fix #81727 Don't mangle HTTP variable names that clash with ones + that have a specific semantic meaning. CVE-2022-31629 +- use oracle client library version 21.7 + +* Tue Jun 7 2022 Remi Collet <remi@remirepo.net> - 7.3.33-3 +- use oracle client library version 21.6 +- mysqlnd: fix #81719: mysqlnd/pdo password buffer overflow. CVE-2022-31626 +- pgsql: fix #81720: Uninitialized array in pg_query_params(). CVE-2022-31625 +- pcre: fix default options for pcre >= 10.38 + +* Wed Feb 23 2022 Remi Collet <remi@remirepo.net> - 7.3.33-2 +- retrieve tzdata version +- use oracle client library version 21.5 + +* Tue Nov 16 2021 Remi Collet <remi@remirepo.net> - 7.3.33-1 +- Update to 7.3.33 - http://www.php.net/releases/7_3_33.php + +* Tue Oct 26 2021 Remi Collet <remi@remirepo.net> - 7.3.32-1 +- Update to 7.3.32 - http://www.php.net/releases/7_3_32.php + +* Wed Oct 20 2021 Remi Collet <remi@remirepo.net> - 7.3.31-2 +- fix PHP-FPM oob R/W in root process leading to priv escalation + CVE-2021-21703 +- use libicu version 69 + +* Tue Sep 21 2021 Remi Collet <remi@remirepo.net> - 7.3.31-1 +- Update to 7.3.31 - http://www.php.net/releases/7_3_31.php +- use oracle client library version 21.3 + +* Tue Aug 24 2021 Remi Collet <remi@remirepo.net> - 7.3.30-1 +- Update to 7.3.30 - http://www.php.net/releases/7_3_30.php + +* Tue Jun 29 2021 Remi Collet <remi@remirepo.net> - 7.3.29-1 +- Update to 7.3.29 - http://www.php.net/releases/7_3_29.php + +* Thu May 27 2021 Remi Collet <remi@remirepo.net> - 7.3.28-2 +- fix snmp extension build with net-snmp without DES + +* Tue Apr 27 2021 Remi Collet <remi@remirepo.net> - 7.3.28-1 +- Update to 7.3.28 - http://www.php.net/releases/7_3_28.php + +* Thu Apr 8 2021 Remi Collet <remi@remirepo.net> - 7.3.27-2 +- add upstream patch for https://bugs.php.net/80783 + PDO ODBC truncates BLOB records at every 256th byte +- use oracle client library version 21.1 + +* Tue Feb 2 2021 Remi Collet <remi@remirepo.net> - 7.3.27-1 +- Update to 7.3.27 - http://www.php.net/releases/7_3_27.php + +* Thu Jan 28 2021 Remi Collet <remi@remirepo.net> - 7.3.26-2 +- add upstream patch for https://bugs.php.net/80682 + fix opcache doesn't honour pcre.jit option + +* Tue Jan 5 2021 Remi Collet <remi@remirepo.net> - 7.3.26-1 +- Update to 7.3.26 - http://www.php.net/releases/7_3_26.php + +* Tue Dec 15 2020 Remi Collet <remi@remirepo.net> - 7.3.26~RC1-1 +- update to 7.3.26RC1 + +* Tue Nov 24 2020 Remi Collet <remi@remirepo.net> - 7.3.25-1 +- Update to 7.3.25 - http://www.php.net/releases/7_3_25.php +- use oracle client library version 19.9 (x86_64) + +* Tue Nov 10 2020 Remi Collet <remi@remirepo.net> - 7.3.25~RC1-1 +- update to 7.3.25RC1 + +* Tue Oct 27 2020 Remi Collet <remi@remirepo.net> - 7.3.24-1 +- Update to 7.3.24 - http://www.php.net/releases/7_3_24.php + +* Fri Oct 23 2020 Remi Collet <remi@remirepo.net> - 7.3.24~RC1-2 +- backport fix for https://bugs.php.net/74083 from 7.4 + master PHP-fpm is stopped on multiple reloads + +* Tue Oct 13 2020 Remi Collet <remi@remirepo.net> - 7.3.24~RC1-1 +- update to 7.3.24RC1 + +* Tue Sep 29 2020 Remi Collet <remi@remirepo.net> - 7.3.23-1 +- Update to 7.3.23 - http://www.php.net/releases/7_3_23.php + +* Tue Sep 15 2020 Remi Collet <remi@remirepo.net> - 7.3.23~RC1-1 +- update to 7.3.23RC1 + +* Tue Sep 1 2020 Remi Collet <remi@remirepo.net> - 7.3.22-1 +- Update to 7.3.22 - http://www.php.net/releases/7_3_22.php + +* Tue Aug 18 2020 Remi Collet <remi@remirepo.net> - 7.3.22~RC1-1 +- update to 7.3.22RC1 +- use oracle client library version 19.8 (x86_64) + +* Tue Aug 4 2020 Remi Collet <remi@remirepo.net> - 7.3.21-1 +- Update to 7.3.21 - http://www.php.net/releases/7_3_21.php + +* Tue Jul 21 2020 Remi Collet <remi@remirepo.net> - 7.3.21~RC1-1 +- update to 7.3.21RC1 +- build using ICU 65 (excepted on EL-6) + +* Tue Jul 7 2020 Remi Collet <remi@remirepo.net> - 7.3.20-1 +- Update to 7.3.20 - http://www.php.net/releases/7_3_20.php + +* Tue Jun 23 2020 Remi Collet <remi@remirepo.net> - 7.3.20~RC1-2 +- display build system and provider in phpinfo (from 8.0) + +* Tue Jun 23 2020 Remi Collet <remi@remirepo.net> - 7.3.20~RC1-1 +- update to 7.3.20RC1 + +* Tue Jun 9 2020 Remi Collet <remi@remirepo.net> - 7.3.19-1 +- Update to 7.3.19 - http://www.php.net/releases/7_3_19.php +- rebuild using oniguruma5php +- build phpdbg only once + +* Tue May 26 2020 Remi Collet <remi@remirepo.net> - 7.3.19~RC1-1 +- update to 7.3.19RC1 + +* Tue May 12 2020 Remi Collet <remi@remirepo.net> - 7.3.18-1 +- Update to 7.3.18 - http://www.php.net/releases/7_3_18.php + +* Tue Apr 28 2020 Remi Collet <remi@remirepo.net> - 7.3.18~RC1-1 +- update to 7.3.18RC1 + +* Tue Apr 14 2020 Remi Collet <remi@remirepo.net> - 7.3.17-1 +- Update to 7.3.17 - http://www.php.net/releases/7_3_17.php + +* Tue Mar 31 2020 Remi Collet <remi@remirepo.net> - 7.3.17~RC1-1 +- update to 7.3.17RC1 + +* Tue Mar 17 2020 Remi Collet <remi@remirepo.net> - 7.3.16-1 +- Update to 7.3.16 - http://www.php.net/releases/7_3_16.php +- use oracle client library version 19.6 (18.5 on EL-6) + +* Tue Mar 3 2020 Remi Collet <remi@remirepo.net> - 7.3.16~RC1-1 +- update to 7.3.16RC1 + +* Tue Feb 18 2020 Remi Collet <remi@remirepo.net> - 7.3.15-1 +- Update to 7.3.15 - http://www.php.net/releases/7_3_15.php + +* Tue Feb 4 2020 Remi Collet <remi@remirepo.net> - 7.3.15~RC1-1 +- update to 7.3.15RC1 + +* Tue Jan 21 2020 Remi Collet <remi@remirepo.net> - 7.3.14-1 +- Update to 7.3.14 - http://www.php.net/releases/7_3_14.php + +* Tue Jan 7 2020 Remi Collet <remi@remirepo.net> - 7.3.14~RC1-1 +- update to 7.3.14RC1 + +* Tue Dec 17 2019 Remi Collet <remi@remirepo.net> - 7.3.13-1 +- Update to 7.3.13 - http://www.php.net/releases/7_3_13.php +- use oracle client library version 19.5 (18.5 on EL-6) + +* Tue Dec 3 2019 Remi Collet <remi@remirepo.net> - 7.3.13~RC1-1 +- update to 7.3.13RC1 + +* Tue Nov 19 2019 Remi Collet <remi@remirepo.net> - 7.3.12-1 +- Update to 7.3.12 - http://www.php.net/releases/7_3_12.php + +* Wed Nov 6 2019 Remi Collet <remi@remirepo.net> - 7.3.12~RC1-1 +- update to 7.3.12RC1 + +* Tue Oct 22 2019 Remi Collet <remi@remirepo.net> - 7.3.11-1 +- Update to 7.3.11 - http://www.php.net/releases/7_3_11.php + +* Tue Oct 8 2019 Remi Collet <remi@remirepo.net> - 7.3.11~RC1-1 +- update to 7.3.11RC1 + +* Tue Sep 24 2019 Remi Collet <remi@remirepo.net> - 7.3.10-1 +- Update to 7.3.10 - http://www.php.net/releases/7_3_10.php + +* Wed Sep 11 2019 Remi Collet <remi@remirepo.net> - 7.3.10~RC1-2 +- update to 7.3.10RC1 (new tag) +- add tarball signature check + +* Tue Sep 10 2019 Remi Collet <remi@remirepo.net> - 7.3.10~RC1-1 +- update to 7.3.10RC1 + +* Wed Aug 28 2019 Remi Collet <remi@remirepo.net> - 7.3.9-1 +- Update to 7.3.9 - http://www.php.net/releases/7_3_9.php + +* Mon Aug 19 2019 Remi Collet <remi@remirepo.net> - 7.3.9~RC1-1 +- update to 7.3.9RC1 + * Tue Jul 30 2019 Remi Collet <remi@remirepo.net> - 7.3.8-1 - Update to 7.3.8 - http://www.php.net/releases/7_3_8.php |