Compare commits

...

No commits in common. "c8-stream-7.2" and "stream-php-7.4-rhel-8.10.0" have entirely different histories.

47 changed files with 3536 additions and 812 deletions

6
.gitignore vendored
View File

@ -1 +1,5 @@
SOURCES/php-7.2.24.tar.xz
clog
php-8.*.xz
php-8.*.xz.asc
/php-7.4.33.tar.xz
/php-7.4.33.tar.xz.asc

View File

@ -1 +0,0 @@
d31628bdc89a724a2a0950c2ed7d79b40cf489a7 SOURCES/php-7.2.24.tar.xz

View File

@ -5,17 +5,17 @@ zend_extension=opcache
opcache.enable=1
; Determines if Zend OPCache is enabled for the CLI version of PHP
;opcache.enable_cli=0
opcache.enable_cli=1
; The OPcache shared memory storage size.
opcache.memory_consumption=128
;opcache.memory_consumption=128
; The amount of memory for interned strings in Mbytes.
opcache.interned_strings_buffer=8
;opcache.interned_strings_buffer=8
; The maximum number of keys (scripts) in the OPcache hash table.
; Only numbers between 200 and 1000000 are allowed.
opcache.max_accelerated_files=4000
;opcache.max_accelerated_files=10000
; The maximum percentage of "wasted" memory until a restart is scheduled.
;opcache.max_wasted_percentage=5
@ -42,18 +42,15 @@ opcache.max_accelerated_files=4000
; size of the optimized code.
;opcache.save_comments=1
; If enabled, a fast shutdown sequence is used for the accelerated code
; Depending on the used Memory Manager this may cause some incompatibilities.
;opcache.fast_shutdown=0
; Allow file existence override (file_exists, etc.) performance feature.
;opcache.enable_file_override=0
; A bitmask, where each bit enables or disables the appropriate OPcache
; passes
;opcache.optimization_level=0xffffffff
;opcache.optimization_level=0x7FFFBFFF
;opcache.inherited_hack=1
; This hack should only be enabled to work around "Cannot redeclare class"
; errors.
;opcache.dups_fix=0
; The location of the OPcache blacklist file (wildcards allowed).
@ -112,6 +109,10 @@ opcache.blacklist_filename=/etc/php.d/opcache*.blacklist
; cache is required.
;opcache.file_cache_fallback=1
; Enables or disables copying of PHP code (text segment) into HUGE PAGES.
; This should improve performance, but requires appropriate OS configuration.
opcache.huge_code_pages=0
; Validate cached file permissions.
; Leads OPcache to check file readability on each access to cached file.
; This directive should be enabled in shared hosting environment, when few
@ -124,7 +125,24 @@ opcache.blacklist_filename=/etc/php.d/opcache*.blacklist
; different "chroot" environments.
;opcache.validate_root=0
; Enables or disables copying of PHP code (text segment) into HUGE PAGES.
; This should improve performance, but requires appropriate OS configuration.
opcache.huge_code_pages=0
; If specified, it produces opcode dumps for debugging different stages of
; optimizations.
;opcache.opt_debug_level=0
; Specifies a PHP script that is going to be compiled and executed at server
; start-up.
; http://php.net/opcache.preload
;opcache.preload=
; Preloading code as root is not allowed for security reasons. This directive
; facilitates to let the preloading to be run as another user.
; http://php.net/opcache.preload_user
;opcache.preload_user=
; Prevents caching files that are less than this number of seconds old. It
; protects from caching of incompletely updated files. In case all file updates
; on your site are atomic, you may increase performance by setting it to "0".
;opcache.file_update_protection=2
; Absolute path used to store shared lockfiles (for *nix only).
;opcache.lockfile_path=/tmp

13
20-ffi.ini Normal file
View File

@ -0,0 +1,13 @@
; Enable ffi extension module
extension=ffi
; FFI API restriction. Possibe values:
; "preload" - enabled in CLI scripts and preloaded files (default)
; "false" - always disabled
; "true" - always enabled
;ffi.enable=preload
; List of headers files to preload, wildcard patterns allowed.
; /usr/share/php/preload used by for RPM packages
; /usr/local/share/php/preload may be used for local files
ffi.preload=/usr/share/php/preload/*.h:/usr/local/share/php/preload/*.h

View File

@ -1,17 +0,0 @@
diff -up php-5.3.0beta1/ext/recode/config9.m4.recode php-5.3.0beta1/ext/recode/config9.m4
--- php-5.3.0beta1/ext/recode/config9.m4.recode 2008-12-02 00:30:21.000000000 +0100
+++ php-5.3.0beta1/ext/recode/config9.m4 2009-02-28 09:46:50.000000000 +0100
@@ -4,13 +4,6 @@ dnl
dnl Check for extensions with which Recode can not work
if test "$PHP_RECODE" != "no"; then
- test "$PHP_IMAP" != "no" && recode_conflict="$recode_conflict imap"
-
- if test -n "$MYSQL_LIBNAME"; then
- PHP_CHECK_LIBRARY($MYSQL_LIBNAME, hash_insert, [
- recode_conflict="$recode_conflict mysql"
- ])
- fi
if test -n "$recode_conflict"; then
AC_MSG_ERROR([recode extension can not be configured together with:$recode_conflict])

View File

@ -1,30 +0,0 @@
diff -up php-7.2.4RC1/sapi/litespeed/lsapilib.c.dlopen php-7.2.4RC1/sapi/litespeed/lsapilib.c
--- php-7.2.4RC1/sapi/litespeed/lsapilib.c.dlopen 2018-03-13 12:40:25.330885880 +0100
+++ php-7.2.4RC1/sapi/litespeed/lsapilib.c 2018-03-13 12:41:35.797251042 +0100
@@ -755,7 +755,7 @@ static int (*fp_lve_leave)(struct liblve
static int (*fp_lve_jail)( struct passwd *, char *) = NULL;
static int lsapi_load_lve_lib(void)
{
- s_liblve = dlopen("liblve.so.0", RTLD_LAZY);
+ s_liblve = dlopen("liblve.so.0", RTLD_NOW);
if (s_liblve)
{
fp_lve_is_available = dlsym(s_liblve, "lve_is_available");
diff -up php-7.2.4RC1/Zend/zend_portability.h.dlopen php-7.2.4RC1/Zend/zend_portability.h
--- php-7.2.4RC1/Zend/zend_portability.h.dlopen 2018-03-13 12:33:38.000000000 +0100
+++ php-7.2.4RC1/Zend/zend_portability.h 2018-03-13 12:40:25.330885880 +0100
@@ -144,11 +144,11 @@
# endif
# if defined(RTLD_GROUP) && defined(RTLD_WORLD) && defined(RTLD_PARENT)
-# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT)
+# define DL_LOAD(libname) dlopen(libname, RTLD_NOW | RTLD_GLOBAL | RTLD_GROUP | RTLD_WORLD | RTLD_PARENT)
# elif defined(RTLD_DEEPBIND) && !defined(__SANITIZE_ADDRESS__)
-# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL | RTLD_DEEPBIND)
+# define DL_LOAD(libname) dlopen(libname, RTLD_NOW | RTLD_GLOBAL | RTLD_DEEPBIND)
# else
-# define DL_LOAD(libname) dlopen(libname, RTLD_LAZY | RTLD_GLOBAL)
+# define DL_LOAD(libname) dlopen(libname, RTLD_NOW | RTLD_GLOBAL)
# endif
# define DL_UNLOAD dlclose
# if defined(DLSYM_NEEDS_UNDERSCORE)

View File

@ -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])

View File

@ -1,280 +0,0 @@
Adapted for 7.2.7 from 7.3 by remi
From 0ea4013f101d64fbeb9221260b36e98f10ed1ddd Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Wed, 4 Jul 2018 08:48:38 +0200
Subject: [PATCH] Fixed bug #62596 add getallheaders (apache_request_headers)
missing function in FPM add sapi_add_request_header in public API (was
add_request_header) fix arginfo for fastcgi_finish_request fucntion
---
main/SAPI.c | 50 +++++++++++++++++++++++++++++
main/SAPI.h | 1 +
sapi/cgi/cgi_main.c | 51 +----------------------------
sapi/fpm/fpm/fpm_main.c | 25 ++++++++++++++-
sapi/fpm/tests/getallheaders.phpt | 67 +++++++++++++++++++++++++++++++++++++++
5 files changed, 143 insertions(+), 51 deletions(-)
create mode 100644 sapi/fpm/tests/getallheaders.phpt
diff --git a/main/SAPI.c b/main/SAPI.c
index b6c3329..7e0c7c8 100644
--- a/main/SAPI.c
+++ b/main/SAPI.c
@@ -1104,6 +1104,56 @@ SAPI_API void sapi_terminate_process(void) {
}
}
+SAPI_API void sapi_add_request_header(char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg) /* {{{ */
+{
+ zval *return_value = (zval*)arg;
+ char *str = NULL;
+
+ ALLOCA_FLAG(use_heap)
+
+ if (var_len > 5 &&
+ var[0] == 'H' &&
+ var[1] == 'T' &&
+ var[2] == 'T' &&
+ var[3] == 'P' &&
+ var[4] == '_') {
+
+ char *p;
+
+ var_len -= 5;
+ p = var + 5;
+ var = str = do_alloca(var_len + 1, use_heap);
+ *str++ = *p++;
+ while (*p) {
+ if (*p == '_') {
+ *str++ = '-';
+ p++;
+ if (*p) {
+ *str++ = *p++;
+ }
+ } else if (*p >= 'A' && *p <= 'Z') {
+ *str++ = (*p++ - 'A' + 'a');
+ } else {
+ *str++ = *p++;
+ }
+ }
+ *str = 0;
+ } else if (var_len == sizeof("CONTENT_TYPE")-1 &&
+ memcmp(var, "CONTENT_TYPE", sizeof("CONTENT_TYPE")-1) == 0) {
+ var = "Content-Type";
+ } else if (var_len == sizeof("CONTENT_LENGTH")-1 &&
+ memcmp(var, "CONTENT_LENGTH", sizeof("CONTENT_LENGTH")-1) == 0) {
+ var = "Content-Length";
+ } else {
+ return;
+ }
+ add_assoc_stringl_ex(return_value, var, var_len, val, val_len);
+ if (str) {
+ free_alloca(var, use_heap);
+ }
+}
+/* }}} */
+
/*
* Local variables:
* tab-width: 4
diff --git a/main/SAPI.h b/main/SAPI.h
index f829fd7..4b8e223 100644
--- a/main/SAPI.h
+++ b/main/SAPI.h
@@ -151,6 +151,7 @@ SAPI_API void sapi_shutdown(void);
SAPI_API void sapi_activate(void);
SAPI_API void sapi_deactivate(void);
SAPI_API void sapi_initialize_empty_request(void);
+SAPI_API void sapi_add_request_header(char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg);
END_EXTERN_C()
/*
diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
index 2e9cefe..350846d 100644
--- a/sapi/cgi/cgi_main.c
+++ b/sapi/cgi/cgi_main.c
@@ -1591,54 +1591,6 @@ PHP_FUNCTION(apache_child_terminate) /*
}
/* }}} */
-static void add_request_header(char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg) /* {{{ */
-{
- zval *return_value = (zval*)arg;
- char *str = NULL;
- char *p;
- ALLOCA_FLAG(use_heap)
-
- if (var_len > 5 &&
- var[0] == 'H' &&
- var[1] == 'T' &&
- var[2] == 'T' &&
- var[3] == 'P' &&
- var[4] == '_') {
-
- var_len -= 5;
- p = var + 5;
- var = str = do_alloca(var_len + 1, use_heap);
- *str++ = *p++;
- while (*p) {
- if (*p == '_') {
- *str++ = '-';
- p++;
- if (*p) {
- *str++ = *p++;
- }
- } else if (*p >= 'A' && *p <= 'Z') {
- *str++ = (*p++ - 'A' + 'a');
- } else {
- *str++ = *p++;
- }
- }
- *str = 0;
- } else if (var_len == sizeof("CONTENT_TYPE")-1 &&
- memcmp(var, "CONTENT_TYPE", sizeof("CONTENT_TYPE")-1) == 0) {
- var = "Content-Type";
- } else if (var_len == sizeof("CONTENT_LENGTH")-1 &&
- memcmp(var, "CONTENT_LENGTH", sizeof("CONTENT_LENGTH")-1) == 0) {
- var = "Content-Length";
- } else {
- return;
- }
- add_assoc_stringl_ex(return_value, var, var_len, val, val_len);
- if (str) {
- free_alloca(var, use_heap);
- }
-}
-/* }}} */
-
PHP_FUNCTION(apache_request_headers) /* {{{ */
{
if (zend_parse_parameters_none()) {
@@ -1648,7 +1600,7 @@ PHP_FUNCTION(apache_request_headers) /*
if (fcgi_is_fastcgi()) {
fcgi_request *request = (fcgi_request*) SG(server_context);
- fcgi_loadenv(request, add_request_header, return_value);
+ fcgi_loadenv(request, sapi_add_request_header, return_value);
} else {
char buf[128];
char **env, *p, *q, *var, *val, *t = buf;
diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c
index 3256660..e815be4 100644
--- a/sapi/fpm/fpm/fpm_main.c
+++ b/sapi/fpm/fpm/fpm_main.c
@@ -1533,6 +1533,10 @@ PHP_FUNCTION(fastcgi_finish_request) /* {{{ */
{
fcgi_request *request = (fcgi_request*) SG(server_context);
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
if (!fcgi_is_closed(request)) {
php_output_end_all();
php_header();
@@ -1547,8 +1551,27 @@ PHP_FUNCTION(fastcgi_finish_request) /* {{{ */
}
/* }}} */
+ZEND_BEGIN_ARG_INFO(cgi_fcgi_sapi_no_arginfo, 0)
+ZEND_END_ARG_INFO()
+
+PHP_FUNCTION(apache_request_headers) /* {{{ */
+{
+ fcgi_request *request;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ array_init(return_value);
+ if ((request = (fcgi_request*) SG(server_context))) {
+ fcgi_loadenv(request, sapi_add_request_header, return_value);
+ }
+} /* }}} */
+
static const zend_function_entry cgi_fcgi_sapi_functions[] = {
- PHP_FE(fastcgi_finish_request, NULL)
+ PHP_FE(fastcgi_finish_request, cgi_fcgi_sapi_no_arginfo)
+ PHP_FE(apache_request_headers, cgi_fcgi_sapi_no_arginfo)
+ PHP_FALIAS(getallheaders, apache_request_headers, cgi_fcgi_sapi_no_arginfo)
PHP_FE_END
};
diff --git a/sapi/fpm/tests/getallheaders.phpt b/sapi/fpm/tests/getallheaders.phpt
new file mode 100644
index 0000000..b41f1c6
--- /dev/null
+++ b/sapi/fpm/tests/getallheaders.phpt
@@ -0,0 +1,67 @@
+--TEST--
+FPM: Function getallheaders basic test
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--FILE--
+<?php
+
+require_once "tester.inc";
+
+$cfg = <<<EOT
+[global]
+error_log = {{FILE:LOG}}
+[unconfined]
+listen = {{ADDR}}
+pm = dynamic
+pm.max_children = 5
+pm.start_servers = 1
+pm.min_spare_servers = 1
+pm.max_spare_servers = 3
+EOT;
+
+$code = <<<EOT
+<?php
+echo "Test Start\n";
+var_dump(getallheaders());
+echo "Test End\n";
+EOT;
+
+$headers = [];
+$tester = new FPM\Tester($cfg, $code);
+$tester->start();
+$tester->expectLogStartNotices();
+$tester->request(
+ '',
+ [
+ 'HTTP_X_FOO' => 'BAR',
+ 'HTTP_FOO' => 'foo'
+ ]
+ )->expectBody(
+ [
+ 'Test Start',
+ 'array(4) {',
+ ' ["Foo"]=>',
+ ' string(3) "foo"',
+ ' ["X-Foo"]=>',
+ ' string(3) "BAR"',
+ ' ["Content-Length"]=>',
+ ' string(1) "0"',
+ ' ["Content-Type"]=>',
+ ' string(0) ""',
+ '}',
+ 'Test End',
+ ]
+ );
+$tester->terminate();
+$tester->expectLogTerminatingNotices();
+$tester->close();
+
+?>
+Done
+--EXPECT--
+Done
+--CLEAN--
+<?php
+require_once "tester.inc";
+FPM\Tester::clean();
+?>
--
2.1.4

View File

@ -1,7 +0,0 @@
<IfModule !mod_php5.c>
<IfModule !prefork.c>
# ZTS module is not supported, so FPM is preferred
# LoadModule php7_module modules/libphp7-zts.so
</IfModule>
</IfModule>

View File

@ -5,7 +5,9 @@ Add support for use of the system timezone database, rather
than embedding a copy. Discussed upstream but was not desired.
History:
r17: adapt for autotool change in 7.2.16RC1
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)
r15: adapt for timelib 2017.05beta7 (in 7.2.0RC1)
r14: improve check for valid tz file
@ -28,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.2.16RC1/ext/date/config0.m4.systzdata php-7.2.16RC1/ext/date/config0.m4
--- php-7.2.16RC1/ext/date/config0.m4.systzdata 2019-02-19 11:22:22.223741585 +0100
+++ php-7.2.16RC1/ext/date/config0.m4 2019-02-19 11:23:05.089111556 +0100
@@ -10,6 +10,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)
@ -51,10 +54,11 @@ diff -up php-7.2.16RC1/ext/date/config0.m4.systzdata php-7.2.16RC1/ext/date/conf
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.2.16RC1/ext/date/lib/parse_tz.c.systzdata php-7.2.16RC1/ext/date/lib/parse_tz.c
--- php-7.2.16RC1/ext/date/lib/parse_tz.c.systzdata 2019-02-19 11:13:22.000000000 +0100
+++ php-7.2.16RC1/ext/date/lib/parse_tz.c 2019-02-19 11:19:40.245313535 +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"
@ -76,7 +80,7 @@ diff -up php-7.2.16RC1/ext/date/lib/parse_tz.c.systzdata php-7.2.16RC1/ext/date/
#if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__))
# if defined(__LITTLE_ENDIAN__)
@@ -67,6 +80,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;
@ -88,7 +92,7 @@ diff -up php-7.2.16RC1/ext/date/lib/parse_tz.c.systzdata php-7.2.16RC1/ext/date/
/* read ID */
version = (*tzf)[3] - '0';
*tzf += 4;
@@ -374,7 +392,429 @@ void timelib_dump_tzinfo(timelib_tzinfo
@@ -412,7 +430,467 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz)
}
}
@ -319,6 +323,44 @@ diff -up php-7.2.16RC1/ext/date/lib/parse_tz.c.systzdata php-7.2.16RC1/ext/date/
+}
+
+
+/* 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)
+{
@ -519,7 +561,7 @@ diff -up php-7.2.16RC1/ext/date/lib/parse_tz.c.systzdata php-7.2.16RC1/ext/date/
{
int left = 0, right = tzdb->index_size - 1;
@@ -400,9 +840,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;
}
@ -556,6 +598,7 @@ diff -up php-7.2.16RC1/ext/date/lib/parse_tz.c.systzdata php-7.2.16RC1/ext/date/
+ 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;
@ -568,7 +611,7 @@ diff -up php-7.2.16RC1/ext/date/lib/parse_tz.c.systzdata php-7.2.16RC1/ext/date/
}
const timelib_tzdb_index_entry *timelib_timezone_identifiers_list(const timelib_tzdb *tzdb, int *count)
@@ -414,7 +893,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;
@ -600,7 +643,7 @@ diff -up php-7.2.16RC1/ext/date/lib/parse_tz.c.systzdata php-7.2.16RC1/ext/date/
}
static int skip_64bit_preamble(const unsigned char **tzf, timelib_tzinfo *tz)
@@ -456,12 +958,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;
@ -616,11 +659,10 @@ diff -up php-7.2.16RC1/ext/date/lib/parse_tz.c.systzdata php-7.2.16RC1/ext/date/
tmp = timelib_tzinfo_ctor(timezone);
version = read_preamble(&tzf, tmp, &type);
@@ -484,6 +988,29 @@ timelib_tzinfo *timelib_parse_tzfile(cha
timelib_tzinfo_dtor(tmp);
return NULL;
@@ -534,11 +1077,36 @@ timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb, i
}
+
skip_posix_string(&tzf, tmp);
+#ifdef HAVE_SYSTEM_TZDATA
+ if (memmap) {
+ const struct location_info *li;
@ -643,10 +685,8 @@ diff -up php-7.2.16RC1/ext/date/lib/parse_tz.c.systzdata php-7.2.16RC1/ext/date/
+ munmap(memmap, maplen);
+ } else {
+#endif
if (version == 2 || version == 3) {
if (!skip_64bit_preamble(&tzf, tmp)) {
/* 64 bit preamble is not in place */
@@ -501,6 +1028,9 @@ timelib_tzinfo *timelib_parse_tzfile(cha
if (type == TIMELIB_TZINFO_PHP) {
read_location(&tzf, tmp);
} else {
set_default_location_and_comments(&tzf, tmp);
}
@ -656,3 +696,19 @@ diff -up php-7.2.16RC1/ext/date/lib/parse_tz.c.systzdata php-7.2.16RC1/ext/date/
} 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();

View File

@ -1,6 +1,6 @@
--- php-5.6.3/sapi/embed/config.m4.embed
+++ php-5.6.3/sapi/embed/config.m4
@@ -12,7 +12,8 @@ if test "$PHP_EMBED" != "no"; then
@@ -11,7 +11,8 @@ if test "$PHP_EMBED" != "no"; then
case "$PHP_EMBED" in
yes|shared)
PHP_EMBED_TYPE=shared
@ -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 fpm phpdbg @PHP_INSTALLED_SAPIS@"
ini_dir="@EXPANDED_PHP_CONFIG_FILE_SCAN_DIR@"
ini_path="@EXPANDED_PHP_CONFIG_FILE_PATH@"
# Set php_cli_binary and php_cgi_binary if available
for sapi in $php_sapis; do

View File

@ -5,10 +5,9 @@ mod_php is build twice
- as ZTS using --enable-maintainer-zts
diff --git a/sapi/apache2handler/config.m4 b/sapi/apache2handler/config.m4
index 2e64b21..ec4799f 100644
--- a/sapi/apache2handler/config.m4
+++ b/sapi/apache2handler/config.m4
@@ -116,17 +116,6 @@ if test "$PHP_APXS2" != "no"; then
@@ -105,17 +105,6 @@ if test "$PHP_APXS2" != "no"; then
;;
esac
@ -18,7 +17,7 @@ index 2e64b21..ec4799f 100644
- PHP_BUILD_THREAD_SAFE
- fi
- else
- APACHE_THREADED_MPM=`$APXS_HTTPD -V | grep 'threaded:.*yes'`
- APACHE_THREADED_MPM=`$APXS_HTTPD -V 2>/dev/null | grep 'threaded:.*yes'`
- if test -n "$APACHE_THREADED_MPM"; then
- PHP_BUILD_THREAD_SAFE
- fi

View File

@ -1,12 +1,12 @@
Use -lldap_r by default.
diff -up php-7.2.3RC1/ext/ldap/config.m4.ldap_r php-7.2.3RC1/ext/ldap/config.m4
--- php-7.2.3RC1/ext/ldap/config.m4.ldap_r 2018-02-14 06:05:11.553142812 +0100
+++ php-7.2.3RC1/ext/ldap/config.m4 2018-02-14 06:07:31.179816122 +0100
@@ -119,7 +119,11 @@ if test "$PHP_LDAP" != "no"; then
MACHINE_INCLUDES=$($CC -dumpmachine)
diff -up php-7.4.0RC2/ext/ldap/config.m4.ldap_r php-7.4.0RC2/ext/ldap/config.m4
--- php-7.4.0RC2/ext/ldap/config.m4.ldap_r 2019-09-17 10:21:24.769200812 +0200
+++ php-7.4.0RC2/ext/ldap/config.m4 2019-09-17 10:21:30.658181771 +0200
@@ -68,7 +68,11 @@ if test "$PHP_LDAP" != "no"; then
dnl -pc removal is a hack for clang
MACHINE_INCLUDES=$($CC -dumpmachine | $SED 's/-pc//')
- if test -f $LDAP_LIBDIR/liblber.a || test -f $LDAP_LIBDIR/liblber.$SHLIB_SUFFIX_NAME || test -f $LDAP_LIBDIR/$MACHINE_INCLUDES/liblber.a || test -f $LDAP_LIBDIR/$MACHINE_INCLUDES/liblber.$SHLIB_SUFFIX_NAME; then
+ if test -f $LDAP_LIBDIR/libldap_r.$SHLIB_SUFFIX_NAME; then

View File

@ -1,7 +1,7 @@
diff -up php-7.2.12RC1/scripts/phpize.in.headers php-7.2.12RC1/scripts/phpize.in
--- php-7.2.12RC1/scripts/phpize.in.headers 2018-10-23 11:47:43.000000000 +0200
+++ php-7.2.12RC1/scripts/phpize.in 2018-10-23 11:49:51.651818777 +0200
@@ -162,6 +162,15 @@ phpize_autotools()
diff -up ./scripts/phpize.in.headers ./scripts/phpize.in
--- ./scripts/phpize.in.headers 2019-07-23 10:05:11.000000000 +0200
+++ ./scripts/phpize.in 2019-07-23 10:18:13.648098089 +0200
@@ -165,6 +165,15 @@ phpize_autotools()
$PHP_AUTOHEADER || exit 1
}
@ -17,7 +17,7 @@ diff -up php-7.2.12RC1/scripts/phpize.in.headers php-7.2.12RC1/scripts/phpize.in
# Main script
case "$1" in
@@ -180,12 +189,15 @@ case "$1" in
@@ -183,12 +192,15 @@ case "$1" in
# Version
--version|-v)

84
php-cve-2022-31631.patch Normal file
View File

@ -0,0 +1,84 @@
From 7cb160efe19d3dfb8b92629805733ea186b55050 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)
---
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 0595bd09feb..54f9d05e1e2 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 00000000000..99fb07c3048
--- /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 7328f3a0344806b846bd05657bdce96e47810bf0 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
---
NEWS | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/NEWS b/NEWS
index 8a8c0c9285d..03e8c839c77 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,12 @@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
+Backported from 8.0.27
+
+- PDO/SQLite:
+ . Fixed bug #81740 (PDO::quote() may return unquoted string).
+ (CVE-2022-31631) (cmb)
+
03 Nov 2022, PHP 7.4.33
- GD:
--
2.38.1

188
php-cve-2023-0567.patch Normal file
View File

@ -0,0 +1,188 @@
From 7437aaae38cf4b3357e7580f9e22fd4a403b6c23 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/7] crypt: Fix validation of malformed BCrypt hashes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
PHPs 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 PHPs own crypt_blowfish
implementation that was added in 1e820eca02dcf322b41fd2fe4ed2a6b8309f8ab5.
No clear reason is given for the PHP Hacks existence. This commit removes it,
because BCrypt hashes containing a `$` character in their salt are not valid
BCrypt hashes.
(cherry picked from commit c840f71524067aa474c00c3eacfb83bd860bfc8a)
---
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 c1f945f29ed..aa7e1bc2e68 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 00000000000..32e335f4b08
--- /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 ed0281b588a6840cb95f3134a4e68847a3be5bb7 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/7] crypt: Fix possible buffer overread in php_crypt()
(cherry picked from commit a92acbad873a05470af1a47cb785a18eadd827b5)
---
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 92430b69f77..04487f3fe5a 100644
--- a/ext/standard/crypt.c
+++ b/ext/standard/crypt.c
@@ -151,6 +151,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 00000000000..085bc8a2390
--- /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

98
php-cve-2023-0568.patch Normal file
View File

@ -0,0 +1,98 @@
From 887cd0710ad856a0d22c329b6ea6c71ebd8621ae 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/7] 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)
---
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 b478e1a1aab..e683eb8f701 100644
--- a/ext/dom/document.c
+++ b/ext/dom/document.c
@@ -1380,7 +1380,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 06f569949ce..ecc81ad1470 100644
--- a/ext/xmlreader/php_xmlreader.c
+++ b/ext/xmlreader/php_xmlreader.c
@@ -1038,7 +1038,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 27135020fa3..90de040a218 100644
--- a/main/fopen_wrappers.c
+++ b/main/fopen_wrappers.c
@@ -138,10 +138,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 614468ce4056c0ef93aae09532dcffdf65b594b5 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/7] NEWS
---
NEWS | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/NEWS b/NEWS
index 03e8c839c77..8157a20d4b3 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

143
php-cve-2023-0662.patch Normal file
View File

@ -0,0 +1,143 @@
From 3a2fdef1ae38881110006616ee1f0534b082ca45 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/7] Fix repeated warning for file uploads limit exceeding
---
main/rfc1867.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/main/rfc1867.c b/main/rfc1867.c
index edef19c16d6..4931b9aeefb 100644
--- a/main/rfc1867.c
+++ b/main/rfc1867.c
@@ -922,7 +922,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 8ec78d28d20c82c75c4747f44c52601cfdb22516 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/7] 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.
---
main/main.c | 1 +
main/rfc1867.c | 11 +++++++++++
2 files changed, 12 insertions(+)
diff --git a/main/main.c b/main/main.c
index 0b33b2b56c9..d8c465988cc 100644
--- a/main/main.c
+++ b/main/main.c
@@ -836,6 +836,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 4931b9aeefb..1b212c93325 100644
--- a/main/rfc1867.c
+++ b/main/rfc1867.c
@@ -694,6 +694,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;
@@ -715,6 +716,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) {
@@ -799,6 +805,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 472db3ee3a00ac00d36019eee0b3b7362334481c 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/7] NEWS
---
NEWS | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/NEWS b/NEWS
index 8157a20d4b3..c1668368818 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 c04f310440a906fc4ca885f4ecf6e3e4cd36edc7 Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Tue, 14 Feb 2023 11:47:22 +0100
Subject: [PATCH] fix NEWS, not FPM specific
---
NEWS | 2 --
1 file changed, 2 deletions(-)
diff --git a/NEWS b/NEWS
index c1668368818..3f8739eae78 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

152
php-cve-2023-3247.patch Normal file
View File

@ -0,0 +1,152 @@
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 e3a9afdbe9f..912b8e341d8 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);
--
2.40.1
From f3021d66d7bb42d2578530cc94f9bde47e58eb10 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
---
NEWS | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/NEWS b/NEWS
index 7c07635cade..899644b3d63 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

89
php-cve-2023-3823.patch Normal file
View File

@ -0,0 +1,89 @@
From c398fe98c044c8e7c23135acdc38d4ef7bedc983 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)
---
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 4710703c70e..490b14528f1 100644
--- a/ext/phar/dirstream.c
+++ b/ext/phar/dirstream.c
@@ -91,25 +91,28 @@ static int phar_dir_seek(php_stream *stream, zend_off_t offset, int whence, zend
*/
static ssize_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 00000000000..4e12f05fb62
--- /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

644
php-cve-2023-3824.patch Normal file
View File

@ -0,0 +1,644 @@
From b3758bd21223b97c042cae7bd26a66cde081ea98 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)
---
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 e683eb8f701..989b5b3dd24 100644
--- a/ext/dom/document.c
+++ b/ext/dom/document.c
@@ -1459,6 +1459,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;
@@ -1759,7 +1760,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
@@ -1799,6 +1802,7 @@ PHP_FUNCTION(dom_document_validate)
DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+ PHP_LIBXML_SANITIZE_GLOBALS(validate);
cvp = xmlNewValidCtxt();
cvp->userData = NULL;
@@ -1810,6 +1814,7 @@ PHP_FUNCTION(dom_document_validate)
} else {
RETVAL_FALSE;
}
+ PHP_LIBXML_RESTORE_GLOBALS(validate);
xmlFreeValidCtxt(cvp);
@@ -1844,14 +1849,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;
}
@@ -1872,6 +1881,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;
@@ -1890,11 +1900,13 @@ static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type
valid_opts |= XML_SCHEMA_VAL_VC_I_CREATE;
}
+ 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;
@@ -1965,12 +1977,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;
@@ -2069,6 +2083,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 9b222586ac5..711c42f939d 100644
--- a/ext/dom/documentfragment.c
+++ b/ext/dom/documentfragment.c
@@ -131,7 +131,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 00000000000..b28afd4694e
--- /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 cf936e95de1..92028d5703e 100644
--- a/ext/libxml/php_libxml.h
+++ b/ext/libxml/php_libxml.h
@@ -121,6 +121,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 2cdff0e648d..101a9d8fd8c 100644
--- a/ext/simplexml/simplexml.c
+++ b/ext/simplexml/simplexml.c
@@ -2194,7 +2194,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;
@@ -2248,7 +2250,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;
@@ -2298,7 +2302,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 00000000000..2152e012328
--- /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 18a266179b7..1bb7fa00a37 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;
@@ -141,6 +142,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 fc4525650fc..57eb00dd429 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;
@@ -471,6 +472,7 @@ XML_ParserCreate_MM(const XML_Char *encoding, const XML_Memory_Handling_Suite *m
return NULL;
}
+ php_libxml_sanitize_parse_ctxt_options(parser->parser);
xmlCtxtUseOptions(parser->parser, XML_PARSE_OLDSAX);
parser->parser->replaceEntities = 1;
diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c
index ecc81ad1470..51d6bb9c9f2 100644
--- a/ext/xmlreader/php_xmlreader.c
+++ b/ext/xmlreader/php_xmlreader.c
@@ -304,6 +304,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,
@@ -312,6 +313,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;
}
@@ -881,7 +883,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) {
@@ -958,7 +962,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;
@@ -1082,6 +1088,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) {
@@ -1100,9 +1107,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 00000000000..e9ffb04c2bb
--- /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 079920d0ffa..2d95b2ff4bb 100644
--- a/ext/xsl/xsltprocessor.c
+++ b/ext/xsl/xsltprocessor.c
@@ -398,7 +398,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;
@@ -421,13 +421,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 ef1d507acf7be23d7624dc3c891683b2218feb51 Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Tue, 1 Aug 2023 07:22:33 +0200
Subject: [PATCH 3/4] NEWS
---
NEWS | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/NEWS b/NEWS
index 899644b3d63..4f88029a7d6 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
From 24e669e790e6aebd219c9a9fa19017455c8646b4 Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Tue, 1 Aug 2023 07:37:25 +0200
Subject: [PATCH 4/4] backport zend_test changes
(zend_test_override_libxml_global_state)
---
...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 b28afd4694e..7fc2a249ac7 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 2152e012328..54f9d4941eb 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 e9ffb04c2bb..b0120b325ef 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 4f81adc6ac1..cdfc15571c0 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 */
@@ -297,6 +316,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

193
php-cve-2024-2756.patch Normal file
View File

@ -0,0 +1,193 @@
From a6c1c62a25ac23b08a86af11d68f0e2eaafc102b 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)
---
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 00000000000..77fcb680894
--- /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 18f6b65a6c5..e971d497337 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 dcdd49ef3bfbd8ccc778850d6a0f9b98adf625d4 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)
---
NEWS | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/NEWS b/NEWS
index 4f88029a7d6..d63aadc6851 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

81
php-cve-2024-3096.patch Normal file
View File

@ -0,0 +1,81 @@
From 4a7ceb9d6427f8d368f1a8739267b1f8310ec201 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)
---
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 9fe7fb1a422..af80670246a 100644
--- a/ext/standard/password.c
+++ b/ext/standard/password.c
@@ -260,6 +260,11 @@ static zend_string* php_password_bcrypt_hash(const zend_string *password, zend_a
zval *zcost;
zend_long cost = PHP_PASSWORD_BCRYPT_COST;
+ 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 (options && (zcost = zend_hash_str_find(options, "cost", sizeof("cost")-1)) != NULL) {
cost = zval_get_long(zcost);
}
diff --git a/ext/standard/tests/password/password_bcrypt_errors.phpt b/ext/standard/tests/password/password_bcrypt_errors.phpt
index a0826080e62..f95b72670ae 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 027bdbc636632be49ecfad8d4191509faacb34ac 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)
---
NEWS | 2 ++
1 file changed, 2 insertions(+)
diff --git a/NEWS b/NEWS
index d63aadc6851..96a33c21637 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

180
php-cve-2024-5458.patch Normal file
View File

@ -0,0 +1,180 @@
From 08be64e40197fc12dca5f802d16748d9c3cb4cb4 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Wed, 22 May 2024 22:25:02 +0200
Subject: [PATCH 1/2] Fix GHSA-w8qr-v226-r27w
We should not early-out with success status if we found an ipv6
hostname, we should keep checking the rest of the conditions.
Because integrating the if-check of the ipv6 hostname in the
"Validate domain" if-check made the code hard to read, I extracted the
condition out to a separate function. This also required to make
a few pointers const in order to have some clean code.
(cherry picked from commit 4066610b47e22c24cbee91be434a94357056a479)
---
ext/filter/logical_filters.c | 35 ++++++++++---------
ext/filter/tests/ghsa-w8qr-v226-r27w.phpt | 41 +++++++++++++++++++++++
2 files changed, 61 insertions(+), 15 deletions(-)
create mode 100644 ext/filter/tests/ghsa-w8qr-v226-r27w.phpt
diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c
index e5e87c01568..9c86ad072cc 100644
--- a/ext/filter/logical_filters.c
+++ b/ext/filter/logical_filters.c
@@ -91,7 +91,7 @@
#define FORMAT_IPV4 4
#define FORMAT_IPV6 6
-static int _php_filter_validate_ipv6(char *str, size_t str_len, int ip[8]);
+static int _php_filter_validate_ipv6(const char *str, size_t str_len, int ip[8]);
static int php_filter_parse_int(const char *str, size_t str_len, zend_long *ret) { /* {{{ */
zend_long ctx_value;
@@ -571,6 +571,14 @@ static int is_userinfo_valid(zend_string *str)
return 1;
}
+static zend_bool php_filter_is_valid_ipv6_hostname(const char *s, size_t l)
+{
+ const char *e = s + l;
+ const char *t = e - 1;
+
+ return *s == '[' && *t == ']' && _php_filter_validate_ipv6(s + 1, l - 2, NULL);
+}
+
void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
{
php_url *url;
@@ -596,7 +604,7 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
if (url->scheme != NULL &&
(zend_string_equals_literal_ci(url->scheme, "http") || zend_string_equals_literal_ci(url->scheme, "https"))) {
- char *e, *s, *t;
+ const char *s;
size_t l;
if (url->host == NULL) {
@@ -605,17 +613,14 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
s = ZSTR_VAL(url->host);
l = ZSTR_LEN(url->host);
- e = s + l;
- t = e - 1;
-
- /* An IPv6 enclosed by square brackets is a valid hostname */
- if (*s == '[' && *t == ']' && _php_filter_validate_ipv6((s + 1), l - 2, NULL)) {
- php_url_free(url);
- return;
- }
- // Validate domain
- if (!_php_filter_validate_domain(ZSTR_VAL(url->host), l, FILTER_FLAG_HOSTNAME)) {
+ if (
+ /* An IPv6 enclosed by square brackets is a valid hostname.*/
+ !php_filter_is_valid_ipv6_hostname(s, l) &&
+ /* Validate domain.
+ * This includes a loose check for an IPv4 address. */
+ !_php_filter_validate_domain(ZSTR_VAL(url->host), l, FILTER_FLAG_HOSTNAME)
+ ) {
php_url_free(url);
RETURN_VALIDATION_FAILED
}
@@ -749,15 +754,15 @@ static int _php_filter_validate_ipv4(char *str, size_t str_len, int *ip) /* {{{
}
/* }}} */
-static int _php_filter_validate_ipv6(char *str, size_t str_len, int ip[8]) /* {{{ */
+static int _php_filter_validate_ipv6(const char *str, size_t str_len, int ip[8]) /* {{{ */
{
int compressed_pos = -1;
int blocks = 0;
int num, n, i;
char *ipv4;
- char *end;
+ const char *end;
int ip4elm[4];
- char *s = str;
+ const char *s = str;
if (!memchr(str, ':', str_len)) {
return 0;
diff --git a/ext/filter/tests/ghsa-w8qr-v226-r27w.phpt b/ext/filter/tests/ghsa-w8qr-v226-r27w.phpt
new file mode 100644
index 00000000000..0092408ee5a
--- /dev/null
+++ b/ext/filter/tests/ghsa-w8qr-v226-r27w.phpt
@@ -0,0 +1,41 @@
+--TEST--
+GHSA-w8qr-v226-r27w
+--EXTENSIONS--
+filter
+--FILE--
+<?php
+
+function test(string $input) {
+ var_dump(filter_var($input, FILTER_VALIDATE_URL));
+}
+
+echo "--- These ones should fail ---\n";
+test("http://t[est@127.0.0.1");
+test("http://t[est@[::1]");
+test("http://t[est@[::1");
+test("http://t[est@::1]");
+test("http://php.net\\@aliyun.com/aaa.do");
+test("http://test[@2001:db8:3333:4444:5555:6666:1.2.3.4]");
+test("http://te[st@2001:db8:3333:4444:5555:6666:1.2.3.4]");
+test("http://te[st@2001:db8:3333:4444:5555:6666:1.2.3.4");
+
+echo "--- These ones should work ---\n";
+test("http://test@127.0.0.1");
+test("http://test@[2001:db8:3333:4444:5555:6666:1.2.3.4]");
+test("http://test@[::1]");
+
+?>
+--EXPECT--
+--- These ones should fail ---
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+--- These ones should work ---
+string(21) "http://test@127.0.0.1"
+string(50) "http://test@[2001:db8:3333:4444:5555:6666:1.2.3.4]"
+string(17) "http://test@[::1]"
--
2.45.1
From ec1d5e6468479e64acc7fb8cb955f053b64ea9a0 Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Tue, 4 Jun 2024 16:48:08 +0200
Subject: [PATCH 2/2] NEWS
(cherry picked from commit a1ff81b786bd519597e770795be114f5171f0648)
---
NEWS | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/NEWS b/NEWS
index 8058eff0256..34ad33cf5c4 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,12 @@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+Backported from 8.1.29
+
+- Filter:
+ . Fixed bug GHSA-w8qr-v226-r27w (Filter bypass in filter_var FILTER_VALIDATE_URL).
+ (CVE-2024-5458) (nielsdos)
+
Backported from 8.1.28
- Standard:
--
2.45.1

227
php-cve-2024-8925.patch Normal file
View File

@ -0,0 +1,227 @@
From a24ac172f52e75101913f3946cfa5515f723c99f Mon Sep 17 00:00:00 2001
From: Arnaud Le Blanc <arnaud.lb@gmail.com>
Date: Mon, 9 Sep 2024 15:22:07 +0200
Subject: [PATCH 04/11] Fix GHSA-9pqp-7h25-4f32
multipart/form-data boundaries larger than the read buffer result in erroneous
parsing, which violates data integrity.
Limit boundary size, as allowed by RFC 1521:
Encapsulation boundaries [...] must be no longer than 70 characters, not
counting the two leading hyphens.
We correctly parse payloads with boundaries of length up to
FILLUNIT-strlen("\r\n--") bytes, so allow this for BC.
(cherry picked from commit 19b49258d0c5a61398d395d8afde1123e8d161e0)
(cherry picked from commit 2b0daf421c162376892832588eccdfa9a286ed09)
---
main/rfc1867.c | 7 ++
tests/basic/GHSA-9pqp-7h25-4f32.inc | 3 +
tests/basic/GHSA-9pqp-7h25-4f32.phpt | 100 +++++++++++++++++++++++++++
3 files changed, 110 insertions(+)
create mode 100644 tests/basic/GHSA-9pqp-7h25-4f32.inc
create mode 100644 tests/basic/GHSA-9pqp-7h25-4f32.phpt
diff --git a/main/rfc1867.c b/main/rfc1867.c
index 1b212c93325..43ccce120c3 100644
--- a/main/rfc1867.c
+++ b/main/rfc1867.c
@@ -759,6 +759,13 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
boundary_len = boundary_end-boundary;
}
+ /* Boundaries larger than FILLUNIT-strlen("\r\n--") characters lead to
+ * erroneous parsing */
+ if (boundary_len > FILLUNIT-strlen("\r\n--")) {
+ sapi_module.sapi_error(E_WARNING, "Boundary too large in multipart/form-data POST data");
+ return;
+ }
+
/* Initialize the buffer */
if (!(mbuff = multipart_buffer_new(boundary, boundary_len))) {
sapi_module.sapi_error(E_WARNING, "Unable to initialize the input buffer");
diff --git a/tests/basic/GHSA-9pqp-7h25-4f32.inc b/tests/basic/GHSA-9pqp-7h25-4f32.inc
new file mode 100644
index 00000000000..adf72a361a2
--- /dev/null
+++ b/tests/basic/GHSA-9pqp-7h25-4f32.inc
@@ -0,0 +1,3 @@
+<?php
+print "Hello world\n";
+var_dump($_POST);
diff --git a/tests/basic/GHSA-9pqp-7h25-4f32.phpt b/tests/basic/GHSA-9pqp-7h25-4f32.phpt
new file mode 100644
index 00000000000..af819163705
--- /dev/null
+++ b/tests/basic/GHSA-9pqp-7h25-4f32.phpt
@@ -0,0 +1,100 @@
+--TEST--
+GHSA-9pqp-7h25-4f32
+--SKIPIF--
+<?php
+if (!getenv('TEST_PHP_CGI_EXECUTABLE')) {
+ die("skip php-cgi not available");
+}
+?>
+--FILE--
+<?php
+
+const FILLUNIT = 5 * 1024;
+
+function test($boundaryLen) {
+ printf("Boundary len: %d\n", $boundaryLen);
+
+ $cmd = [
+ getenv('TEST_PHP_CGI_EXECUTABLE'),
+ '-C',
+ '-n',
+ __DIR__ . '/GHSA-9pqp-7h25-4f32.inc',
+ ];
+
+ $boundary = str_repeat('A', $boundaryLen);
+ $body = ""
+ . "--$boundary\r\n"
+ . "Content-Disposition: form-data; name=\"koko\"\r\n"
+ . "\r\n"
+ . "BBB\r\n--" . substr($boundary, 0, -1) . "CCC\r\n"
+ . "--$boundary--\r\n"
+ ;
+
+ $env = array_merge($_ENV, [
+ 'REDIRECT_STATUS' => '1',
+ 'CONTENT_TYPE' => "multipart/form-data; boundary=$boundary",
+ 'CONTENT_LENGTH' => strlen($body),
+ 'REQUEST_METHOD' => 'POST',
+ 'SCRIPT_FILENAME' => __DIR__ . '/GHSA-9pqp-7h25-4f32.inc',
+ ]);
+
+ $spec = [
+ 0 => ['pipe', 'r'],
+ 1 => STDOUT,
+ 2 => STDOUT,
+ ];
+
+ $pipes = [];
+
+ print "Starting...\n";
+
+ $handle = proc_open($cmd, $spec, $pipes, getcwd(), $env);
+
+ fwrite($pipes[0], $body);
+
+ $status = proc_close($handle);
+
+ print "\n";
+}
+
+for ($offset = -1; $offset <= 1; $offset++) {
+ test(FILLUNIT - strlen("\r\n--") + $offset);
+}
+
+?>
+--EXPECTF--
+Boundary len: 5115
+Starting...
+X-Powered-By: %s
+Content-type: text/html; charset=UTF-8
+
+Hello world
+array(1) {
+ ["koko"]=>
+ string(5124) "BBB
+--AAA%sCCC"
+}
+
+Boundary len: 5116
+Starting...
+X-Powered-By: %s
+Content-type: text/html; charset=UTF-8
+
+Hello world
+array(1) {
+ ["koko"]=>
+ string(5125) "BBB
+--AAA%sCCC"
+}
+
+Boundary len: 5117
+Starting...
+X-Powered-By: %s
+Content-type: text/html; charset=UTF-8
+
+<br />
+<b>Warning</b>: Boundary too large in multipart/form-data POST data in <b>Unknown</b> on line <b>0</b><br />
+Hello world
+array(0) {
+}
+
--
2.46.1
From 2fd1b83817d20523e72bef3ad524cd5797f51acf Mon Sep 17 00:00:00 2001
From: Jakub Zelenka <bukka@php.net>
Date: Mon, 23 Sep 2024 18:54:31 +0100
Subject: [PATCH 08/11] Skip GHSA-9pqp-7h25-4f32 test on Windows
(cherry picked from commit c70e25630832fa10d421328eed2b8e1a36af7a64)
(cherry picked from commit c75683864f6e4188439e8ca2adbb05824918be12)
---
tests/basic/GHSA-9pqp-7h25-4f32.phpt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tests/basic/GHSA-9pqp-7h25-4f32.phpt b/tests/basic/GHSA-9pqp-7h25-4f32.phpt
index af819163705..29bcb6557d5 100644
--- a/tests/basic/GHSA-9pqp-7h25-4f32.phpt
+++ b/tests/basic/GHSA-9pqp-7h25-4f32.phpt
@@ -5,6 +5,9 @@ GHSA-9pqp-7h25-4f32
if (!getenv('TEST_PHP_CGI_EXECUTABLE')) {
die("skip php-cgi not available");
}
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die("skip not for Windows in CI - probably resource issue");
+}
?>
--FILE--
<?php
--
2.46.1
From 29065f33f37f99ba33254cb23c941647bcd7372c Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Thu, 26 Sep 2024 15:49:03 +0200
Subject: [PATCH 11/11] adapt GHSA-9pqp-7h25-4f32 test for 7.x
---
tests/basic/GHSA-9pqp-7h25-4f32.phpt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/basic/GHSA-9pqp-7h25-4f32.phpt b/tests/basic/GHSA-9pqp-7h25-4f32.phpt
index 29bcb6557d5..a1ead918ff3 100644
--- a/tests/basic/GHSA-9pqp-7h25-4f32.phpt
+++ b/tests/basic/GHSA-9pqp-7h25-4f32.phpt
@@ -21,6 +21,7 @@ function test($boundaryLen) {
getenv('TEST_PHP_CGI_EXECUTABLE'),
'-C',
'-n',
+ '-dlog_errors=1',
__DIR__ . '/GHSA-9pqp-7h25-4f32.inc',
];
@@ -92,11 +93,10 @@ array(1) {
Boundary len: 5117
Starting...
+PHP Warning: Boundary too large in multipart/form-data POST data in Unknown on line 0
X-Powered-By: %s
Content-type: text/html; charset=UTF-8
-<br />
-<b>Warning</b>: Boundary too large in multipart/form-data POST data in <b>Unknown</b> on line <b>0</b><br />
Hello world
array(0) {
}
--
2.46.1

210
php-cve-2024-8926.patch Normal file
View File

@ -0,0 +1,210 @@
From fb718aa6f2117933566bb7bb2f70b2b0d9a9c08f Mon Sep 17 00:00:00 2001
From: Jan Ehrhardt <github@ehrhardt.nl>
Date: Wed, 5 Jun 2024 20:24:52 +0200
Subject: [PATCH 01/11] Fix GHSA-3qgc-jrrr-25jv
---
sapi/cgi/cgi_main.c | 23 ++++++++++++++-
sapi/cgi/tests/ghsa-3qgc-jrrr-25jv.phpt | 38 +++++++++++++++++++++++++
2 files changed, 60 insertions(+), 1 deletion(-)
create mode 100644 sapi/cgi/tests/ghsa-3qgc-jrrr-25jv.phpt
diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
index a36f426d266..8d1342727dc 100644
--- a/sapi/cgi/cgi_main.c
+++ b/sapi/cgi/cgi_main.c
@@ -1827,8 +1827,13 @@ int main(int argc, char *argv[])
}
}
+ /* Apache CGI will pass the query string to the command line if it doesn't contain a '='.
+ * This can create an issue where a malicious request can pass command line arguments to
+ * the executable. Ideally we skip argument parsing when we're in cgi or fastcgi mode,
+ * but that breaks PHP scripts on Linux with a hashbang: `#!/php-cgi -d option=value`.
+ * Therefore, this code only prevents passing arguments if the query string starts with a '-'.
+ * Similarly, scripts spawned in subprocesses on Windows may have the same issue. */
if((query_string = getenv("QUERY_STRING")) != NULL && strchr(query_string, '=') == NULL) {
- /* we've got query string that has no = - apache CGI will pass it to command line */
unsigned char *p;
decoded_query_string = strdup(query_string);
php_url_decode(decoded_query_string, strlen(decoded_query_string));
@@ -1838,6 +1843,22 @@ int main(int argc, char *argv[])
if(*p == '-') {
skip_getopt = 1;
}
+
+ /* On Windows we have to take into account the "best fit" mapping behaviour. */
+#ifdef PHP_WIN32
+ if (*p >= 0x80) {
+ wchar_t wide_buf[1];
+ wide_buf[0] = *p;
+ char char_buf[4];
+ size_t wide_buf_len = sizeof(wide_buf) / sizeof(wide_buf[0]);
+ size_t char_buf_len = sizeof(char_buf) / sizeof(char_buf[0]);
+ if (WideCharToMultiByte(CP_ACP, 0, wide_buf, wide_buf_len, char_buf, char_buf_len, NULL, NULL) == 0
+ || char_buf[0] == '-') {
+ skip_getopt = 1;
+ }
+ }
+#endif
+
free(decoded_query_string);
}
diff --git a/sapi/cgi/tests/ghsa-3qgc-jrrr-25jv.phpt b/sapi/cgi/tests/ghsa-3qgc-jrrr-25jv.phpt
new file mode 100644
index 00000000000..fd2fcdfbf89
--- /dev/null
+++ b/sapi/cgi/tests/ghsa-3qgc-jrrr-25jv.phpt
@@ -0,0 +1,38 @@
+--TEST--
+GHSA-3qgc-jrrr-25jv
+--SKIPIF--
+<?php
+include 'skipif.inc';
+if (PHP_OS_FAMILY !== "Windows") die("skip Only for Windows");
+
+$codepage = trim(shell_exec("powershell Get-ItemPropertyValue HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage ACP"));
+if ($codepage !== '932' && $codepage !== '936' && $codepage !== '950') die("skip Wrong codepage");
+?>
+--FILE--
+<?php
+include 'include.inc';
+
+$filename = __DIR__."/GHSA-3qgc-jrrr-25jv_tmp.php";
+$script = '<?php echo "hello "; echo "world"; ?>';
+file_put_contents($filename, $script);
+
+$php = get_cgi_path();
+reset_env_vars();
+
+putenv("SERVER_NAME=Test");
+putenv("SCRIPT_FILENAME=$filename");
+putenv("QUERY_STRING=%ads");
+putenv("REDIRECT_STATUS=1");
+
+passthru("$php -s");
+
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__."/GHSA-3qgc-jrrr-25jv_tmp.php");
+?>
+--EXPECTF--
+X-Powered-By: PHP/%s
+Content-type: %s
+
+hello world
--
2.46.1
From a634d3f5169c884715d9e26ac213ecf2a25c3666 Mon Sep 17 00:00:00 2001
From: Jan Ehrhardt <github@ehrhardt.nl>
Date: Sun, 9 Jun 2024 20:09:02 +0200
Subject: [PATCH 03/11] NEWS: Add backports from 8.1.29
---
NEWS | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/NEWS b/NEWS
index 34ad33cf5c4..a96518695fb 100644
--- a/NEWS
+++ b/NEWS
@@ -3,10 +3,18 @@ PHP NEWS
Backported from 8.1.29
+- CGI:
+ . Fixed bug GHSA-3qgc-jrrr-25jv (Bypass of CVE-2012-1823, Argument Injection
+ in PHP-CGI). (CVE-2024-4577) (nielsdos)
+
- Filter:
. Fixed bug GHSA-w8qr-v226-r27w (Filter bypass in filter_var FILTER_VALIDATE_URL).
(CVE-2024-5458) (nielsdos)
+- Standard:
+ . Fixed bug GHSA-9fcc-425m-g385 (Bypass of CVE-2024-1874).
+ (CVE-2024-5585) (nielsdos)
+
Backported from 8.1.28
- Standard:
--
2.46.1
From 1158d06f0b20532ab7309cb20f0be843f9662e3c Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Fri, 14 Jun 2024 19:49:22 +0200
Subject: [PATCH 05/11] Fix GHSA-p99j-rfp4-xqvq
It's no use trying to work around whatever the operating system and Apache
do because we'll be fighting that until eternity.
Change the skip_getopt condition such that when we're running in
CGI or FastCGI mode we always skip the argument parsing.
This is a BC break, but this seems to be the only way to get rid of this
class of issues.
(cherry picked from commit abcfd980bfa03298792fd3aba051c78d52f10642)
(cherry picked from commit 2d2552e092b6ff32cd823692d512f126ee629842)
---
sapi/cgi/cgi_main.c | 26 ++++++++------------------
1 file changed, 8 insertions(+), 18 deletions(-)
diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
index 8d1342727dc..a2761aafd7b 100644
--- a/sapi/cgi/cgi_main.c
+++ b/sapi/cgi/cgi_main.c
@@ -1777,7 +1777,6 @@ int main(int argc, char *argv[])
int status = 0;
#endif
char *query_string;
- char *decoded_query_string;
int skip_getopt = 0;
#if defined(SIGPIPE) && defined(SIG_IGN)
@@ -1832,10 +1831,15 @@ int main(int argc, char *argv[])
* the executable. Ideally we skip argument parsing when we're in cgi or fastcgi mode,
* but that breaks PHP scripts on Linux with a hashbang: `#!/php-cgi -d option=value`.
* Therefore, this code only prevents passing arguments if the query string starts with a '-'.
- * Similarly, scripts spawned in subprocesses on Windows may have the same issue. */
+ * Similarly, scripts spawned in subprocesses on Windows may have the same issue.
+ * However, Windows has lots of conversion rules and command line parsing rules that
+ * are too difficult and dangerous to reliably emulate. */
if((query_string = getenv("QUERY_STRING")) != NULL && strchr(query_string, '=') == NULL) {
+#ifdef PHP_WIN32
+ skip_getopt = cgi || fastcgi;
+#else
unsigned char *p;
- decoded_query_string = strdup(query_string);
+ char *decoded_query_string = strdup(query_string);
php_url_decode(decoded_query_string, strlen(decoded_query_string));
for (p = (unsigned char *)decoded_query_string; *p && *p <= ' '; p++) {
/* skip all leading spaces */
@@ -1844,22 +1848,8 @@ int main(int argc, char *argv[])
skip_getopt = 1;
}
- /* On Windows we have to take into account the "best fit" mapping behaviour. */
-#ifdef PHP_WIN32
- if (*p >= 0x80) {
- wchar_t wide_buf[1];
- wide_buf[0] = *p;
- char char_buf[4];
- size_t wide_buf_len = sizeof(wide_buf) / sizeof(wide_buf[0]);
- size_t char_buf_len = sizeof(char_buf) / sizeof(char_buf[0]);
- if (WideCharToMultiByte(CP_ACP, 0, wide_buf, wide_buf_len, char_buf, char_buf_len, NULL, NULL) == 0
- || char_buf[0] == '-') {
- skip_getopt = 1;
- }
- }
-#endif
-
free(decoded_query_string);
+#endif
}
while (!skip_getopt && (c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
--
2.46.1

57
php-cve-2024-8927.patch Normal file
View File

@ -0,0 +1,57 @@
From c7308ba7cd0533501b40eba255602bb5e085550f Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Tue, 18 Jun 2024 21:28:26 +0200
Subject: [PATCH 06/11] Fix GHSA-94p6-54jq-9mwp
Apache only generates REDIRECT_STATUS, so explicitly check for that
if the server name is Apache, don't allow other variable names.
Furthermore, redirect.so and Netscape no longer exist, so
remove those entries as we can't check their server name anymore.
We now also check for the configuration override *first* such that it
always take precedence. This would allow for a mitigation path if
something like this happens in the future.
(cherry picked from commit 48808d98f4fc2a05193cdcc1aedd6c66816450f1)
(cherry picked from commit 8aa748ee0657cdee8d883ba50d04b68bc450f686)
---
sapi/cgi/cgi_main.c | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
index a2761aafd7b..ebce6302b93 100644
--- a/sapi/cgi/cgi_main.c
+++ b/sapi/cgi/cgi_main.c
@@ -1939,18 +1939,17 @@ int main(int argc, char *argv[])
/* check force_cgi after startup, so we have proper output */
if (cgi && CGIG(force_redirect)) {
- /* Apache will generate REDIRECT_STATUS,
- * Netscape and redirect.so will generate HTTP_REDIRECT_STATUS.
- * redirect.so and installation instructions available from
- * http://www.koehntopp.de/php.
- * -- kk@netuse.de
- */
- if (!getenv("REDIRECT_STATUS") &&
- !getenv ("HTTP_REDIRECT_STATUS") &&
- /* this is to allow a different env var to be configured
- * in case some server does something different than above */
- (!CGIG(redirect_status_env) || !getenv(CGIG(redirect_status_env)))
- ) {
+ /* This is to allow a different environment variable to be configured
+ * in case the we cannot auto-detect which environment variable to use.
+ * Checking this first to allow user overrides in case the environment
+ * variable can be set by an untrusted party. */
+ const char *redirect_status_env = CGIG(redirect_status_env);
+ if (!redirect_status_env) {
+ /* Apache will generate REDIRECT_STATUS. */
+ redirect_status_env = "REDIRECT_STATUS";
+ }
+
+ if (!getenv(redirect_status_env)) {
zend_try {
SG(sapi_headers).http_response_code = 400;
PUTS("<b>Security Alert!</b> The PHP CGI cannot be accessed directly.\n\n\
--
2.46.1

245
php-cve-2024-9026.patch Normal file
View File

@ -0,0 +1,245 @@
From 4a8b8fa2592bd8862adeacb5b2faacb30500b9f9 Mon Sep 17 00:00:00 2001
From: Jakub Zelenka <bukka@php.net>
Date: Thu, 12 Sep 2024 13:11:11 +0100
Subject: [PATCH 07/11] Fix GHSA-865w-9rf3-2wh5: FPM: Logs from childrens may
be altered
(cherry picked from commit 1f8e16172c7961045c2b0f34ba7613e3f21cdee8)
(cherry picked from commit 22f4d3504d7613ce78bb96aa53cbfe7d672fa036)
---
sapi/fpm/fpm/fpm_stdio.c | 2 +-
.../log-bwp-msg-flush-split-sep-pos-end.phpt | 47 +++++++++++++++++++
...log-bwp-msg-flush-split-sep-pos-start.phpt | 47 +++++++++++++++++++
3 files changed, 95 insertions(+), 1 deletion(-)
create mode 100644 sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt
create mode 100644 sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt
diff --git a/sapi/fpm/fpm/fpm_stdio.c b/sapi/fpm/fpm/fpm_stdio.c
index ddedfb48c7c..9d87273314a 100644
--- a/sapi/fpm/fpm/fpm_stdio.c
+++ b/sapi/fpm/fpm/fpm_stdio.c
@@ -177,7 +177,7 @@ stdio_read:
if ((sizeof(FPM_STDIO_CMD_FLUSH) - cmd_pos) <= in_buf &&
!memcmp(buf, &FPM_STDIO_CMD_FLUSH[cmd_pos], sizeof(FPM_STDIO_CMD_FLUSH) - cmd_pos)) {
zlog_stream_finish(log_stream);
- start = cmd_pos;
+ start = sizeof(FPM_STDIO_CMD_FLUSH) - cmd_pos;
} else {
zlog_stream_str(log_stream, &FPM_STDIO_CMD_FLUSH[0], cmd_pos);
}
diff --git a/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt
new file mode 100644
index 00000000000..52826320080
--- /dev/null
+++ b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt
@@ -0,0 +1,47 @@
+--TEST--
+FPM: Buffered worker output plain log with msg with flush split position towards separator end
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--FILE--
+<?php
+
+require_once "tester.inc";
+
+$cfg = <<<EOT
+[global]
+error_log = {{FILE:LOG}}
+[unconfined]
+listen = {{ADDR}}
+pm = dynamic
+pm.max_children = 5
+pm.start_servers = 1
+pm.min_spare_servers = 1
+pm.max_spare_servers = 3
+catch_workers_output = yes
+decorate_workers_output = no
+EOT;
+
+$code = <<<EOT
+<?php
+file_put_contents('php://stderr', str_repeat('a', 1013) . "Quarkslab\0fscf\0Quarkslab");
+EOT;
+
+$tester = new FPM\Tester($cfg, $code);
+$tester->start();
+$tester->expectLogStartNotices();
+$tester->request()->expectEmptyBody();
+$tester->expectLogLine(str_repeat('a', 1013) . "Quarkslab", decorated: false);
+$tester->expectLogLine("Quarkslab", decorated: false);
+$tester->terminate();
+$tester->expectLogTerminatingNotices();
+$tester->close();
+
+?>
+Done
+--EXPECT--
+Done
+--CLEAN--
+<?php
+require_once "tester.inc";
+FPM\Tester::clean();
+?>
diff --git a/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt
new file mode 100644
index 00000000000..34905938553
--- /dev/null
+++ b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt
@@ -0,0 +1,47 @@
+--TEST--
+FPM: Buffered worker output plain log with msg with flush split position towards separator start
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--FILE--
+<?php
+
+require_once "tester.inc";
+
+$cfg = <<<EOT
+[global]
+error_log = {{FILE:LOG}}
+[unconfined]
+listen = {{ADDR}}
+pm = dynamic
+pm.max_children = 5
+pm.start_servers = 1
+pm.min_spare_servers = 1
+pm.max_spare_servers = 3
+catch_workers_output = yes
+decorate_workers_output = no
+EOT;
+
+$code = <<<EOT
+<?php
+file_put_contents('php://stderr', str_repeat('a', 1009) . "Quarkslab\0fscf\0Quarkslab");
+EOT;
+
+$tester = new FPM\Tester($cfg, $code);
+$tester->start();
+$tester->expectLogStartNotices();
+$tester->request()->expectEmptyBody();
+$tester->expectLogLine(str_repeat('a', 1009) . "Quarkslab", decorated: false);
+$tester->expectLogLine("Quarkslab", decorated: false);
+$tester->terminate();
+$tester->expectLogTerminatingNotices();
+$tester->close();
+
+?>
+Done
+--EXPECT--
+Done
+--CLEAN--
+<?php
+require_once "tester.inc";
+FPM\Tester::clean();
+?>
--
2.46.1
From 1154fbd3ddfa418bf2492c5366adaefb47c47737 Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Thu, 26 Sep 2024 11:50:54 +0200
Subject: [PATCH 09/11] NEWS for 8.1.30 backports
(cherry picked from commit af3fb385e7b328ab89db26ec712d89c7096f0743)
---
NEWS | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/NEWS b/NEWS
index a96518695fb..62616d6312d 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,23 @@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+Backported from 8.1.30
+
+- CGI:
+ . Fixed bug GHSA-p99j-rfp4-xqvq (Bypass of CVE-2024-4577, Parameter Injection
+ Vulnerability). (CVE-2024-8926) (nielsdos)
+ . Fixed bug GHSA-94p6-54jq-9mwp (cgi.force_redirect configuration is
+ bypassable due to the environment variable collision). (CVE-2024-8927)
+ (nielsdos)
+
+- FPM:
+ . Fixed bug GHSA-865w-9rf3-2wh5 (Logs from childrens may be altered).
+ (CVE-2024-9026) (Jakub Zelenka)
+
+- SAPI:
+ . Fixed bug GHSA-9pqp-7h25-4f32 (Erroneous parsing of multipart form data).
+ (CVE-2024-8925) (Arnaud)
+
Backported from 8.1.29
- CGI:
--
2.46.1
From bc574c256596abc4966e7f0e3e0913839092151e Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Thu, 26 Sep 2024 15:48:11 +0200
Subject: [PATCH 10/11] adapt GHSA-865w-9rf3-2wh5 test for 7.x
---
sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt | 4 ++--
sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt | 4 ++--
sapi/fpm/tests/tester.inc | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt
index 52826320080..bdd61782bfa 100644
--- a/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt
+++ b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt
@@ -30,8 +30,8 @@ $tester = new FPM\Tester($cfg, $code);
$tester->start();
$tester->expectLogStartNotices();
$tester->request()->expectEmptyBody();
-$tester->expectLogLine(str_repeat('a', 1013) . "Quarkslab", decorated: false);
-$tester->expectLogLine("Quarkslab", decorated: false);
+$tester->expectLogLine(str_repeat('a', 1013) . "Quarkslab", true, false);
+$tester->expectLogLine("Quarkslab", true, false);
$tester->terminate();
$tester->expectLogTerminatingNotices();
$tester->close();
diff --git a/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt
index 34905938553..f3461e4a0c8 100644
--- a/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt
+++ b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt
@@ -30,8 +30,8 @@ $tester = new FPM\Tester($cfg, $code);
$tester->start();
$tester->expectLogStartNotices();
$tester->request()->expectEmptyBody();
-$tester->expectLogLine(str_repeat('a', 1009) . "Quarkslab", decorated: false);
-$tester->expectLogLine("Quarkslab", decorated: false);
+$tester->expectLogLine(str_repeat('a', 1009) . "Quarkslab", true, false);
+$tester->expectLogLine("Quarkslab", true, false);
$tester->terminate();
$tester->expectLogTerminatingNotices();
$tester->close();
diff --git a/sapi/fpm/tests/tester.inc b/sapi/fpm/tests/tester.inc
index 7868afc4ac1..fe5f0c2fde7 100644
--- a/sapi/fpm/tests/tester.inc
+++ b/sapi/fpm/tests/tester.inc
@@ -1315,7 +1315,7 @@ class Tester
* @param string $message
* @return bool
*/
- public function expectLogLine(string $message, bool $is_stderr = true)
+ public function expectLogLine(string $message, bool $is_stderr = true, bool $decorated = true)
{
$messageLen = strlen($message);
$limit = $messageLen > 1024 ? $messageLen + 16 : 1024;
@@ -1325,7 +1325,7 @@ class Tester
$this->message("LOG LINE: " . ($logLines[0] ?? ''));
}
- return $this->logTool->checkWrappedMessage($logLines, false, true, $is_stderr);
+ return $this->logTool->checkWrappedMessage($logLines, false, $decorated, $is_stderr);
}
/**
--
2.46.1

View File

@ -1,5 +1,5 @@
; Start a new pool named 'www'.
; the variable $pool can we used in any directive and will be replaced by the
; the variable $pool can be used in any directive and will be replaced by the
; pool name ('www' here)
[www]
@ -128,7 +128,7 @@ pm.min_spare_servers = 5
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
pm.max_spare_servers = 35
; The number of seconds after which an idle process will be killed.
; Note: Used only when pm is set to 'ondemand'
; Default Value: 10s
@ -238,7 +238,7 @@ pm.max_spare_servers = 35
; may conflict with a real PHP file.
; Default Value: not set
;pm.status_path = /status
; The ping URI to call the monitoring page of FPM. If this value is not set, no
; URI will be recognized as a ping page. This could be used to test from outside
; that FPM is alive and responding, or to
@ -255,7 +255,7 @@ pm.max_spare_servers = 35
; response is formatted as text/plain with a 200 response code.
; Default Value: pong
;ping.response = pong
; The access log file
; Default: not set
;access.log = log/$pool.access.log
@ -330,22 +330,26 @@ slowlog = /var/log/php-fpm/www-slow.log
; Default Value: 0
;request_slowlog_timeout = 0
; Depth of slow log stack trace.
; Default Value: 20
;request_slowlog_trace_depth = 20
; The timeout for serving a single request after which the worker process will
; be killed. This option should be used when the 'max_execution_time' ini option
; does not stop script execution for some reason. A value of '0' means 'off'.
; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
; Default Value: 0
;request_terminate_timeout = 0
; Set open file descriptor rlimit.
; Default Value: system defined value
;rlimit_files = 1024
; Set max core size rlimit.
; Possible Values: 'unlimited' or an integer greater or equal to 0
; Default Value: system defined value
;rlimit_core = 0
; Chroot to this directory at the start. This value must be defined as an
; absolute path. When this value is not set, chroot is not used.
; Note: you can prefix with '$prefix' to chroot to the pool prefix or one
@ -355,20 +359,20 @@ slowlog = /var/log/php-fpm/www-slow.log
; possible. However, all PHP paths will be relative to the chroot
; (error_log, sessions.save_path, ...).
; Default Value: not set
;chroot =
;chroot =
; Chdir to this directory at the start.
; Note: relative path can be used.
; Default Value: current directory or / when chroot
;chdir = /var/www
; Redirect worker stdout and stderr into main error log. If not set, stdout and
; stderr will be redirected to /dev/null according to FastCGI specs.
; Note: on highloaded environement, this can cause some delay in the page
; process time (several ms).
; Default Value: no
;catch_workers_output = yes
; Clear environment in FPM workers
; Prevents arbitrary environment variables from reaching FPM worker processes
; by clearing the environment in workers before env vars specified in this
@ -381,7 +385,7 @@ slowlog = /var/log/php-fpm/www-slow.log
; Limits the extensions of the main script FPM will allow to parse. This can
; prevent configuration mistakes on the web server side. You should only limit
; FPM to .php extensions to prevent malicious users to use other extensions to
; exectute php code.
; execute php code.
; Note: set an empty value to allow all extensions.
; Default Value: .php
;security.limit_extensions = .php .php3 .php4 .php5 .php7
@ -399,7 +403,7 @@ slowlog = /var/log/php-fpm/www-slow.log
; overwrite the values previously defined in the php.ini. The directives are the
; same as the PHP SAPI:
; php_value/php_flag - you can set classic ini defines which can
; be overwritten from PHP call 'ini_set'.
; be overwritten from PHP call 'ini_set'.
; php_admin_value/php_admin_flag - these directives won't be overwritten by
; PHP call 'ini_set'
; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no.

View File

@ -43,6 +43,24 @@ error_log = /var/log/php-fpm/error.log
; Default Value: notice
;log_level = notice
; Log limit on number of characters in the single line (log entry). If the
; line is over the limit, it is wrapped on multiple lines. The limit is for
; all logged characters including message prefix and suffix if present. However
; the new line character does not count into it as it is present only when
; logging to a file descriptor. It means the new line character is not present
; when logging to syslog.
; Default Value: 1024
;log_limit = 4096
; Log buffering specifies if the log line is buffered which means that the
; line is written in a single write operation. If the value is false, then the
; data is written directly into the file descriptor. It is an experimental
; option that can potentionaly improve logging performance and memory usage
; for some heavy logging scenarios. This option is ignored if logging to syslog
; as it has to be always buffered.
; Default value: yes
;log_buffering = no
; If this number of child processes exit with SIGSEGV or SIGBUS within the time
; interval set by emergency_restart_interval then FPM will restart. A value
; of '0' means 'Off'.

320
php-keyring.gpg Normal file
View File

@ -0,0 +1,320 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
jZkkGZj3BY/7ApoLq4mwqzbh+CpLXwNn20tFNvSXfb8RdeXvVEb7Scx+W9qYpiau
n2iXJgCVH8fgpZpR856ulT1q6uCG++CXubEvip/eJkZl93/84h04KQJwsgOrAh0O
m3OePRn8Pr+++0LNS0EL8uX/YHeTOGOnnmTqYTeySBVFdov6L4mepddfjekicKQq
hL7mZh/xuq29JijT0uNNX8v4vDWQDu5dlAcdd+uB3gcXMD/PginD11zp+6wtrWCm
/+yBqpvDwXQX5PGUnwvbRfl7Ay3MmwmoXiecZMg0dwTSc7e0lhB4HGRHZdBMJB4r
HUVGdzqujK/ctOvrAAMFB/0Utb76Qe6sCMlHxVAmeE/fbo7Pi05btZ/x01r67dHf
aMSP0riCKJ7M0OW+jAXtu9+z/BVnYisW67WWfxl2cS5tZDgiHgJARXWUOO72+sSc
HP8KQmTl1z16gyKbwY3SmyBkwcpOL35nhUWNLy93syPoY6sZUTikr2bZYukHDQ33
XBPs4e6MbWKfsa9qaVmnlOF3k5UqChjutfHaEa4Q7VP4wBIpphHBi9MI16oJIzzB
PbGl2uoedjwiZ6QeQZnSuOVYZxU2d3lRA8PrtfFN1VSlpEm/VcAvtieHUYWHN0wO
u+cp3Slr5XJVNjTjJhl28SlinMME54mKAGf2Ldr/dRwXiGEEGBEIAAkFAk9mqaAC
GwwACgkQL3lWvF2gS126EQD/VVd3FgjLKglClRQPzdfU847tqDK4zJjbmRv5vLLw
oE0A+wbrQs7jVGU3NrS0AIl5vUmewpp2BKzSkepy23nWmejwmQINBFjxRtoBEADk
S6+Q7afwYDPFnqJXuyF2ZIvXysDBrpr/xbre4jVeiC/HIELaQedOJqO1V+BgnTRk
fhor+Yq3mZ1un+6zJIiFcm5Kp7sPZjh15JF96PsA4e2Eh5eCeJzjXHj1nAKXfn5+
CgpYEyL30r1/ACkmo9TKIiUxIDZRkZvxjY4UKeo+EoJo0ViutV8mvSTgxaz9gzPh
Z5OJR8zECT8j3T8d+tBD8wWxxmGZ0veOu/MBew1C/BDr8RqTCXDywUbyNuSsdb3a
5aLuIuLekSJVSCcFwPIje1WrX4FyC42+elOp0SXpjWzdb08NXX4DEY8zVyVXI1Sc
SpTbslffcFkY60NJhjpP7t856L9vTLRfHIM9BIdSYH/ar5mEQ0vyJbiNfkx5tIMn
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
RbbnRGir0GxlvcmpWMLo+2IqeVyRrbY=
=jKsj
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -15,7 +15,7 @@
; 5. The web server's directory (for SAPI modules), or directory of PHP
; (otherwise in Windows)
; 6. The directory from the --with-config-file-path compile time option, or the
; Windows directory (C:\windows or C:\winnt)
; Windows directory (usually C:\windows)
; See the PHP docs for more specific information.
; http://php.net/configuration.file
@ -58,9 +58,9 @@
; An empty string can be denoted by simply not writing anything after the equal
; sign, or by using the None keyword:
; foo = ; sets foo to an empty string
; foo = None ; sets foo to an empty string
; foo = "None" ; sets foo to the string 'None'
; foo = ; sets foo to an empty string
; foo = None ; sets foo to an empty string
; foo = "None" ; sets foo to the string 'None'
; If you use constants in your value, and these constants belong to a
; dynamically loaded extension (either a PHP extension or a Zend extension),
@ -83,7 +83,7 @@
; development version only in development environments, as errors shown to
; application users can inadvertently leak otherwise secure information.
; This is php.ini-production INI file.
; This is the php.ini-production INI file.
;;;;;;;;;;;;;;;;;;;
; Quick Reference ;
@ -108,11 +108,6 @@
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; html_errors
; Default Value: On
; Development Value: On
; Production value: On
; log_errors
; Default Value: Off
; Development Value: On
@ -153,11 +148,6 @@
; Development Value: Off
; Production Value: Off
; track_errors
; Default Value: Off
; Development Value: On
; Production Value: Off
; variables_order
; Default Value: "EGPCS"
; Development Value: "GPCS"
@ -169,7 +159,7 @@
; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini"
;user_ini.filename = ".user.ini"
; To disable this feature set this option to empty value
; To disable this feature set this option to an empty value
;user_ini.filename =
; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes)
@ -248,7 +238,7 @@ output_buffering = 4096
; Production Value: "form="
;url_rewriter.tags
; URL rewriter will not rewrites absolute URL nor form by default. To enable
; URL rewriter will not rewrite absolute URL nor form by default. To enable
; absolute URL rewrite, allowed hosts must be defined at RUNTIME.
; Refer to session.trans_sid_hosts for more details.
; Default Value: ""
@ -294,6 +284,13 @@ implicit_flush = Off
; callback-function.
unserialize_callback_func =
; The unserialize_max_depth specifies the default depth limit for unserialized
; structures. Setting the depth limit too high may result in stack overflows
; during unserialization. The unserialize_max_depth ini setting can be
; overridden by the max_depth option on individual unserialize() calls.
; A value of 0 disables the depth limit.
;unserialize_max_depth = 4096
; When floats & doubles are serialized, store serialize_precision significant
; digits after the floating point. The default value ensures that when floats
; are decoded with unserialize, the data will remain the same.
@ -305,6 +302,7 @@ serialize_precision = -1
; open_basedir, if set, limits all file operations to the defined directory
; and below. This directive makes most sense if used in a per-directory
; or per-virtualhost web server configuration file.
; Note: disables the realpath cache
; http://php.net/open-basedir
;open_basedir =
@ -337,6 +335,7 @@ disable_classes =
; Determines the size of the realpath cache to be used by PHP. This value should
; be increased on systems where PHP opens many files to reflect the quantity of
; the file operations performed.
; Note: if open_basedir is set, the cache is disabled
; http://php.net/realpath-cache-size
;realpath_cache_size = 4096k
@ -362,6 +361,12 @@ zend.enable_gc = On
; Default: ""
;zend.script_encoding =
; Allows to include or exclude arguments from stack traces generated for exceptions
; Default: Off
; In production, it is recommended to turn this setting on to prohibit the output
; of sensitive information in stack traces
zend.exception_ignore_args = On
;;;;;;;;;;;;;;;;;
; Miscellaneous ;
;;;;;;;;;;;;;;;;;
@ -397,7 +402,7 @@ max_input_time = 60
;max_input_nesting_level = 64
; How many GET/POST/COOKIE input variables may be accepted
; max_input_vars = 1000
;max_input_vars = 1000
; Maximum amount of memory a script may consume (128MB)
; http://php.net/memory-limit
@ -514,7 +519,7 @@ ignore_repeated_errors = Off
ignore_repeated_source = Off
; If this parameter is set to Off, then memory leaks will not be shown (on
; stdout or in the log). This has only effect in a debug compile, and if
; stdout or in the log). This is only effective in a debug compile, and if
; error reporting includes E_WARNING in the allowed list
; http://php.net/report-memleaks
report_memleaks = On
@ -543,11 +548,8 @@ report_memleaks = On
; error message as HTML for easier reading. This directive controls whether
; the error message is formatted as HTML or not.
; Note: This directive is hardcoded to Off for the CLI SAPI
; Default Value: On
; Development Value: On
; Production value: On
; http://php.net/html-errors
html_errors = On
;html_errors = On
; If html_errors is set to On *and* docref_root is not empty, then PHP
; produces clickable error messages that direct to a page describing the error
@ -582,9 +584,29 @@ html_errors = On
; http://php.net/error-log
; Example:
;error_log = php_errors.log
; Log errors to syslog.
; Log errors to syslog (Event Log on Windows).
;error_log = syslog
; The syslog ident is a string which is prepended to every message logged
; to syslog. Only used when error_log is set to syslog.
;syslog.ident = php
; The syslog facility is used to specify what type of program is logging
; the message. Only used when error_log is set to syslog.
;syslog.facility = user
; Set this to disable filtering control characters (the default).
; Some loggers only accept NVT-ASCII, others accept anything that's not
; control characters. If your logger accepts everything, then no filtering
; is needed at all.
; Allowed values are:
; ascii (all printable ASCII characters and NL)
; no-ctrl (all characters except control characters)
; all (all characters)
; raw (like "all", but messages are not split at newlines)
; http://php.net/syslog.filter
;syslog.filter = ascii
;windows.show_crt_warning
; Default value: 0
; Development value: 0
@ -652,7 +674,7 @@ register_argc_argv = Off
; first used (Just In Time) instead of when the script starts. If these
; variables are not used within a script, having this directive on will result
; in a performance gain. The PHP directive register_argc_argv must be disabled
; for this directive to have any affect.
; for this directive to have any effect.
; http://php.net/auto-globals-jit
auto_globals_jit = On
@ -734,13 +756,13 @@ user_dir =
; Directory in which the loadable extensions (modules) reside.
; http://php.net/extension-dir
; extension_dir = "./"
;extension_dir = "./"
; On windows:
; extension_dir = "ext"
;extension_dir = "ext"
; Directory where the temporary files should be placed.
; Defaults to the system default (see sys_get_temp_dir)
; sys_temp_dir = "/tmp"
;sys_temp_dir = "/tmp"
; Whether or not to enable the dl() function. The dl() function does NOT work
; properly in multithreaded servers, such as IIS or Zeus, and is automatically
@ -777,10 +799,9 @@ enable_dl = Off
; if cgi.discard_path is enabled, the PHP CGI binary can safely be placed outside
; of the web tree and people will not be able to circumvent .htaccess security.
; http://php.net/cgi.dicard-path
;cgi.discard_path=1
; FastCGI under IIS (on WINNT based OS) supports the ability to impersonate
; FastCGI under IIS supports the ability to impersonate
; security tokens of the calling client. This allows IIS to define the
; security context that the request runs under. mod_fastcgi under Apache
; does not currently support this feature (03/17/2002)
@ -923,7 +944,7 @@ cli_server.color = On
[iconv]
; Use of this INI entry is deprecated, use global input_encoding instead.
; If empty, default_charset or input_encoding or iconv.input_encoding is used.
; The precedence is: default_charset < intput_encoding < iconv.input_encoding
; The precedence is: default_charset < input_encoding < iconv.input_encoding
;iconv.input_encoding =
; Use of this INI entry is deprecated, use global internal_encoding instead.
@ -938,6 +959,13 @@ cli_server.color = On
; otherwise output encoding conversion cannot be performed.
;iconv.output_encoding =
[imap]
; rsh/ssh logins are disabled by default. Use this INI entry if you want to
; enable them. Note that the IMAP library does not filter mailbox names before
; passing them to rsh/ssh command, thus passing untrusted data to this function
; with rsh/ssh enabled is insecure.
;imap.enable_insecure_rsh=0
[intl]
;intl.default_locale =
; This directive allows you to produce PHP errors when some error
@ -947,22 +975,33 @@ cli_server.color = On
;intl.use_exceptions = 0
[sqlite3]
; Directory pointing to SQLite3 extensions
; http://php.net/sqlite3.extension-dir
;sqlite3.extension_dir =
; SQLite defensive mode flag (only available from SQLite 3.26+)
; When the defensive flag is enabled, language features that allow ordinary
; SQL to deliberately corrupt the database file are disabled. This forbids
; writing directly to the schema, shadow tables (eg. FTS data tables), or
; the sqlite_dbpage virtual table.
; https://www.sqlite.org/c3ref/c_dbconfig_defensive.html
; (for older SQLite versions, this flag has no use)
;sqlite3.defensive = 1
[Pcre]
;PCRE library backtracking limit.
; PCRE library backtracking limit.
; http://php.net/pcre.backtrack-limit
;pcre.backtrack_limit=100000
;PCRE library recursion limit.
;Please note that if you set this value to a high number you may consume all
;the available process stack and eventually crash PHP (due to reaching the
;stack size limit imposed by the Operating System).
; PCRE library recursion limit.
; Please note that if you set this value to a high number you may consume all
; the available process stack and eventually crash PHP (due to reaching the
; stack size limit imposed by the Operating System).
; http://php.net/pcre.recursion-limit
;pcre.recursion_limit=100000
;Enables or disables JIT compilation of patterns. This requires the PCRE
;library to be compiled with JIT support.
; Enables or disables JIT compilation of patterns. This requires the PCRE
; library to be compiled with JIT support.
pcre.jit=0
[Pdo]
@ -973,13 +1012,8 @@ pcre.jit=0
;pdo_odbc.db2_instance_name
[Pdo_mysql]
; If mysqlnd is used: Number of cache slots for the internal result set cache
; http://php.net/pdo_mysql.cache_size
pdo_mysql.cache_size = 2000
; Default socket name for local MySQL connects. If empty, uses the built-in
; MySQL defaults.
; http://php.net/pdo_mysql.default-socket
pdo_mysql.default_socket=
[Phar]
@ -1002,12 +1036,12 @@ sendmail_path = /usr/sbin/sendmail -t -i
;mail.force_extra_parameters =
; Add X-PHP-Originating-Script: that will include uid of the script followed by the filename
mail.add_x_header = On
mail.add_x_header = Off
; The path to a log file that will log all mail() calls. Log entries include
; the full path of the script, line number, To address and headers.
;mail.log =
; Log mail to syslog;
; Log mail to syslog (Event Log on Windows).
;mail.log = syslog
[ODBC]
@ -1051,39 +1085,6 @@ odbc.defaultlrl = 4096
; http://php.net/odbc.defaultbinmode
odbc.defaultbinmode = 1
;birdstep.max_links = -1
[Interbase]
; Allow or prevent persistent links.
ibase.allow_persistent = 1
; Maximum number of persistent links. -1 means no limit.
ibase.max_persistent = -1
; Maximum number of links (persistent + non-persistent). -1 means no limit.
ibase.max_links = -1
; Default database name for ibase_connect().
;ibase.default_db =
; Default username for ibase_connect().
;ibase.default_user =
; Default password for ibase_connect().
;ibase.default_password =
; Default charset for ibase_connect().
;ibase.default_charset =
; Default timestamp format.
ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
; Default date format.
ibase.dateformat = "%Y-%m-%d"
; Default time format.
ibase.timeformat = "%H:%M:%S"
[MySQLi]
; Maximum number of persistent links. -1 means no limit.
@ -1102,10 +1103,6 @@ mysqli.allow_persistent = On
; http://php.net/mysqli.max-links
mysqli.max_links = -1
; If mysqlnd is used: Number of cache slots for the internal result set cache
; http://php.net/mysqli.cache_size
mysqli.cache_size = 2000
; Default port number for mysqli_connect(). If unset, mysqli_connect() will use
; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the
; compile-time value defined MYSQL_PORT (in that order). Win32 will only look
@ -1118,11 +1115,11 @@ mysqli.default_port = 3306
; http://php.net/mysqli.default-socket
mysqli.default_socket =
; Default host for mysql_connect() (doesn't apply in safe mode).
; Default host for mysqli_connect() (doesn't apply in safe mode).
; http://php.net/mysqli.default-host
mysqli.default_host =
; Default user for mysql_connect() (doesn't apply in safe mode).
; Default user for mysqli_connect() (doesn't apply in safe mode).
; http://php.net/mysqli.default-user
mysqli.default_user =
@ -1140,12 +1137,10 @@ mysqli.reconnect = Off
[mysqlnd]
; Enable / Disable collection of general statistics by mysqlnd which can be
; used to tune and monitor MySQL operations.
; http://php.net/mysqlnd.collect_statistics
mysqlnd.collect_statistics = On
; Enable / Disable collection of memory usage statistics by mysqlnd which can be
; used to tune and monitor MySQL operations.
; http://php.net/mysqlnd.collect_memory_statistics
mysqlnd.collect_memory_statistics = Off
; Records communication from all extensions using mysqlnd to the specified log
@ -1154,29 +1149,23 @@ mysqlnd.collect_memory_statistics = Off
;mysqlnd.debug =
; Defines which queries will be logged.
; http://php.net/mysqlnd.log_mask
;mysqlnd.log_mask = 0
; Default size of the mysqlnd memory pool, which is used by result sets.
; http://php.net/mysqlnd.mempool_default_size
;mysqlnd.mempool_default_size = 16000
; Size of a pre-allocated buffer used when sending commands to MySQL in bytes.
; http://php.net/mysqlnd.net_cmd_buffer_size
;mysqlnd.net_cmd_buffer_size = 2048
; Size of a pre-allocated buffer used for reading data sent by the server in
; bytes.
; http://php.net/mysqlnd.net_read_buffer_size
;mysqlnd.net_read_buffer_size = 32768
; Timeout for network requests in seconds.
; http://php.net/mysqlnd.net_read_timeout
;mysqlnd.net_read_timeout = 31536000
; SHA-256 Authentication Plugin related. File with the MySQL server public RSA
; key.
; http://php.net/mysqlnd.sha256_server_public_key
;mysqlnd.sha256_server_public_key =
[PostgreSQL]
@ -1255,10 +1244,11 @@ session.save_handler = files
;session.save_path = "/tmp"
; Whether to use strict session mode.
; Strict session mode does not accept uninitialized session ID and regenerate
; session ID if browser sends uninitialized session ID. Strict mode protects
; applications from session fixation via session adoption vulnerability. It is
; disabled by default for maximum compatibility, but enabling it is encouraged.
; Strict session mode does not accept an uninitialized session ID, and
; regenerates the session ID if the browser sends an uninitialized session ID.
; Strict mode protects applications from session fixation via a session adoption
; vulnerability. It is disabled by default for maximum compatibility, but
; enabling it is encouraged.
; https://wiki.php.net/rfc/strict_sessions
session.use_strict_mode = 0
@ -1296,11 +1286,17 @@ session.cookie_path = /
; http://php.net/session.cookie-domain
session.cookie_domain =
; Whether or not to add the httpOnly flag to the cookie, which makes it inaccessible to browser scripting languages such as JavaScript.
; Whether or not to add the httpOnly flag to the cookie, which makes it
; inaccessible to browser scripting languages such as JavaScript.
; http://php.net/session.cookie-httponly
session.cookie_httponly =
; Handler used to serialize data. php is the standard serializer of PHP.
; Add SameSite attribute to cookie to help mitigate Cross-Site Request Forgery (CSRF/XSRF)
; Current valid values are "Lax" or "Strict"
; https://tools.ietf.org/html/draft-west-first-party-cookies-07
session.cookie_samesite =
; Handler used to serialize data. php is the standard serializer of PHP.
; http://php.net/session.serialize-handler
session.serialize_handler = php
@ -1309,7 +1305,7 @@ session.serialize_handler = php
; gc_probability/gc_divisor. Where session.gc_probability is the numerator
; and gc_divisor is the denominator in the equation. Setting this value to 1
; when the session.gc_divisor value is 100 will give you approximately a 1% chance
; the gc will run on any give request.
; the gc will run on any given request.
; Default Value: 1
; Development Value: 1
; Production Value: 1
@ -1319,10 +1315,10 @@ session.gc_probability = 1
; Defines the probability that the 'garbage collection' process is started on every
; session initialization. The probability is calculated by using the following equation:
; gc_probability/gc_divisor. Where session.gc_probability is the numerator and
; session.gc_divisor is the denominator in the equation. Setting this value to 1
; when the session.gc_divisor value is 100 will give you approximately a 1% chance
; the gc will run on any give request. Increasing this value to 1000 will give you
; a 0.1% chance the gc will run on any give request. For high volume production servers,
; session.gc_divisor is the denominator in the equation. Setting this value to 100
; when the session.gc_probability value is 1 will give you approximately a 1% chance
; the gc will run on any given request. Increasing this value to 1000 will give you
; a 0.1% chance the gc will run on any given request. For high volume production servers,
; this is a more efficient approach.
; Default Value: 100
; Development Value: 1000
@ -1373,7 +1369,7 @@ session.use_trans_sid = 0
; Set session ID character length. This value could be between 22 to 256.
; Shorter length than default is supported only for compatibility reason.
; Users should use 32 or more chars.
; http://php.net/session.sid_length
; http://php.net/session.sid-length
; Default Value: 32
; Development Value: 26
; Production Value: 26
@ -1392,7 +1388,7 @@ session.sid_length = 26
session.trans_sid_tags = "a=href,area=href,frame=src,form="
; URL rewriter does not rewrite absolute URLs by default.
; To enable rewrites for absolute pathes, target hosts must be specified
; To enable rewrites for absolute paths, target hosts must be specified
; at RUNTIME. i.e. use ini_set()
; <form> tags is special. PHP will check action attribute's URL regardless
; of session.trans_sid_tags setting.
@ -1481,7 +1477,7 @@ zend.assertions = -1
; http://php.net/assert.active
;assert.active = On
; Throw an AssertationException on failed assertions
; Throw an AssertionError on failed assertions
; http://php.net/assert.exception
;assert.exception = On
@ -1517,9 +1513,9 @@ zend.assertions = -1
; Use of this INI entry is deprecated, use global input_encoding instead.
; http input encoding.
; mbstring.encoding_traslation = On is needed to use this setting.
; mbstring.encoding_translation = On is needed to use this setting.
; If empty, default_charset or input_encoding or mbstring.input is used.
; The precedence is: default_charset < intput_encoding < mbsting.http_input
; The precedence is: default_charset < input_encoding < mbsting.http_input
; http://php.net/mbstring.http-input
;mbstring.http_input =
@ -1571,6 +1567,16 @@ zend.assertions = -1
; Default: mbstring.http_output_conv_mimetype=^(text/|application/xhtml\+xml)
;mbstring.http_output_conv_mimetype=
; This directive specifies maximum stack depth for mbstring regular expressions. It is similar
; to the pcre.recursion_limit for PCRE.
; Default: 100000
;mbstring.regex_stack_limit=100000
; This directive specifies maximum retry count for mbstring regular expressions. It is similar
; to the pcre.backtrack_limit for PCRE.
; Default: 1000000
;mbstring.regex_retry_limit=1000000
[gd]
; Tell the jpeg decode to ignore warnings and try to create
; a gd image. The warning will then be displayed as notices
@ -1645,6 +1651,9 @@ ldap.max_links = -1
[dba]
;dba.default_handler=
[opcache]
; see /etc/php.d/10-opcache.ini
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
@ -1668,6 +1677,5 @@ ldap.max_links = -1
; SSL stream context option.
;openssl.capath=
; Local Variables:
; tab-width: 4
; End:
[ffi]
; see /etc/php.d/20-ffi.ini

File diff suppressed because it is too large Load Diff

2
sources Normal file
View File

@ -0,0 +1,2 @@
SHA512 (php-7.4.33.tar.xz) = 499b63b99e5d8e8082ff89d3a91b4cb9a593ea7553b96e48863414c13d2e50275904ed29070e2232e529ee91160f505e6060a4d129cb5bf098aa5b6ea0928d3d
SHA512 (php-7.4.33.tar.xz.asc) = 7f33bb4d844a9701e1a12db14af7d8f880b470de8f0018ff727acea75a7d1de154acaabef6e66549e49ba4507181ca73ea3c6feed393f3c361bf4a3d1c274256