Fix pgsql extension does not check for errors during escaping CVE-2025-1735
Fix NULL Pointer Dereference in PHP SOAP Extension via Large XML Namespace Prefix CVE-2025-6491 Fix Null byte termination in hostnames CVE-2025-1220 Fix soap memory corruption Fix ldap_set_option() not applied on different ldap connections Resolves: RHEL-116532 Resolves: RHEL-80383 Resolves: RHEL-82078
This commit is contained in:
parent
a52e0350ba
commit
24221dbf44
655
php-8.0.30-ldap.patch
Normal file
655
php-8.0.30-ldap.patch
Normal file
@ -0,0 +1,655 @@
|
|||||||
|
From 8f69248f7631cbd0515604c5d7e68fc6ee0c5b97 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Remi Collet <remi@remirepo.net>
|
||||||
|
Date: Wed, 26 Feb 2025 17:26:08 +0100
|
||||||
|
Subject: [PATCH 1/4] Fix #17776 LDAP_OPT_X_TLS_REQUIRE_CERT can't be
|
||||||
|
overridden
|
||||||
|
|
||||||
|
(cherry picked from commit 389de7c6bf59e14145e932f4d3c0171803a3ba97)
|
||||||
|
---
|
||||||
|
ext/ldap/ldap.c | 89 ++++++++++++++++++------
|
||||||
|
ext/ldap/php_ldap.h | 1 +
|
||||||
|
ext/ldap/tests/ldap_start_tls_basic.phpt | 21 +++++-
|
||||||
|
ext/ldap/tests/ldaps_basic.phpt | 55 +++++++++++++++
|
||||||
|
4 files changed, 141 insertions(+), 25 deletions(-)
|
||||||
|
create mode 100644 ext/ldap/tests/ldaps_basic.phpt
|
||||||
|
|
||||||
|
diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c
|
||||||
|
index 6661310d055..299cd6c855b 100644
|
||||||
|
--- a/ext/ldap/ldap.c
|
||||||
|
+++ b/ext/ldap/ldap.c
|
||||||
|
@@ -715,6 +715,21 @@ static PHP_GINIT_FUNCTION(ldap)
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
+/* {{{ PHP_RINIT_FUNCTION */
|
||||||
|
+static PHP_RINIT_FUNCTION(ldap)
|
||||||
|
+{
|
||||||
|
+#if defined(COMPILE_DL_LDAP) && defined(ZTS)
|
||||||
|
+ ZEND_TSRMLS_CACHE_UPDATE();
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ /* needed before first connect and after TLS option changes */
|
||||||
|
+ LDAPG(tls_newctx) = true;
|
||||||
|
+
|
||||||
|
+ return SUCCESS;
|
||||||
|
+}
|
||||||
|
+/* }}} */
|
||||||
|
+
|
||||||
|
+
|
||||||
|
/* {{{ PHP_MINIT_FUNCTION */
|
||||||
|
PHP_MINIT_FUNCTION(ldap)
|
||||||
|
{
|
||||||
|
@@ -1037,6 +1052,20 @@ PHP_FUNCTION(ldap_connect)
|
||||||
|
snprintf( url, urllen, "ldap://%s:" ZEND_LONG_FMT, host, port );
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef LDAP_OPT_X_TLS_NEWCTX
|
||||||
|
+ if (LDAPG(tls_newctx) && url && !strncmp(url, "ldaps:", 6)) {
|
||||||
|
+ int val = 0;
|
||||||
|
+
|
||||||
|
+ /* ensure all pending TLS options are applied in a new context */
|
||||||
|
+ if (ldap_set_option(NULL, LDAP_OPT_X_TLS_NEWCTX, &val) != LDAP_OPT_SUCCESS) {
|
||||||
|
+ zval_ptr_dtor(return_value);
|
||||||
|
+ php_error_docref(NULL, E_WARNING, "Could not create new security context");
|
||||||
|
+ RETURN_FALSE;
|
||||||
|
+ }
|
||||||
|
+ LDAPG(tls_newctx) = false;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#ifdef LDAP_API_FEATURE_X_OPENLDAP
|
||||||
|
/* ldap_init() is deprecated, use ldap_initialize() instead.
|
||||||
|
*/
|
||||||
|
@@ -3135,15 +3164,7 @@ PHP_FUNCTION(ldap_set_option)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (option) {
|
||||||
|
- /* options with int value */
|
||||||
|
- case LDAP_OPT_DEREF:
|
||||||
|
- case LDAP_OPT_SIZELIMIT:
|
||||||
|
- case LDAP_OPT_TIMELIMIT:
|
||||||
|
- case LDAP_OPT_PROTOCOL_VERSION:
|
||||||
|
- case LDAP_OPT_ERROR_NUMBER:
|
||||||
|
-#ifdef LDAP_OPT_DEBUG_LEVEL
|
||||||
|
- case LDAP_OPT_DEBUG_LEVEL:
|
||||||
|
-#endif
|
||||||
|
+ /* TLS options with int value */
|
||||||
|
#ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
|
||||||
|
case LDAP_OPT_X_TLS_REQUIRE_CERT:
|
||||||
|
#endif
|
||||||
|
@@ -3152,6 +3173,18 @@ PHP_FUNCTION(ldap_set_option)
|
||||||
|
#endif
|
||||||
|
#ifdef LDAP_OPT_X_TLS_PROTOCOL_MIN
|
||||||
|
case LDAP_OPT_X_TLS_PROTOCOL_MIN:
|
||||||
|
+#endif
|
||||||
|
+ /* TLS option change requires resetting TLS context */
|
||||||
|
+ LDAPG(tls_newctx) = true;
|
||||||
|
+ ZEND_FALLTHROUGH;
|
||||||
|
+ /* other options with int value */
|
||||||
|
+ case LDAP_OPT_DEREF:
|
||||||
|
+ case LDAP_OPT_SIZELIMIT:
|
||||||
|
+ case LDAP_OPT_TIMELIMIT:
|
||||||
|
+ case LDAP_OPT_PROTOCOL_VERSION:
|
||||||
|
+ case LDAP_OPT_ERROR_NUMBER:
|
||||||
|
+#ifdef LDAP_OPT_DEBUG_LEVEL
|
||||||
|
+ case LDAP_OPT_DEBUG_LEVEL:
|
||||||
|
#endif
|
||||||
|
#ifdef LDAP_OPT_X_KEEPALIVE_IDLE
|
||||||
|
case LDAP_OPT_X_KEEPALIVE_IDLE:
|
||||||
|
@@ -3208,17 +3241,7 @@ PHP_FUNCTION(ldap_set_option)
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
#endif
|
||||||
|
- /* options with string value */
|
||||||
|
- case LDAP_OPT_ERROR_STRING:
|
||||||
|
-#ifdef LDAP_OPT_HOST_NAME
|
||||||
|
- case LDAP_OPT_HOST_NAME:
|
||||||
|
-#endif
|
||||||
|
-#ifdef HAVE_LDAP_SASL
|
||||||
|
- case LDAP_OPT_X_SASL_MECH:
|
||||||
|
- case LDAP_OPT_X_SASL_REALM:
|
||||||
|
- case LDAP_OPT_X_SASL_AUTHCID:
|
||||||
|
- case LDAP_OPT_X_SASL_AUTHZID:
|
||||||
|
-#endif
|
||||||
|
+ /* TLS options with string value */
|
||||||
|
#if (LDAP_API_VERSION > 2000)
|
||||||
|
case LDAP_OPT_X_TLS_CACERTDIR:
|
||||||
|
case LDAP_OPT_X_TLS_CACERTFILE:
|
||||||
|
@@ -3232,6 +3255,20 @@ PHP_FUNCTION(ldap_set_option)
|
||||||
|
#endif
|
||||||
|
#ifdef LDAP_OPT_X_TLS_DHFILE
|
||||||
|
case LDAP_OPT_X_TLS_DHFILE:
|
||||||
|
+#endif
|
||||||
|
+ /* TLS option change requires resetting TLS context */
|
||||||
|
+ LDAPG(tls_newctx) = true;
|
||||||
|
+ ZEND_FALLTHROUGH;
|
||||||
|
+ /* other options with string value */
|
||||||
|
+ case LDAP_OPT_ERROR_STRING:
|
||||||
|
+#ifdef LDAP_OPT_HOST_NAME
|
||||||
|
+ case LDAP_OPT_HOST_NAME:
|
||||||
|
+#endif
|
||||||
|
+#ifdef HAVE_LDAP_SASL
|
||||||
|
+ case LDAP_OPT_X_SASL_MECH:
|
||||||
|
+ case LDAP_OPT_X_SASL_REALM:
|
||||||
|
+ case LDAP_OPT_X_SASL_AUTHCID:
|
||||||
|
+ case LDAP_OPT_X_SASL_AUTHZID:
|
||||||
|
#endif
|
||||||
|
#ifdef LDAP_OPT_MATCHED_DN
|
||||||
|
case LDAP_OPT_MATCHED_DN:
|
||||||
|
@@ -3658,6 +3695,9 @@ PHP_FUNCTION(ldap_start_tls)
|
||||||
|
zval *link;
|
||||||
|
ldap_linkdata *ld;
|
||||||
|
int rc, protocol = LDAP_VERSION3;
|
||||||
|
+#ifdef LDAP_OPT_X_TLS_NEWCTX
|
||||||
|
+ int val = 0;
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &link) != SUCCESS) {
|
||||||
|
RETURN_THROWS();
|
||||||
|
@@ -3668,13 +3708,16 @@ PHP_FUNCTION(ldap_start_tls)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((rc = ldap_set_option(ld->link, LDAP_OPT_PROTOCOL_VERSION, &protocol)) != LDAP_SUCCESS) ||
|
||||||
|
+#ifdef LDAP_OPT_X_TLS_NEWCTX
|
||||||
|
+ (LDAPG(tls_newctx) && (rc = ldap_set_option(ld->link, LDAP_OPT_X_TLS_NEWCTX, &val)) != LDAP_OPT_SUCCESS) ||
|
||||||
|
+#endif
|
||||||
|
((rc = ldap_start_tls_s(ld->link, NULL, NULL)) != LDAP_SUCCESS)
|
||||||
|
) {
|
||||||
|
php_error_docref(NULL, E_WARNING,"Unable to start TLS: %s", ldap_err2string(rc));
|
||||||
|
RETURN_FALSE;
|
||||||
|
- } else {
|
||||||
|
- RETURN_TRUE;
|
||||||
|
}
|
||||||
|
+ LDAPG(tls_newctx) = false;
|
||||||
|
+ RETURN_TRUE;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
#endif
|
||||||
|
@@ -4178,7 +4221,7 @@ zend_module_entry ldap_module_entry = { /* {{{ */
|
||||||
|
ext_functions,
|
||||||
|
PHP_MINIT(ldap),
|
||||||
|
PHP_MSHUTDOWN(ldap),
|
||||||
|
- NULL,
|
||||||
|
+ PHP_RINIT(ldap),
|
||||||
|
NULL,
|
||||||
|
PHP_MINFO(ldap),
|
||||||
|
PHP_LDAP_VERSION,
|
||||||
|
diff --git a/ext/ldap/php_ldap.h b/ext/ldap/php_ldap.h
|
||||||
|
index fcda55e92fb..36941d952bf 100644
|
||||||
|
--- a/ext/ldap/php_ldap.h
|
||||||
|
+++ b/ext/ldap/php_ldap.h
|
||||||
|
@@ -39,6 +39,7 @@ PHP_MINFO_FUNCTION(ldap);
|
||||||
|
ZEND_BEGIN_MODULE_GLOBALS(ldap)
|
||||||
|
zend_long num_links;
|
||||||
|
zend_long max_links;
|
||||||
|
+ bool tls_newctx; /* create new TLS context before connect */
|
||||||
|
ZEND_END_MODULE_GLOBALS(ldap)
|
||||||
|
|
||||||
|
#if defined(ZTS) && defined(COMPILE_DL_LDAP)
|
||||||
|
diff --git a/ext/ldap/tests/ldap_start_tls_basic.phpt b/ext/ldap/tests/ldap_start_tls_basic.phpt
|
||||||
|
index a9e3c6c97ce..94d9e8e9552 100644
|
||||||
|
--- a/ext/ldap/tests/ldap_start_tls_basic.phpt
|
||||||
|
+++ b/ext/ldap/tests/ldap_start_tls_basic.phpt
|
||||||
|
@@ -8,11 +8,28 @@ Patrick Allaert <patrickallaert@php.net>
|
||||||
|
<?php require_once __DIR__ .'/skipifbindfailure.inc'; ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
-require "connect.inc";
|
||||||
|
+require_once "connect.inc";
|
||||||
|
|
||||||
|
+// CI uses self signed certificate
|
||||||
|
+
|
||||||
|
+// No cert option - fails
|
||||||
|
+$link = ldap_connect($host, $port);
|
||||||
|
+ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
|
||||||
|
+var_dump(@ldap_start_tls($link));
|
||||||
|
+
|
||||||
|
+// No cert check - passes
|
||||||
|
+$link = ldap_connect($host, $port);
|
||||||
|
+ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
|
||||||
|
+ldap_set_option($link, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_NEVER);
|
||||||
|
+var_dump(@ldap_start_tls($link));
|
||||||
|
+
|
||||||
|
+// With cert check - fails
|
||||||
|
$link = ldap_connect($host, $port);
|
||||||
|
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
|
||||||
|
-var_dump(ldap_start_tls($link));
|
||||||
|
+ldap_set_option($link, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_DEMAND);
|
||||||
|
+var_dump(@ldap_start_tls($link));
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
+bool(false)
|
||||||
|
bool(true)
|
||||||
|
+bool(false)
|
||||||
|
diff --git a/ext/ldap/tests/ldaps_basic.phpt b/ext/ldap/tests/ldaps_basic.phpt
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..7a1a1383436
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/ext/ldap/tests/ldaps_basic.phpt
|
||||||
|
@@ -0,0 +1,55 @@
|
||||||
|
+--TEST--
|
||||||
|
+ldap_connect() - Basic ldaps test
|
||||||
|
+--EXTENSIONS--
|
||||||
|
+ldap
|
||||||
|
+--XFAIL--
|
||||||
|
+Passes locally but fails on CI - need investigation (configuration ?)
|
||||||
|
+--SKIPIF--
|
||||||
|
+<?php require_once __DIR__ .'/skipifbindfailure.inc'; ?>
|
||||||
|
+--FILE--
|
||||||
|
+<?php
|
||||||
|
+require_once "connect.inc";
|
||||||
|
+
|
||||||
|
+$uri = "ldaps://$host:636";
|
||||||
|
+
|
||||||
|
+// CI uses self signed certificate
|
||||||
|
+
|
||||||
|
+// No cert option - fails
|
||||||
|
+$link = ldap_connect($uri);
|
||||||
|
+ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
|
||||||
|
+var_dump(@ldap_bind($link, $user, $passwd));
|
||||||
|
+ldap_unbind($link);
|
||||||
|
+
|
||||||
|
+// No cert check - passes
|
||||||
|
+ldap_set_option(null, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_ALLOW);
|
||||||
|
+$link = ldap_connect($uri);
|
||||||
|
+ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
|
||||||
|
+var_dump(@ldap_bind($link, $user, $passwd));
|
||||||
|
+ldap_unbind($link);
|
||||||
|
+
|
||||||
|
+// No change to TLS options
|
||||||
|
+$link = ldap_connect($uri);
|
||||||
|
+ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
|
||||||
|
+var_dump(@ldap_bind($link, $user, $passwd));
|
||||||
|
+ldap_unbind($link);
|
||||||
|
+
|
||||||
|
+// With cert check - fails
|
||||||
|
+ldap_set_option(null, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_DEMAND);
|
||||||
|
+$link = ldap_connect($uri);
|
||||||
|
+ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
|
||||||
|
+var_dump(@ldap_bind($link, $user, $passwd));
|
||||||
|
+ldap_unbind($link);
|
||||||
|
+
|
||||||
|
+// No change to TLS options
|
||||||
|
+$link = ldap_connect($uri);
|
||||||
|
+ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
|
||||||
|
+var_dump(@ldap_bind($link, $user, $passwd));
|
||||||
|
+ldap_unbind($link);
|
||||||
|
+
|
||||||
|
+?>
|
||||||
|
+--EXPECT--
|
||||||
|
+bool(false)
|
||||||
|
+bool(true)
|
||||||
|
+bool(true)
|
||||||
|
+bool(false)
|
||||||
|
+bool(false)
|
||||||
|
--
|
||||||
|
2.43.7
|
||||||
|
|
||||||
|
From 398430a2ee29c30aad76fea54358e3d7c53c3357 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Remi Collet <remi@remirepo.net>
|
||||||
|
Date: Tue, 13 May 2025 16:00:32 +0200
|
||||||
|
Subject: [PATCH 2/4] Fix GH-18529: ldap no longer respects TLS_CACERT from
|
||||||
|
ldaprc in ldap_start_tls() Regresion introduced in fix for GH-17776
|
||||||
|
|
||||||
|
- ensure TLS string options are properly inherited
|
||||||
|
workaround to openldap issue https://bugs.openldap.org/show_bug.cgi?id=10337
|
||||||
|
|
||||||
|
- fix ldaps/start_tls tests using LDAPNOINIT in ldaps/tls tests
|
||||||
|
|
||||||
|
(cherry picked from commit 2760a3ef9719dac2e53baf3dc2d8a3dd1227d88b)
|
||||||
|
---
|
||||||
|
ext/ldap/ldap.c | 49 ++++++++++++++++++++++--
|
||||||
|
ext/ldap/tests/ldap_start_tls_basic.phpt | 2 +
|
||||||
|
ext/ldap/tests/ldaps_basic.phpt | 4 +-
|
||||||
|
3 files changed, 49 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c
|
||||||
|
index 299cd6c855b..6d576b84bd4 100644
|
||||||
|
--- a/ext/ldap/ldap.c
|
||||||
|
+++ b/ext/ldap/ldap.c
|
||||||
|
@@ -3689,15 +3689,56 @@ PHP_FUNCTION(ldap_rename_ext)
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
#ifdef HAVE_LDAP_START_TLS_S
|
||||||
|
+/*
|
||||||
|
+ Force new tls context creation with string options inherited from global
|
||||||
|
+ Workaround to https://bugs.openldap.org/show_bug.cgi?id=10337
|
||||||
|
+ */
|
||||||
|
+static int _php_ldap_tls_newctx(LDAP *ld)
|
||||||
|
+{
|
||||||
|
+ int val = 0, i, opts[] = {
|
||||||
|
+#if (LDAP_API_VERSION > 2000)
|
||||||
|
+ LDAP_OPT_X_TLS_CACERTDIR,
|
||||||
|
+ LDAP_OPT_X_TLS_CACERTFILE,
|
||||||
|
+ LDAP_OPT_X_TLS_CERTFILE,
|
||||||
|
+ LDAP_OPT_X_TLS_CIPHER_SUITE,
|
||||||
|
+ LDAP_OPT_X_TLS_KEYFILE,
|
||||||
|
+ LDAP_OPT_X_TLS_RANDOM_FILE,
|
||||||
|
+#endif
|
||||||
|
+#ifdef LDAP_OPT_X_TLS_CRLFILE
|
||||||
|
+ LDAP_OPT_X_TLS_CRLFILE,
|
||||||
|
+#endif
|
||||||
|
+#ifdef LDAP_OPT_X_TLS_DHFILE
|
||||||
|
+ LDAP_OPT_X_TLS_DHFILE,
|
||||||
|
+#endif
|
||||||
|
+#ifdef LDAP_OPT_X_TLS_ECNAME
|
||||||
|
+ LDAP_OPT_X_TLS_ECNAME,
|
||||||
|
+#endif
|
||||||
|
+ 0};
|
||||||
|
+
|
||||||
|
+ for (i=0 ; opts[i] ; i++) {
|
||||||
|
+ char *path = NULL;
|
||||||
|
+
|
||||||
|
+ ldap_get_option(ld, opts[i], &path);
|
||||||
|
+ if (path) { /* already set locally */
|
||||||
|
+ ldap_memfree(path);
|
||||||
|
+ } else {
|
||||||
|
+ ldap_get_option(NULL, opts[i], &path);
|
||||||
|
+ if (path) { /* set globally, inherit */
|
||||||
|
+ ldap_set_option(ld, opts[i], path);
|
||||||
|
+ ldap_memfree(path);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return ldap_set_option(ld, LDAP_OPT_X_TLS_NEWCTX, &val);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* {{{ Start TLS */
|
||||||
|
PHP_FUNCTION(ldap_start_tls)
|
||||||
|
{
|
||||||
|
zval *link;
|
||||||
|
ldap_linkdata *ld;
|
||||||
|
int rc, protocol = LDAP_VERSION3;
|
||||||
|
-#ifdef LDAP_OPT_X_TLS_NEWCTX
|
||||||
|
- int val = 0;
|
||||||
|
-#endif
|
||||||
|
|
||||||
|
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &link) != SUCCESS) {
|
||||||
|
RETURN_THROWS();
|
||||||
|
@@ -3709,7 +3750,7 @@ PHP_FUNCTION(ldap_start_tls)
|
||||||
|
|
||||||
|
if (((rc = ldap_set_option(ld->link, LDAP_OPT_PROTOCOL_VERSION, &protocol)) != LDAP_SUCCESS) ||
|
||||||
|
#ifdef LDAP_OPT_X_TLS_NEWCTX
|
||||||
|
- (LDAPG(tls_newctx) && (rc = ldap_set_option(ld->link, LDAP_OPT_X_TLS_NEWCTX, &val)) != LDAP_OPT_SUCCESS) ||
|
||||||
|
+ (LDAPG(tls_newctx) && (rc = _php_ldap_tls_newctx(ld->link)) != LDAP_OPT_SUCCESS) ||
|
||||||
|
#endif
|
||||||
|
((rc = ldap_start_tls_s(ld->link, NULL, NULL)) != LDAP_SUCCESS)
|
||||||
|
) {
|
||||||
|
diff --git a/ext/ldap/tests/ldap_start_tls_basic.phpt b/ext/ldap/tests/ldap_start_tls_basic.phpt
|
||||||
|
index 94d9e8e9552..14720b57286 100644
|
||||||
|
--- a/ext/ldap/tests/ldap_start_tls_basic.phpt
|
||||||
|
+++ b/ext/ldap/tests/ldap_start_tls_basic.phpt
|
||||||
|
@@ -3,6 +3,8 @@ ldap_start_tls() - Basic ldap_start_tls test
|
||||||
|
--CREDITS--
|
||||||
|
Patrick Allaert <patrickallaert@php.net>
|
||||||
|
# Belgian PHP Testfest 2009
|
||||||
|
+--ENV--
|
||||||
|
+LDAPNOINIT=1
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require_once __DIR__ .'/skipif.inc'; ?>
|
||||||
|
<?php require_once __DIR__ .'/skipifbindfailure.inc'; ?>
|
||||||
|
diff --git a/ext/ldap/tests/ldaps_basic.phpt b/ext/ldap/tests/ldaps_basic.phpt
|
||||||
|
index 7a1a1383436..9fa49a6ce79 100644
|
||||||
|
--- a/ext/ldap/tests/ldaps_basic.phpt
|
||||||
|
+++ b/ext/ldap/tests/ldaps_basic.phpt
|
||||||
|
@@ -2,8 +2,8 @@
|
||||||
|
ldap_connect() - Basic ldaps test
|
||||||
|
--EXTENSIONS--
|
||||||
|
ldap
|
||||||
|
---XFAIL--
|
||||||
|
-Passes locally but fails on CI - need investigation (configuration ?)
|
||||||
|
+--ENV--
|
||||||
|
+LDAPNOINIT=1
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require_once __DIR__ .'/skipifbindfailure.inc'; ?>
|
||||||
|
--FILE--
|
||||||
|
--
|
||||||
|
2.43.7
|
||||||
|
|
||||||
|
From d79c713b18d67495dad3d8199ec093dd93404eac Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jakub Zelenka <bukka@php.net>
|
||||||
|
Date: Tue, 27 May 2025 19:03:56 +0200
|
||||||
|
Subject: [PATCH 3/4] Fix GH-18529: additional inheriting of TLS int options
|
||||||
|
|
||||||
|
This is for LDAP_OPT_X_TLS_PROTOCOL_MIN and LDAP_OPT_X_TLS_PROTOCOL_MAX
|
||||||
|
|
||||||
|
It also adds a test that uses LDAPCONF with TLS max version lower than
|
||||||
|
the minimum TLS server version so it should always fail. However it
|
||||||
|
does not fial for the second case without this change which confirms
|
||||||
|
that the change works as expected.
|
||||||
|
|
||||||
|
Closes GH-18676
|
||||||
|
|
||||||
|
(cherry picked from commit eade5c17ead650b0735295214bbec84872465e87)
|
||||||
|
---
|
||||||
|
.github/scripts/setup-slapd.sh | 3 ++
|
||||||
|
ext/ldap/ldap.c | 32 ++++++++++++---
|
||||||
|
.../tests/ldap_start_tls_rc_max_version.conf | 1 +
|
||||||
|
.../tests/ldap_start_tls_rc_max_version.phpt | 41 +++++++++++++++++++
|
||||||
|
ext/ldap/tests/skipifbindfailure.inc | 33 +++++++++++++++
|
||||||
|
5 files changed, 105 insertions(+), 5 deletions(-)
|
||||||
|
create mode 100644 ext/ldap/tests/ldap_start_tls_rc_max_version.conf
|
||||||
|
create mode 100644 ext/ldap/tests/ldap_start_tls_rc_max_version.phpt
|
||||||
|
|
||||||
|
diff --git a/.github/scripts/setup-slapd.sh b/.github/scripts/setup-slapd.sh
|
||||||
|
index b9cb1a4ff7a..f2eb1269d1f 100755
|
||||||
|
--- a/.github/scripts/setup-slapd.sh
|
||||||
|
+++ b/.github/scripts/setup-slapd.sh
|
||||||
|
@@ -72,6 +72,9 @@ olcTLSCertificateKeyFile: /etc/ldap/ssl/server.key
|
||||||
|
add: olcTLSVerifyClient
|
||||||
|
olcTLSVerifyClient: never
|
||||||
|
-
|
||||||
|
+add: olcTLSProtocolMin
|
||||||
|
+olcTLSProtocolMin: 3.3
|
||||||
|
+-
|
||||||
|
add: olcAuthzRegexp
|
||||||
|
olcAuthzRegexp: uid=usera,cn=digest-md5,cn=auth cn=usera,dc=my-domain,dc=com
|
||||||
|
-
|
||||||
|
diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c
|
||||||
|
index 6d576b84bd4..8da103fd632 100644
|
||||||
|
--- a/ext/ldap/ldap.c
|
||||||
|
+++ b/ext/ldap/ldap.c
|
||||||
|
@@ -3695,7 +3695,8 @@ PHP_FUNCTION(ldap_rename_ext)
|
||||||
|
*/
|
||||||
|
static int _php_ldap_tls_newctx(LDAP *ld)
|
||||||
|
{
|
||||||
|
- int val = 0, i, opts[] = {
|
||||||
|
+ int val = 0, i;
|
||||||
|
+ int str_opts[] = {
|
||||||
|
#if (LDAP_API_VERSION > 2000)
|
||||||
|
LDAP_OPT_X_TLS_CACERTDIR,
|
||||||
|
LDAP_OPT_X_TLS_CACERTFILE,
|
||||||
|
@@ -3715,21 +3716,42 @@ static int _php_ldap_tls_newctx(LDAP *ld)
|
||||||
|
#endif
|
||||||
|
0};
|
||||||
|
|
||||||
|
- for (i=0 ; opts[i] ; i++) {
|
||||||
|
+ for (i=0 ; str_opts[i] ; i++) {
|
||||||
|
char *path = NULL;
|
||||||
|
|
||||||
|
- ldap_get_option(ld, opts[i], &path);
|
||||||
|
+ ldap_get_option(ld, str_opts[i], &path);
|
||||||
|
if (path) { /* already set locally */
|
||||||
|
ldap_memfree(path);
|
||||||
|
} else {
|
||||||
|
- ldap_get_option(NULL, opts[i], &path);
|
||||||
|
+ ldap_get_option(NULL, str_opts[i], &path);
|
||||||
|
if (path) { /* set globally, inherit */
|
||||||
|
- ldap_set_option(ld, opts[i], path);
|
||||||
|
+ ldap_set_option(ld, str_opts[i], path);
|
||||||
|
ldap_memfree(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+#ifdef LDAP_OPT_X_TLS_PROTOCOL_MIN
|
||||||
|
+ int int_opts[] = {
|
||||||
|
+ LDAP_OPT_X_TLS_PROTOCOL_MIN,
|
||||||
|
+#ifdef LDAP_OPT_X_TLS_PROTOCOL_MAX
|
||||||
|
+ LDAP_OPT_X_TLS_PROTOCOL_MAX,
|
||||||
|
+#endif
|
||||||
|
+ 0
|
||||||
|
+ };
|
||||||
|
+ for (i=0 ; int_opts[i] ; i++) {
|
||||||
|
+ int value = 0;
|
||||||
|
+
|
||||||
|
+ ldap_get_option(ld, int_opts[i], &value);
|
||||||
|
+ if (value <= 0) { /* if value is not set already */
|
||||||
|
+ ldap_get_option(NULL, int_opts[i], &value);
|
||||||
|
+ if (value > 0) { /* set globally, inherit */
|
||||||
|
+ ldap_set_option(ld, int_opts[i], &value);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
return ldap_set_option(ld, LDAP_OPT_X_TLS_NEWCTX, &val);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/ext/ldap/tests/ldap_start_tls_rc_max_version.conf b/ext/ldap/tests/ldap_start_tls_rc_max_version.conf
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..0cd03f8b8e1
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/ext/ldap/tests/ldap_start_tls_rc_max_version.conf
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+TLS_PROTOCOL_MAX 3.2
|
||||||
|
\ No newline at end of file
|
||||||
|
diff --git a/ext/ldap/tests/ldap_start_tls_rc_max_version.phpt b/ext/ldap/tests/ldap_start_tls_rc_max_version.phpt
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..359785f8b5a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/ext/ldap/tests/ldap_start_tls_rc_max_version.phpt
|
||||||
|
@@ -0,0 +1,41 @@
|
||||||
|
+--TEST--
|
||||||
|
+ldap_start_tls() - Basic ldap_start_tls test
|
||||||
|
+--EXTENSIONS--
|
||||||
|
+ldap
|
||||||
|
+--ENV--
|
||||||
|
+LDAPCONF={PWD}/ldap_start_tls_rc_max_version.conf
|
||||||
|
+--SKIPIF--
|
||||||
|
+<?php
|
||||||
|
+$require_vendor = [
|
||||||
|
+ "name" => "OpenLDAP",
|
||||||
|
+ "min_version" => 20600,
|
||||||
|
+];
|
||||||
|
+require_once __DIR__ .'/skipifbindfailure.inc';
|
||||||
|
+?>
|
||||||
|
+--FILE--
|
||||||
|
+<?php
|
||||||
|
+require_once "connect.inc";
|
||||||
|
+
|
||||||
|
+// CI uses self signed certificate
|
||||||
|
+
|
||||||
|
+// No cert option - fails
|
||||||
|
+$link = ldap_connect($uri);
|
||||||
|
+ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
|
||||||
|
+var_dump(@ldap_start_tls($link));
|
||||||
|
+
|
||||||
|
+// No cert check - should pass but due to ldaps check, it fails as well
|
||||||
|
+$link = ldap_connect($uri);
|
||||||
|
+ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
|
||||||
|
+ldap_set_option($link, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_NEVER);
|
||||||
|
+var_dump(@ldap_start_tls($link));
|
||||||
|
+
|
||||||
|
+// With cert check - fails
|
||||||
|
+$link = ldap_connect($uri);
|
||||||
|
+ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
|
||||||
|
+ldap_set_option($link, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_DEMAND);
|
||||||
|
+var_dump(@ldap_start_tls($link));
|
||||||
|
+?>
|
||||||
|
+--EXPECT--
|
||||||
|
+bool(false)
|
||||||
|
+bool(false)
|
||||||
|
+bool(false)
|
||||||
|
diff --git a/ext/ldap/tests/skipifbindfailure.inc b/ext/ldap/tests/skipifbindfailure.inc
|
||||||
|
index 8f66c6cb968..ce24cd78f1e 100644
|
||||||
|
--- a/ext/ldap/tests/skipifbindfailure.inc
|
||||||
|
+++ b/ext/ldap/tests/skipifbindfailure.inc
|
||||||
|
@@ -10,4 +10,37 @@ if ($skip_on_bind_failure) {
|
||||||
|
|
||||||
|
ldap_unbind($link);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+if (isset($require_vendor)) {
|
||||||
|
+ ob_start();
|
||||||
|
+ phpinfo(INFO_MODULES);
|
||||||
|
+ $phpinfo = ob_get_clean();
|
||||||
|
+
|
||||||
|
+ // Extract the LDAP section specifically
|
||||||
|
+ if (preg_match('/^ldap\s*$(.*?)^[a-z_]+\s*$/ims', $phpinfo, $ldap_section_match)) {
|
||||||
|
+ $ldap_section = $ldap_section_match[1];
|
||||||
|
+
|
||||||
|
+ // Extract vendor info from the LDAP section only
|
||||||
|
+ if (preg_match('/Vendor Name\s*=>\s*(.+)/i', $ldap_section, $name_match) &&
|
||||||
|
+ preg_match('/Vendor Version\s*=>\s*(\d+)/i', $ldap_section, $version_match)) {
|
||||||
|
+
|
||||||
|
+ $vendor_name = trim($name_match[1]);
|
||||||
|
+ $vendor_version = (int)$version_match[1];
|
||||||
|
+
|
||||||
|
+ // Check vendor name if specified
|
||||||
|
+ if (isset($require_vendor['name']) && $vendor_name !== $require_vendor['name']) {
|
||||||
|
+ die("skip Requires {$require_vendor['name']} (detected: $vendor_name)");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Check minimum version if specified
|
||||||
|
+ if (isset($require_vendor['min_version']) && $vendor_version < $require_vendor['min_version']) {
|
||||||
|
+ die("skip Requires minimum version {$require_vendor['min_version']} (detected: $vendor_version)");
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ die("skip Cannot determine LDAP vendor information");
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ die("skip LDAP extension information not found");
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
?>
|
||||||
|
--
|
||||||
|
2.43.7
|
||||||
|
|
||||||
|
From bb559b2ecaa9359c79e336e6ff20bbe61bec9f6c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Remi Collet <remi@remirepo.net>
|
||||||
|
Date: Fri, 3 Oct 2025 08:31:29 +0200
|
||||||
|
Subject: [PATCH 4/4] adapt for 8.0
|
||||||
|
|
||||||
|
---
|
||||||
|
ext/ldap/ldap.c | 2 --
|
||||||
|
ext/ldap/tests/ldap_start_tls_rc_max_version.phpt | 2 ++
|
||||||
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c
|
||||||
|
index 8da103fd632..9a4589565cb 100644
|
||||||
|
--- a/ext/ldap/ldap.c
|
||||||
|
+++ b/ext/ldap/ldap.c
|
||||||
|
@@ -3176,7 +3176,6 @@ PHP_FUNCTION(ldap_set_option)
|
||||||
|
#endif
|
||||||
|
/* TLS option change requires resetting TLS context */
|
||||||
|
LDAPG(tls_newctx) = true;
|
||||||
|
- ZEND_FALLTHROUGH;
|
||||||
|
/* other options with int value */
|
||||||
|
case LDAP_OPT_DEREF:
|
||||||
|
case LDAP_OPT_SIZELIMIT:
|
||||||
|
@@ -3258,7 +3257,6 @@ PHP_FUNCTION(ldap_set_option)
|
||||||
|
#endif
|
||||||
|
/* TLS option change requires resetting TLS context */
|
||||||
|
LDAPG(tls_newctx) = true;
|
||||||
|
- ZEND_FALLTHROUGH;
|
||||||
|
/* other options with string value */
|
||||||
|
case LDAP_OPT_ERROR_STRING:
|
||||||
|
#ifdef LDAP_OPT_HOST_NAME
|
||||||
|
diff --git a/ext/ldap/tests/ldap_start_tls_rc_max_version.phpt b/ext/ldap/tests/ldap_start_tls_rc_max_version.phpt
|
||||||
|
index 359785f8b5a..fcdf276af9c 100644
|
||||||
|
--- a/ext/ldap/tests/ldap_start_tls_rc_max_version.phpt
|
||||||
|
+++ b/ext/ldap/tests/ldap_start_tls_rc_max_version.phpt
|
||||||
|
@@ -16,6 +16,8 @@ require_once __DIR__ .'/skipifbindfailure.inc';
|
||||||
|
<?php
|
||||||
|
require_once "connect.inc";
|
||||||
|
|
||||||
|
+$uri = 'ldap://localhost:389';
|
||||||
|
+
|
||||||
|
// CI uses self signed certificate
|
||||||
|
|
||||||
|
// No cert option - fails
|
||||||
|
--
|
||||||
|
2.43.7
|
||||||
|
|
98
php-8.0.30-soap.patch
Normal file
98
php-8.0.30-soap.patch
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
From 60e7e11e8b93662b3eb62d0405e3f4a8a4928ef9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Remi Collet <remi@remirepo.net>
|
||||||
|
Date: Thu, 20 Mar 2025 09:26:26 +0100
|
||||||
|
Subject: [PATCH] Fix #66049 Typemap can break parsing in parse_packet_soap
|
||||||
|
leading to a segfault
|
||||||
|
|
||||||
|
(cherry picked from commit 209f4c296ec6a08c721afdf17d787db4b5fd37d0)
|
||||||
|
---
|
||||||
|
ext/soap/php_packet_soap.c | 3 ++
|
||||||
|
ext/soap/tests/bugs/bug66049.phpt | 48 +++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 51 insertions(+)
|
||||||
|
create mode 100644 ext/soap/tests/bugs/bug66049.phpt
|
||||||
|
|
||||||
|
diff --git a/ext/soap/php_packet_soap.c b/ext/soap/php_packet_soap.c
|
||||||
|
index 0e3a5197373..ab3dbf6b1e4 100644
|
||||||
|
--- a/ext/soap/php_packet_soap.c
|
||||||
|
+++ b/ext/soap/php_packet_soap.c
|
||||||
|
@@ -192,6 +192,7 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction
|
||||||
|
if (tmp != NULL && tmp->children != NULL) {
|
||||||
|
zval zv;
|
||||||
|
master_to_zval(&zv, get_conversion(IS_STRING), tmp);
|
||||||
|
+ convert_to_string(&zv)
|
||||||
|
faultstring = Z_STR(zv);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -199,6 +200,7 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction
|
||||||
|
if (tmp != NULL && tmp->children != NULL) {
|
||||||
|
zval zv;
|
||||||
|
master_to_zval(&zv, get_conversion(IS_STRING), tmp);
|
||||||
|
+ convert_to_string(&zv)
|
||||||
|
faultactor = Z_STR(zv);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -222,6 +224,7 @@ int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunction
|
||||||
|
if (tmp != NULL && tmp->children != NULL) {
|
||||||
|
zval zv;
|
||||||
|
master_to_zval(&zv, get_conversion(IS_STRING), tmp);
|
||||||
|
+ convert_to_string(&zv)
|
||||||
|
faultstring = Z_STR(zv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/ext/soap/tests/bugs/bug66049.phpt b/ext/soap/tests/bugs/bug66049.phpt
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..e48845a8a14
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/ext/soap/tests/bugs/bug66049.phpt
|
||||||
|
@@ -0,0 +1,48 @@
|
||||||
|
+--TEST--
|
||||||
|
+Fix #66049 Typemap can break parsing in parse_packet_soap leading to a segfault
|
||||||
|
+--EXTENSIONS--
|
||||||
|
+soap
|
||||||
|
+--INI--
|
||||||
|
+soap.wsdl_cache_enabled=0
|
||||||
|
+--FILE--
|
||||||
|
+<?php
|
||||||
|
+function soap_string_from_xml($str)
|
||||||
|
+ {
|
||||||
|
+ echo "soap_string_from_xml\n";
|
||||||
|
+
|
||||||
|
+ // Should return an string
|
||||||
|
+ return 2.3;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+class TestSoapClient extends SoapClient {
|
||||||
|
+ function __doRequest($request, $location, $action, $version, $one_way = 0): ?string {
|
||||||
|
+ $res='<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
+ <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
|
||||||
|
+ <SOAP-ENV:Body>
|
||||||
|
+ <SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>not present</faultstring>
|
||||||
|
+ </SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>';
|
||||||
|
+ return $res;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+try {
|
||||||
|
+ $client=new TestSoapClient(null, [
|
||||||
|
+ 'uri' => 'test://',
|
||||||
|
+ 'location' => 'test://',
|
||||||
|
+ 'typemap' => [[
|
||||||
|
+ "type_ns" => "http://www.w3.org/2001/XMLSchema",
|
||||||
|
+ "type_name" => "string",
|
||||||
|
+ "from_xml" => "soap_string_from_xml"
|
||||||
|
+ ]]]);
|
||||||
|
+ $client->Mist("");
|
||||||
|
+} catch (SoapFault $e) {
|
||||||
|
+ var_dump($e->faultstring);
|
||||||
|
+ var_dump($e->faultcode);
|
||||||
|
+}
|
||||||
|
+?>
|
||||||
|
+Done
|
||||||
|
+--EXPECT--
|
||||||
|
+soap_string_from_xml
|
||||||
|
+string(3) "2.3"
|
||||||
|
+string(15) "SOAP-ENV:Server"
|
||||||
|
+Done
|
||||||
|
--
|
||||||
|
2.43.7
|
||||||
|
|
153
php-cve-2025-1220.patch
Normal file
153
php-cve-2025-1220.patch
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
From 36150278addd8686a9899559241296094bd57282 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jakub Zelenka <bukka@php.net>
|
||||||
|
Date: Thu, 10 Apr 2025 15:15:36 +0200
|
||||||
|
Subject: [PATCH 2/4] Fix GHSA-3cr5-j632-f35r: Null byte in hostnames
|
||||||
|
|
||||||
|
This fixes stream_socket_client() and fsockopen().
|
||||||
|
|
||||||
|
Specifically it adds a check to parse_ip_address_ex and it also makes
|
||||||
|
sure that the \0 is not ignored in fsockopen() hostname formatting.
|
||||||
|
|
||||||
|
(cherry picked from commit cac8f7f1cf4939f55f06b68120040f057682d89c)
|
||||||
|
---
|
||||||
|
ext/standard/fsock.c | 27 +++++++++++++++++--
|
||||||
|
.../tests/network/ghsa-3cr5-j632-f35r.phpt | 21 +++++++++++++++
|
||||||
|
.../tests/streams/ghsa-3cr5-j632-f35r.phpt | 26 ++++++++++++++++++
|
||||||
|
main/streams/xp_socket.c | 9 ++++---
|
||||||
|
4 files changed, 78 insertions(+), 5 deletions(-)
|
||||||
|
create mode 100644 ext/standard/tests/network/ghsa-3cr5-j632-f35r.phpt
|
||||||
|
create mode 100644 ext/standard/tests/streams/ghsa-3cr5-j632-f35r.phpt
|
||||||
|
|
||||||
|
diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c
|
||||||
|
index a9c3cb0bf5d..636dbb6e359 100644
|
||||||
|
--- a/ext/standard/fsock.c
|
||||||
|
+++ b/ext/standard/fsock.c
|
||||||
|
@@ -23,6 +23,28 @@
|
||||||
|
#include "php_network.h"
|
||||||
|
#include "file.h"
|
||||||
|
|
||||||
|
+static size_t php_fsockopen_format_host_port(char **message, const char *prefix, size_t prefix_len,
|
||||||
|
+ const char *host, size_t host_len, zend_long port)
|
||||||
|
+{
|
||||||
|
+ char portbuf[32];
|
||||||
|
+ int portlen = snprintf(portbuf, sizeof(portbuf), ":" ZEND_LONG_FMT, port);
|
||||||
|
+ size_t total_len = prefix_len + host_len + portlen;
|
||||||
|
+
|
||||||
|
+ char *result = emalloc(total_len + 1);
|
||||||
|
+
|
||||||
|
+ if (prefix_len > 0) {
|
||||||
|
+ memcpy(result, prefix, prefix_len);
|
||||||
|
+ }
|
||||||
|
+ memcpy(result + prefix_len, host, host_len);
|
||||||
|
+ memcpy(result + prefix_len + host_len, portbuf, portlen);
|
||||||
|
+
|
||||||
|
+ result[total_len] = '\0';
|
||||||
|
+
|
||||||
|
+ *message = result;
|
||||||
|
+
|
||||||
|
+ return total_len;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* {{{ php_fsockopen() */
|
||||||
|
|
||||||
|
static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent)
|
||||||
|
@@ -62,11 +84,12 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (persistent) {
|
||||||
|
- spprintf(&hashkey, 0, "pfsockopen__%s:" ZEND_LONG_FMT, host, port);
|
||||||
|
+ php_fsockopen_format_host_port(&hashkey, "pfsockopen__", strlen("pfsockopen__"), host,
|
||||||
|
+ host_len, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (port > 0) {
|
||||||
|
- hostname_len = spprintf(&hostname, 0, "%s:" ZEND_LONG_FMT, host, port);
|
||||||
|
+ hostname_len = php_fsockopen_format_host_port(&hostname, "", 0, host, host_len, port);
|
||||||
|
} else {
|
||||||
|
hostname_len = host_len;
|
||||||
|
hostname = host;
|
||||||
|
diff --git a/ext/standard/tests/network/ghsa-3cr5-j632-f35r.phpt b/ext/standard/tests/network/ghsa-3cr5-j632-f35r.phpt
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..7556c3be94c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/ext/standard/tests/network/ghsa-3cr5-j632-f35r.phpt
|
||||||
|
@@ -0,0 +1,21 @@
|
||||||
|
+--TEST--
|
||||||
|
+GHSA-3cr5-j632-f35r: Null byte termination in fsockopen()
|
||||||
|
+--FILE--
|
||||||
|
+<?php
|
||||||
|
+
|
||||||
|
+$server = stream_socket_server("tcp://localhost:0");
|
||||||
|
+
|
||||||
|
+if (preg_match('/:(\d+)$/', stream_socket_get_name($server, false), $m)) {
|
||||||
|
+ $client = fsockopen("localhost\0.example.com", intval($m[1]));
|
||||||
|
+ var_dump($client);
|
||||||
|
+ if ($client) {
|
||||||
|
+ fclose($client);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+fclose($server);
|
||||||
|
+
|
||||||
|
+?>
|
||||||
|
+--EXPECTF--
|
||||||
|
+
|
||||||
|
+Warning: fsockopen(): Unable to connect to localhost:%d (The hostname must not contain null bytes) in %s
|
||||||
|
+bool(false)
|
||||||
|
diff --git a/ext/standard/tests/streams/ghsa-3cr5-j632-f35r.phpt b/ext/standard/tests/streams/ghsa-3cr5-j632-f35r.phpt
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..52f9263c99a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/ext/standard/tests/streams/ghsa-3cr5-j632-f35r.phpt
|
||||||
|
@@ -0,0 +1,26 @@
|
||||||
|
+--TEST--
|
||||||
|
+GHSA-3cr5-j632-f35r: Null byte termination in stream_socket_client()
|
||||||
|
+--FILE--
|
||||||
|
+<?php
|
||||||
|
+
|
||||||
|
+$server = stream_socket_server("tcp://localhost:0");
|
||||||
|
+$socket_name = stream_socket_get_name($server, false);
|
||||||
|
+
|
||||||
|
+if (preg_match('/:(\d+)$/', $socket_name, $m)) {
|
||||||
|
+ $port = $m[1];
|
||||||
|
+ $client = stream_socket_client("tcp://localhost\0.example.com:$port");
|
||||||
|
+ var_dump($client);
|
||||||
|
+ if ($client) {
|
||||||
|
+ fclose($client);
|
||||||
|
+ }
|
||||||
|
+} else {
|
||||||
|
+ echo "Could not extract port from socket name: $socket_name\n";
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+fclose($server);
|
||||||
|
+
|
||||||
|
+?>
|
||||||
|
+--EXPECTF--
|
||||||
|
+
|
||||||
|
+Warning: stream_socket_client(): Unable to connect to tcp://localhost\0.example.com:%d (The hostname must not contain null bytes) in %s
|
||||||
|
+bool(false)
|
||||||
|
diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c
|
||||||
|
index 68df3366340..47f1bdd4b1d 100644
|
||||||
|
--- a/main/streams/xp_socket.c
|
||||||
|
+++ b/main/streams/xp_socket.c
|
||||||
|
@@ -580,12 +580,15 @@ static inline char *parse_ip_address_ex(const char *str, size_t str_len, int *po
|
||||||
|
char *colon;
|
||||||
|
char *host = NULL;
|
||||||
|
|
||||||
|
-#ifdef HAVE_IPV6
|
||||||
|
- char *p;
|
||||||
|
+ if (memchr(str, '\0', str_len)) {
|
||||||
|
+ *err = strpprintf(0, "The hostname must not contain null bytes");
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+#ifdef HAVE_IPV6
|
||||||
|
if (*(str) == '[' && str_len > 1) {
|
||||||
|
/* IPV6 notation to specify raw address with port (i.e. [fe80::1]:80) */
|
||||||
|
- p = memchr(str + 1, ']', str_len - 2);
|
||||||
|
+ char *p = memchr(str + 1, ']', str_len - 2);
|
||||||
|
if (!p || *(p + 1) != ':') {
|
||||||
|
if (get_err) {
|
||||||
|
*err = strpprintf(0, "Failed to parse IPv6 address \"%s\"", str);
|
||||||
|
--
|
||||||
|
2.50.0
|
||||||
|
|
490
php-cve-2025-1735.patch
Normal file
490
php-cve-2025-1735.patch
Normal file
@ -0,0 +1,490 @@
|
|||||||
|
From 7633d987cc11ee2601223e73cfdb8b31fed5980f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jakub Zelenka <bukka@php.net>
|
||||||
|
Date: Tue, 4 Mar 2025 17:23:01 +0100
|
||||||
|
Subject: [PATCH 3/4] Fix GHSA-hrwm-9436-5mv3: pgsql escaping no error checks
|
||||||
|
|
||||||
|
This adds error checks for escape function is pgsql and pdo_pgsql
|
||||||
|
extensions. It prevents possibility of storing not properly escaped
|
||||||
|
data which could potentially lead to some security issues.
|
||||||
|
|
||||||
|
(cherry picked from commit 9376aeef9f8ff81f2705b8016237ec3e30bdee44)
|
||||||
|
---
|
||||||
|
ext/pdo_pgsql/pgsql_driver.c | 10 +-
|
||||||
|
ext/pdo_pgsql/tests/ghsa-hrwm-9436-5mv3.phpt | 22 ++++
|
||||||
|
ext/pgsql/pgsql.c | 129 +++++++++++++++----
|
||||||
|
ext/pgsql/tests/ghsa-hrwm-9436-5mv3.phpt | 64 +++++++++
|
||||||
|
4 files changed, 202 insertions(+), 23 deletions(-)
|
||||||
|
create mode 100644 ext/pdo_pgsql/tests/ghsa-hrwm-9436-5mv3.phpt
|
||||||
|
create mode 100644 ext/pgsql/tests/ghsa-hrwm-9436-5mv3.phpt
|
||||||
|
|
||||||
|
diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c
|
||||||
|
index c90ef468907..218a306fa3c 100644
|
||||||
|
--- a/ext/pdo_pgsql/pgsql_driver.c
|
||||||
|
+++ b/ext/pdo_pgsql/pgsql_driver.c
|
||||||
|
@@ -354,11 +354,15 @@ static int pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unqu
|
||||||
|
unsigned char *escaped;
|
||||||
|
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
|
||||||
|
size_t tmp_len;
|
||||||
|
+ int err;
|
||||||
|
|
||||||
|
switch (paramtype) {
|
||||||
|
case PDO_PARAM_LOB:
|
||||||
|
/* escapedlen returned by PQescapeBytea() accounts for trailing 0 */
|
||||||
|
escaped = PQescapeByteaConn(H->server, (unsigned char *)unquoted, unquotedlen, &tmp_len);
|
||||||
|
+ if (escaped == NULL) {
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
*quotedlen = tmp_len + 1;
|
||||||
|
*quoted = emalloc(*quotedlen + 1);
|
||||||
|
memcpy((*quoted)+1, escaped, *quotedlen-2);
|
||||||
|
@@ -370,7 +374,11 @@ static int pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unqu
|
||||||
|
default:
|
||||||
|
*quoted = safe_emalloc(2, unquotedlen, 3);
|
||||||
|
(*quoted)[0] = '\'';
|
||||||
|
- *quotedlen = PQescapeStringConn(H->server, *quoted + 1, unquoted, unquotedlen, NULL);
|
||||||
|
+ *quotedlen = PQescapeStringConn(H->server, *quoted + 1, unquoted, unquotedlen, &err);
|
||||||
|
+ if (err) {
|
||||||
|
+ efree(*quoted);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
(*quoted)[*quotedlen + 1] = '\'';
|
||||||
|
(*quoted)[*quotedlen + 2] = '\0';
|
||||||
|
*quotedlen += 2;
|
||||||
|
diff --git a/ext/pdo_pgsql/tests/ghsa-hrwm-9436-5mv3.phpt b/ext/pdo_pgsql/tests/ghsa-hrwm-9436-5mv3.phpt
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..60e13613d04
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/ext/pdo_pgsql/tests/ghsa-hrwm-9436-5mv3.phpt
|
||||||
|
@@ -0,0 +1,22 @@
|
||||||
|
+--TEST--
|
||||||
|
+#GHSA-hrwm-9436-5mv3: pdo_pgsql extension does not check for errors during escaping
|
||||||
|
+--SKIPIF--
|
||||||
|
+<?php
|
||||||
|
+if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not loaded');
|
||||||
|
+require_once dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||||
|
+require_once dirname(__FILE__) . '/config.inc';
|
||||||
|
+PDOTest::skip();
|
||||||
|
+?>
|
||||||
|
+--FILE--
|
||||||
|
+<?php
|
||||||
|
+require_once dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
|
||||||
|
+require_once dirname(__FILE__) . '/config.inc';
|
||||||
|
+$db = PDOTest::test_factory(dirname(__FILE__) . '/common.phpt');
|
||||||
|
+$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
+
|
||||||
|
+$invalid = "ABC\xff\x30';";
|
||||||
|
+var_dump($db->quote($invalid));
|
||||||
|
+
|
||||||
|
+?>
|
||||||
|
+--EXPECT--
|
||||||
|
+bool(false)
|
||||||
|
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
|
||||||
|
index 588f481a498..e9a68a8555f 100644
|
||||||
|
--- a/ext/pgsql/pgsql.c
|
||||||
|
+++ b/ext/pgsql/pgsql.c
|
||||||
|
@@ -3298,10 +3298,16 @@ PHP_FUNCTION(pg_escape_string)
|
||||||
|
|
||||||
|
to = zend_string_safe_alloc(ZSTR_LEN(from), 2, 0, 0);
|
||||||
|
if (link) {
|
||||||
|
+ int err;
|
||||||
|
if ((pgsql = (PGconn *)zend_fetch_resource2(link, "PostgreSQL link", le_link, le_plink)) == NULL) {
|
||||||
|
RETURN_THROWS();
|
||||||
|
}
|
||||||
|
- ZSTR_LEN(to) = PQescapeStringConn(pgsql, ZSTR_VAL(to), ZSTR_VAL(from), ZSTR_LEN(from), NULL);
|
||||||
|
+ ZSTR_LEN(to) = PQescapeStringConn(pgsql, ZSTR_VAL(to), ZSTR_VAL(from), ZSTR_LEN(from), &err);
|
||||||
|
+ if (err) {
|
||||||
|
+ zend_argument_value_error(ZEND_NUM_ARGS(), "Escaping string failed");
|
||||||
|
+ zend_string_efree(to);
|
||||||
|
+ RETURN_THROWS();
|
||||||
|
+ }
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
ZSTR_LEN(to) = PQescapeString(ZSTR_VAL(to), ZSTR_VAL(from), ZSTR_LEN(from));
|
||||||
|
@@ -3344,6 +3350,10 @@ PHP_FUNCTION(pg_escape_bytea)
|
||||||
|
to = (char *)PQescapeByteaConn(pgsql, (unsigned char *)from, (size_t)from_len, &to_len);
|
||||||
|
} else
|
||||||
|
to = (char *)PQescapeBytea((unsigned char*)from, from_len, &to_len);
|
||||||
|
+ if (to == NULL) {
|
||||||
|
+ zend_argument_value_error(ZEND_NUM_ARGS(), "Escape failure");
|
||||||
|
+ RETURN_THROWS();
|
||||||
|
+ }
|
||||||
|
|
||||||
|
RETVAL_STRINGL(to, to_len-1); /* to_len includes additional '\0' */
|
||||||
|
PQfreemem(to);
|
||||||
|
@@ -4251,7 +4261,7 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z
|
||||||
|
char *escaped;
|
||||||
|
smart_str querystr = {0};
|
||||||
|
size_t new_len;
|
||||||
|
- int i, num_rows;
|
||||||
|
+ int i, num_rows, err;
|
||||||
|
zval elem;
|
||||||
|
|
||||||
|
ZEND_ASSERT(*table_name);
|
||||||
|
@@ -4290,7 +4300,14 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z
|
||||||
|
"WHERE a.attnum > 0 AND c.relname = '");
|
||||||
|
}
|
||||||
|
escaped = (char *)safe_emalloc(strlen(tmp_name2), 2, 1);
|
||||||
|
- new_len = PQescapeStringConn(pg_link, escaped, tmp_name2, strlen(tmp_name2), NULL);
|
||||||
|
+ new_len = PQescapeStringConn(pg_link, escaped, tmp_name2, strlen(tmp_name2), &err);
|
||||||
|
+ if (err) {
|
||||||
|
+ php_error_docref(NULL, E_WARNING, "Escaping table name '%s' failed", table_name);
|
||||||
|
+ efree(src);
|
||||||
|
+ efree(escaped);
|
||||||
|
+ smart_str_free(&querystr);
|
||||||
|
+ return FAILURE;
|
||||||
|
+ }
|
||||||
|
if (new_len) {
|
||||||
|
smart_str_appendl(&querystr, escaped, new_len);
|
||||||
|
}
|
||||||
|
@@ -4298,7 +4315,14 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z
|
||||||
|
|
||||||
|
smart_str_appends(&querystr, "' AND n.nspname = '");
|
||||||
|
escaped = (char *)safe_emalloc(strlen(tmp_name), 2, 1);
|
||||||
|
- new_len = PQescapeStringConn(pg_link, escaped, tmp_name, strlen(tmp_name), NULL);
|
||||||
|
+ new_len = PQescapeStringConn(pg_link, escaped, tmp_name, strlen(tmp_name), &err);
|
||||||
|
+ if (err) {
|
||||||
|
+ php_error_docref(NULL, E_WARNING, "Escaping table namespace '%s' failed", table_name);
|
||||||
|
+ efree(src);
|
||||||
|
+ efree(escaped);
|
||||||
|
+ smart_str_free(&querystr);
|
||||||
|
+ return FAILURE;
|
||||||
|
+ }
|
||||||
|
if (new_len) {
|
||||||
|
smart_str_appendl(&querystr, escaped, new_len);
|
||||||
|
}
|
||||||
|
@@ -4575,7 +4599,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
|
||||||
|
{
|
||||||
|
zend_string *field = NULL;
|
||||||
|
zval meta, *def, *type, *not_null, *has_default, *is_enum, *val, new_val;
|
||||||
|
- int err = 0, skip_field;
|
||||||
|
+ int err = 0, escape_err = 0, skip_field;
|
||||||
|
php_pgsql_data_type data_type;
|
||||||
|
|
||||||
|
ZEND_ASSERT(pg_link != NULL);
|
||||||
|
@@ -4829,10 +4853,14 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
|
||||||
|
/* PostgreSQL ignores \0 */
|
||||||
|
str = zend_string_alloc(Z_STRLEN_P(val) * 2, 0);
|
||||||
|
/* better to use PGSQLescapeLiteral since PGescapeStringConn does not handle special \ */
|
||||||
|
- ZSTR_LEN(str) = PQescapeStringConn(pg_link, ZSTR_VAL(str), Z_STRVAL_P(val), Z_STRLEN_P(val), NULL);
|
||||||
|
- str = zend_string_truncate(str, ZSTR_LEN(str), 0);
|
||||||
|
- ZVAL_NEW_STR(&new_val, str);
|
||||||
|
- php_pgsql_add_quotes(&new_val, 1);
|
||||||
|
+ ZSTR_LEN(str) = PQescapeStringConn(pg_link, ZSTR_VAL(str), Z_STRVAL_P(val), Z_STRLEN_P(val), &escape_err);
|
||||||
|
+ if (escape_err) {
|
||||||
|
+ err = 1;
|
||||||
|
+ } else {
|
||||||
|
+ str = zend_string_truncate(str, ZSTR_LEN(str), 0);
|
||||||
|
+ ZVAL_NEW_STR(&new_val, str);
|
||||||
|
+ php_pgsql_add_quotes(&new_val, 1);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
@@ -4854,7 +4882,15 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
|
||||||
|
}
|
||||||
|
PGSQL_CONV_CHECK_IGNORE();
|
||||||
|
if (err) {
|
||||||
|
- php_error_docref(NULL, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
|
||||||
|
+ if (escape_err) {
|
||||||
|
+ php_error_docref(NULL, E_NOTICE,
|
||||||
|
+ "String value escaping failed for PostgreSQL '%s' (%s)",
|
||||||
|
+ Z_STRVAL_P(type), ZSTR_VAL(field));
|
||||||
|
+ } else {
|
||||||
|
+ php_error_docref(NULL, E_NOTICE,
|
||||||
|
+ "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)",
|
||||||
|
+ Z_STRVAL_P(type), ZSTR_VAL(field));
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
@@ -5129,6 +5165,11 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
|
||||||
|
size_t to_len;
|
||||||
|
smart_str s = {0};
|
||||||
|
tmp = PQescapeByteaConn(pg_link, (unsigned char *)Z_STRVAL_P(val), Z_STRLEN_P(val), &to_len);
|
||||||
|
+ if (tmp == NULL) {
|
||||||
|
+ php_error_docref(NULL, E_NOTICE, "Escaping value failed for %s field (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
|
||||||
|
+ err = 1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
ZVAL_STRINGL(&new_val, (char *)tmp, to_len - 1); /* PQescapeBytea's to_len includes additional '\0' */
|
||||||
|
PQfreemem(tmp);
|
||||||
|
php_pgsql_add_quotes(&new_val, 1);
|
||||||
|
@@ -5210,6 +5251,12 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
|
||||||
|
zend_hash_update(Z_ARRVAL_P(result), field, &new_val);
|
||||||
|
} else {
|
||||||
|
char *escaped = PQescapeIdentifier(pg_link, ZSTR_VAL(field), ZSTR_LEN(field));
|
||||||
|
+ if (escaped == NULL) {
|
||||||
|
+ /* This cannot fail because of invalid string but only due to failed memory allocation */
|
||||||
|
+ php_error_docref(NULL, E_NOTICE, "Escaping field '%s' failed", ZSTR_VAL(field));
|
||||||
|
+ err = 1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
add_assoc_zval(result, escaped, &new_val);
|
||||||
|
PQfreemem(escaped);
|
||||||
|
}
|
||||||
|
@@ -5290,7 +5337,7 @@ static int do_exec(smart_str *querystr, ExecStatusType expect, PGconn *pg_link,
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
-static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const char *table) /* {{{ */
|
||||||
|
+static inline zend_result build_tablename(smart_str *querystr, PGconn *pg_link, const char *table) /* {{{ */
|
||||||
|
{
|
||||||
|
size_t table_len = strlen(table);
|
||||||
|
|
||||||
|
@@ -5301,6 +5348,10 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const c
|
||||||
|
smart_str_appendl(querystr, table, len);
|
||||||
|
} else {
|
||||||
|
char *escaped = PQescapeIdentifier(pg_link, table, len);
|
||||||
|
+ if (escaped == NULL) {
|
||||||
|
+ php_error_docref(NULL, E_NOTICE, "Failed to escape table name '%s'", table);
|
||||||
|
+ return FAILURE;
|
||||||
|
+ }
|
||||||
|
smart_str_appends(querystr, escaped);
|
||||||
|
PQfreemem(escaped);
|
||||||
|
}
|
||||||
|
@@ -5313,11 +5364,17 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const c
|
||||||
|
smart_str_appendl(querystr, after_dot, len);
|
||||||
|
} else {
|
||||||
|
char *escaped = PQescapeIdentifier(pg_link, after_dot, len);
|
||||||
|
+ if (escaped == NULL) {
|
||||||
|
+ php_error_docref(NULL, E_NOTICE, "Failed to escape table name '%s'", table);
|
||||||
|
+ return FAILURE;
|
||||||
|
+ }
|
||||||
|
smart_str_appendc(querystr, '.');
|
||||||
|
smart_str_appends(querystr, escaped);
|
||||||
|
PQfreemem(escaped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ return SUCCESS;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
@@ -5338,7 +5395,9 @@ PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var
|
||||||
|
ZVAL_UNDEF(&converted);
|
||||||
|
if (zend_hash_num_elements(Z_ARRVAL_P(var_array)) == 0) {
|
||||||
|
smart_str_appends(&querystr, "INSERT INTO ");
|
||||||
|
- build_tablename(&querystr, pg_link, table);
|
||||||
|
+ if (build_tablename(&querystr, pg_link, table) == FAILURE) {
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
smart_str_appends(&querystr, " DEFAULT VALUES");
|
||||||
|
|
||||||
|
goto no_values;
|
||||||
|
@@ -5354,7 +5413,9 @@ PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var
|
||||||
|
}
|
||||||
|
|
||||||
|
smart_str_appends(&querystr, "INSERT INTO ");
|
||||||
|
- build_tablename(&querystr, pg_link, table);
|
||||||
|
+ if (build_tablename(&querystr, pg_link, table) == FAILURE) {
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
smart_str_appends(&querystr, " (");
|
||||||
|
|
||||||
|
ZEND_HASH_FOREACH_STR_KEY(Z_ARRVAL_P(var_array), fld) {
|
||||||
|
@@ -5364,6 +5425,10 @@ PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var
|
||||||
|
}
|
||||||
|
if (opt & PGSQL_DML_ESCAPE) {
|
||||||
|
tmp = PQescapeIdentifier(pg_link, ZSTR_VAL(fld), ZSTR_LEN(fld) + 1);
|
||||||
|
+ if (tmp == NULL) {
|
||||||
|
+ php_error_docref(NULL, E_NOTICE, "Failed to escape field '%s'", ZSTR_VAL(fld));
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
smart_str_appends(&querystr, tmp);
|
||||||
|
PQfreemem(tmp);
|
||||||
|
} else {
|
||||||
|
@@ -5375,15 +5440,19 @@ PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var
|
||||||
|
smart_str_appends(&querystr, ") VALUES (");
|
||||||
|
|
||||||
|
/* make values string */
|
||||||
|
- ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(var_array), val) {
|
||||||
|
+ ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(var_array), fld, val) {
|
||||||
|
/* we can avoid the key_type check here, because we tested it in the other loop */
|
||||||
|
switch (Z_TYPE_P(val)) {
|
||||||
|
case IS_STRING:
|
||||||
|
if (opt & PGSQL_DML_ESCAPE) {
|
||||||
|
- size_t new_len;
|
||||||
|
- char *tmp;
|
||||||
|
- tmp = (char *)safe_emalloc(Z_STRLEN_P(val), 2, 1);
|
||||||
|
- new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_P(val), Z_STRLEN_P(val), NULL);
|
||||||
|
+ int error;
|
||||||
|
+ char *tmp = safe_emalloc(Z_STRLEN_P(val), 2, 1);
|
||||||
|
+ size_t new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_P(val), Z_STRLEN_P(val), &error);
|
||||||
|
+ if (error) {
|
||||||
|
+ php_error_docref(NULL, E_NOTICE, "Failed to escape field '%s' value", ZSTR_VAL(fld));
|
||||||
|
+ efree(tmp);
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
smart_str_appendc(&querystr, '\'');
|
||||||
|
smart_str_appendl(&querystr, tmp, new_len);
|
||||||
|
smart_str_appendc(&querystr, '\'');
|
||||||
|
@@ -5537,6 +5606,10 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr,
|
||||||
|
}
|
||||||
|
if (opt & PGSQL_DML_ESCAPE) {
|
||||||
|
char *tmp = PQescapeIdentifier(pg_link, ZSTR_VAL(fld), ZSTR_LEN(fld) + 1);
|
||||||
|
+ if (tmp == NULL) {
|
||||||
|
+ php_error_docref(NULL, E_NOTICE, "Failed to escape field '%s'", ZSTR_VAL(fld));
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
smart_str_appends(querystr, tmp);
|
||||||
|
PQfreemem(tmp);
|
||||||
|
} else {
|
||||||
|
@@ -5551,8 +5624,14 @@ static inline int build_assignment_string(PGconn *pg_link, smart_str *querystr,
|
||||||
|
switch (Z_TYPE_P(val)) {
|
||||||
|
case IS_STRING:
|
||||||
|
if (opt & PGSQL_DML_ESCAPE) {
|
||||||
|
+ int error;
|
||||||
|
char *tmp = (char *)safe_emalloc(Z_STRLEN_P(val), 2, 1);
|
||||||
|
- size_t new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_P(val), Z_STRLEN_P(val), NULL);
|
||||||
|
+ size_t new_len = PQescapeStringConn(pg_link, tmp, Z_STRVAL_P(val), Z_STRLEN_P(val), &error);
|
||||||
|
+ if (error) {
|
||||||
|
+ php_error_docref(NULL, E_NOTICE, "Failed to escape field '%s' value", ZSTR_VAL(fld));
|
||||||
|
+ efree(tmp);
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
smart_str_appendc(querystr, '\'');
|
||||||
|
smart_str_appendl(querystr, tmp, new_len);
|
||||||
|
smart_str_appendc(querystr, '\'');
|
||||||
|
@@ -5620,7 +5699,9 @@ PHP_PGSQL_API int php_pgsql_update(PGconn *pg_link, const char *table, zval *var
|
||||||
|
}
|
||||||
|
|
||||||
|
smart_str_appends(&querystr, "UPDATE ");
|
||||||
|
- build_tablename(&querystr, pg_link, table);
|
||||||
|
+ if (build_tablename(&querystr, pg_link, table) == FAILURE) {
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
smart_str_appends(&querystr, " SET ");
|
||||||
|
|
||||||
|
if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(var_array), 0, ",", 1, opt))
|
||||||
|
@@ -5722,7 +5803,9 @@ PHP_PGSQL_API int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids
|
||||||
|
}
|
||||||
|
|
||||||
|
smart_str_appends(&querystr, "DELETE FROM ");
|
||||||
|
- build_tablename(&querystr, pg_link, table);
|
||||||
|
+ if (build_tablename(&querystr, pg_link, table) == FAILURE) {
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
smart_str_appends(&querystr, " WHERE ");
|
||||||
|
|
||||||
|
if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(ids_array), 1, " AND ", sizeof(" AND ")-1, opt))
|
||||||
|
@@ -5860,7 +5943,9 @@ PHP_PGSQL_API void php_pgsql_result2array(PGresult *pg_result, zval *ret_array,
|
||||||
|
}
|
||||||
|
|
||||||
|
smart_str_appends(&querystr, "SELECT * FROM ");
|
||||||
|
- build_tablename(&querystr, pg_link, table);
|
||||||
|
+ if (build_tablename(&querystr, pg_link, table) == FAILURE) {
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
smart_str_appends(&querystr, " WHERE ");
|
||||||
|
|
||||||
|
if (build_assignment_string(pg_link, &querystr, Z_ARRVAL_P(ids_array), 1, " AND ", sizeof(" AND ")-1, opt))
|
||||||
|
diff --git a/ext/pgsql/tests/ghsa-hrwm-9436-5mv3.phpt b/ext/pgsql/tests/ghsa-hrwm-9436-5mv3.phpt
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..c1c5e05dce6
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/ext/pgsql/tests/ghsa-hrwm-9436-5mv3.phpt
|
||||||
|
@@ -0,0 +1,64 @@
|
||||||
|
+--TEST--
|
||||||
|
+#GHSA-hrwm-9436-5mv3: pgsql extension does not check for errors during escaping
|
||||||
|
+--EXTENSIONS--
|
||||||
|
+pgsql
|
||||||
|
+--SKIPIF--
|
||||||
|
+<?php include("skipif.inc"); ?>
|
||||||
|
+--FILE--
|
||||||
|
+<?php
|
||||||
|
+
|
||||||
|
+include 'config.inc';
|
||||||
|
+define('FILE_NAME', __DIR__ . '/php.gif');
|
||||||
|
+
|
||||||
|
+$db = pg_connect($conn_str);
|
||||||
|
+pg_query($db, "DROP TABLE IF EXISTS ghsa_hrmw_9436_5mv3");
|
||||||
|
+pg_query($db, "CREATE TABLE ghsa_hrmw_9436_5mv3 (bar text);");
|
||||||
|
+
|
||||||
|
+// pg_escape_literal/pg_escape_identifier
|
||||||
|
+
|
||||||
|
+$invalid = "ABC\xff\x30';";
|
||||||
|
+$flags = PGSQL_DML_NO_CONV | PGSQL_DML_ESCAPE;
|
||||||
|
+
|
||||||
|
+var_dump(pg_insert($db, $invalid, ['bar' => 'test'])); // table name str escape in php_pgsql_meta_data
|
||||||
|
+var_dump(pg_insert($db, "$invalid.tbl", ['bar' => 'test'])); // schema name str escape in php_pgsql_meta_data
|
||||||
|
+var_dump(pg_insert($db, 'ghsa_hrmw_9436_5mv3', ['bar' => $invalid])); // converted value str escape in php_pgsql_convert
|
||||||
|
+var_dump(pg_insert($db, $invalid, [])); // ident escape in build_tablename
|
||||||
|
+var_dump(pg_insert($db, 'ghsa_hrmw_9436_5mv3', [$invalid => 'foo'], $flags)); // ident escape for field php_pgsql_insert
|
||||||
|
+var_dump(pg_insert($db, 'ghsa_hrmw_9436_5mv3', ['bar' => $invalid], $flags)); // str escape for field value in php_pgsql_insert
|
||||||
|
+var_dump(pg_update($db, 'ghsa_hrmw_9436_5mv3', ['bar' => 'val'], [$invalid => 'test'], $flags)); // ident escape in build_assignment_string
|
||||||
|
+var_dump(pg_update($db, 'ghsa_hrmw_9436_5mv3', ['bar' => 'val'], ['bar' => $invalid], $flags)); // invalid str escape in build_assignment_string
|
||||||
|
+var_dump(pg_escape_literal($db, $invalid)); // pg_escape_literal escape
|
||||||
|
+var_dump(pg_escape_identifier($db, $invalid)); // pg_escape_identifier escape
|
||||||
|
+
|
||||||
|
+?>
|
||||||
|
+--EXPECTF--
|
||||||
|
+
|
||||||
|
+Warning: pg_insert(): Escaping table name 'ABC%s';' failed in %s on line %d
|
||||||
|
+bool(false)
|
||||||
|
+
|
||||||
|
+Warning: pg_insert(): Escaping table namespace 'ABC%s';.tbl' failed in %s on line %d
|
||||||
|
+bool(false)
|
||||||
|
+
|
||||||
|
+Notice: pg_insert(): String value escaping failed for PostgreSQL 'text' (bar) in %s on line %d
|
||||||
|
+bool(false)
|
||||||
|
+
|
||||||
|
+Notice: pg_insert(): Failed to escape table name 'ABC%s';' in %s on line %d
|
||||||
|
+bool(false)
|
||||||
|
+
|
||||||
|
+Notice: pg_insert(): Failed to escape field 'ABC%s';' in %s on line %d
|
||||||
|
+bool(false)
|
||||||
|
+
|
||||||
|
+Notice: pg_insert(): Failed to escape field 'bar' value in %s on line %d
|
||||||
|
+bool(false)
|
||||||
|
+
|
||||||
|
+Notice: pg_update(): Failed to escape field 'ABC%s';' in %s on line %d
|
||||||
|
+bool(false)
|
||||||
|
+
|
||||||
|
+Notice: pg_update(): Failed to escape field 'bar' value in %s on line %d
|
||||||
|
+bool(false)
|
||||||
|
+
|
||||||
|
+Warning: pg_escape_literal(): Failed to escape in %s on line %d
|
||||||
|
+bool(false)
|
||||||
|
+
|
||||||
|
+Warning: pg_escape_identifier(): Failed to escape in %s on line %d
|
||||||
|
+bool(false)
|
||||||
|
--
|
||||||
|
2.50.0
|
||||||
|
|
||||||
|
From 970548b94b7f23be32154d05a9545b10c98bfd62 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Remi Collet <remi@remirepo.net>
|
||||||
|
Date: Thu, 3 Jul 2025 09:32:25 +0200
|
||||||
|
Subject: [PATCH 4/4] NEWS
|
||||||
|
|
||||||
|
---
|
||||||
|
NEWS | 14 ++++++++++++++
|
||||||
|
1 file changed, 14 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/NEWS b/NEWS
|
||||||
|
index 7db6f2660d2..c813f4f357a 100644
|
||||||
|
--- a/NEWS
|
||||||
|
+++ b/NEWS
|
||||||
|
@@ -1,6 +1,20 @@
|
||||||
|
PHP NEWS
|
||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||
|
|
||||||
|
+Backported from 8.1.33
|
||||||
|
+
|
||||||
|
+- PGSQL:
|
||||||
|
+ . Fixed GHSA-hrwm-9436-5mv3 (pgsql extension does not check for errors during
|
||||||
|
+ escaping). (CVE-2025-1735) (Jakub Zelenka)
|
||||||
|
+
|
||||||
|
+- SOAP:
|
||||||
|
+ . Fixed GHSA-453j-q27h-5p8x (NULL Pointer Dereference in PHP SOAP Extension
|
||||||
|
+ via Large XML Namespace Prefix). (CVE-2025-6491) (Lekssays, nielsdos)
|
||||||
|
+
|
||||||
|
+- Standard:
|
||||||
|
+ . Fixed GHSA-3cr5-j632-f35r (Null byte termination in hostnames).
|
||||||
|
+ (CVE-2025-1220) (Jakub Zelenka)
|
||||||
|
+
|
||||||
|
Backported from 8.1.32
|
||||||
|
|
||||||
|
- LibXML:
|
||||||
|
--
|
||||||
|
2.50.0
|
||||||
|
|
102
php-cve-2025-6491.patch
Normal file
102
php-cve-2025-6491.patch
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
From 1b7410a57f8a5fd1dd43854bcf7b9200517c9fd2 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ahmed Lekssays <lekssaysahmed@gmail.com>
|
||||||
|
Date: Tue, 3 Jun 2025 09:00:55 +0000
|
||||||
|
Subject: [PATCH 1/4] Fix GHSA-453j-q27h-5p8x
|
||||||
|
|
||||||
|
Libxml versions prior to 2.13 cannot correctly handle a call to
|
||||||
|
xmlNodeSetName() with a name longer than 2G. It will leave the node
|
||||||
|
object in an invalid state with a NULL name. This later causes a NULL
|
||||||
|
pointer dereference when using the name during message serialization.
|
||||||
|
|
||||||
|
To solve this, implement a workaround that resets the name to the
|
||||||
|
sentinel name if this situation arises.
|
||||||
|
|
||||||
|
Versions of libxml of 2.13 and higher are not affected.
|
||||||
|
|
||||||
|
This can be exploited if a SoapVar is created with a fully qualified
|
||||||
|
name that is longer than 2G. This would be possible if some application
|
||||||
|
code uses a namespace prefix from an untrusted source like from a remote
|
||||||
|
SOAP service.
|
||||||
|
|
||||||
|
Co-authored-by: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
|
||||||
|
(cherry picked from commit 9cb3d8d200f0c822b17bda35a2a67a97b039d3e1)
|
||||||
|
---
|
||||||
|
ext/soap/soap.c | 6 ++--
|
||||||
|
ext/soap/tests/soap_qname_crash.phpt | 48 ++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 52 insertions(+), 2 deletions(-)
|
||||||
|
create mode 100644 ext/soap/tests/soap_qname_crash.phpt
|
||||||
|
|
||||||
|
diff --git a/ext/soap/soap.c b/ext/soap/soap.c
|
||||||
|
index a8df136d665..08d6f285d28 100644
|
||||||
|
--- a/ext/soap/soap.c
|
||||||
|
+++ b/ext/soap/soap.c
|
||||||
|
@@ -4143,8 +4143,10 @@ static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName,
|
||||||
|
}
|
||||||
|
xmlParam = master_to_xml(enc, val, style, parent);
|
||||||
|
zval_ptr_dtor(&defval);
|
||||||
|
- if (!strcmp((char*)xmlParam->name, "BOGUS")) {
|
||||||
|
- xmlNodeSetName(xmlParam, BAD_CAST(paramName));
|
||||||
|
+ if (xmlParam != NULL) {
|
||||||
|
+ if (xmlParam->name == NULL || strcmp((char*)xmlParam->name, "BOGUS") == 0) {
|
||||||
|
+ xmlNodeSetName(xmlParam, BAD_CAST(paramName));
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
return xmlParam;
|
||||||
|
}
|
||||||
|
diff --git a/ext/soap/tests/soap_qname_crash.phpt b/ext/soap/tests/soap_qname_crash.phpt
|
||||||
|
new file mode 100644
|
||||||
|
index 00000000000..52177577788
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/ext/soap/tests/soap_qname_crash.phpt
|
||||||
|
@@ -0,0 +1,48 @@
|
||||||
|
+--TEST--
|
||||||
|
+Test SoapClient with excessively large QName prefix in SoapVar
|
||||||
|
+--EXTENSIONS--
|
||||||
|
+soap
|
||||||
|
+--SKIPIF--
|
||||||
|
+<?php
|
||||||
|
+if (PHP_INT_SIZE != 8) die("skip: 64-bit only");
|
||||||
|
+?>
|
||||||
|
+--INI--
|
||||||
|
+memory_limit=8G
|
||||||
|
+--FILE--
|
||||||
|
+<?php
|
||||||
|
+
|
||||||
|
+class TestSoapClient extends SoapClient {
|
||||||
|
+ public function __doRequest(
|
||||||
|
+ $request,
|
||||||
|
+ $location,
|
||||||
|
+ $action,
|
||||||
|
+ $version,
|
||||||
|
+ $one_way = false,
|
||||||
|
+ ): ?string {
|
||||||
|
+ die($request);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+$prefix = str_repeat("A", 2 * 1024 * 1024 * 1024);
|
||||||
|
+$qname = "{$prefix}:tag";
|
||||||
|
+
|
||||||
|
+echo "Attempting to create SoapVar with very large QName\n";
|
||||||
|
+
|
||||||
|
+$var = new SoapVar("value", XSD_QNAME, null, null, $qname);
|
||||||
|
+
|
||||||
|
+echo "Attempting encoding\n";
|
||||||
|
+
|
||||||
|
+$options = [
|
||||||
|
+ 'location' => 'http://127.0.0.1/',
|
||||||
|
+ 'uri' => 'urn:dummy',
|
||||||
|
+ 'trace' => 1,
|
||||||
|
+ 'exceptions' => true,
|
||||||
|
+];
|
||||||
|
+$client = new TestSoapClient(null, $options);
|
||||||
|
+$client->__soapCall("DummyFunction", [$var]);
|
||||||
|
+?>
|
||||||
|
+--EXPECT--
|
||||||
|
+Attempting to create SoapVar with very large QName
|
||||||
|
+Attempting encoding
|
||||||
|
+<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:dummy" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:DummyFunction><param0 xsi:type="xsd:QName">value</param0></ns1:DummyFunction></SOAP-ENV:Body></SOAP-ENV:Envelope>
|
||||||
|
--
|
||||||
|
2.50.0
|
||||||
|
|
24
php.spec
24
php.spec
@ -62,7 +62,7 @@
|
|||||||
Summary: PHP scripting language for creating dynamic web sites
|
Summary: PHP scripting language for creating dynamic web sites
|
||||||
Name: php
|
Name: php
|
||||||
Version: %{upver}%{?rcver:~%{rcver}}
|
Version: %{upver}%{?rcver:~%{rcver}}
|
||||||
Release: 3%{?dist}
|
Release: 4%{?dist}
|
||||||
# All files licensed under PHP version 3.01, except
|
# All files licensed under PHP version 3.01, except
|
||||||
# Zend is licensed under Zend
|
# Zend is licensed under Zend
|
||||||
# TSRM is licensed under BSD
|
# TSRM is licensed under BSD
|
||||||
@ -121,6 +121,10 @@ Patch49: php-8.0.10-phar-sha.patch
|
|||||||
Patch50: php-8.0.21-openssl3.patch
|
Patch50: php-8.0.21-openssl3.patch
|
||||||
# use system libxcrypt
|
# use system libxcrypt
|
||||||
Patch51: php-8.0.13-crypt.patch
|
Patch51: php-8.0.13-crypt.patch
|
||||||
|
# soap fixes from 8.3
|
||||||
|
Patch52: php-8.0.30-soap.patch
|
||||||
|
# ldap fixes from 8.3
|
||||||
|
Patch53: php-8.0.30-ldap.patch
|
||||||
|
|
||||||
# Upstream fixes (100+)
|
# Upstream fixes (100+)
|
||||||
|
|
||||||
@ -144,6 +148,9 @@ Patch214: php-cve-2025-1734.patch
|
|||||||
Patch215: php-cve-2025-1861.patch
|
Patch215: php-cve-2025-1861.patch
|
||||||
Patch216: php-cve-2025-1736.patch
|
Patch216: php-cve-2025-1736.patch
|
||||||
Patch217: php-cve-2025-1219.patch
|
Patch217: php-cve-2025-1219.patch
|
||||||
|
Patch218: php-cve-2025-6491.patch
|
||||||
|
Patch219: php-cve-2025-1220.patch
|
||||||
|
Patch220: php-cve-2025-1735.patch
|
||||||
|
|
||||||
# Fixes for tests (300+)
|
# Fixes for tests (300+)
|
||||||
# Factory is droped from system tzdata
|
# Factory is droped from system tzdata
|
||||||
@ -742,6 +749,8 @@ in pure PHP.
|
|||||||
%patch -P50 -p1 -b .openssl3
|
%patch -P50 -p1 -b .openssl3
|
||||||
rm ext/openssl/tests/p12_with_extra_certs.p12
|
rm ext/openssl/tests/p12_with_extra_certs.p12
|
||||||
%patch -P51 -p1 -b .libxcrypt
|
%patch -P51 -p1 -b .libxcrypt
|
||||||
|
%patch -P52 -p1 -b .soapbackports
|
||||||
|
%patch -P53 -p1 -b .ldapbackports
|
||||||
|
|
||||||
# upstream patches
|
# upstream patches
|
||||||
|
|
||||||
@ -764,6 +773,9 @@ rm ext/openssl/tests/p12_with_extra_certs.p12
|
|||||||
%patch -P215 -p1 -b .cve1861
|
%patch -P215 -p1 -b .cve1861
|
||||||
%patch -P216 -p1 -b .cve1736
|
%patch -P216 -p1 -b .cve1736
|
||||||
%patch -P217 -p1 -b .cve1219
|
%patch -P217 -p1 -b .cve1219
|
||||||
|
%patch -P218 -p1 -b .cve6491
|
||||||
|
%patch -P219 -p1 -b .cve1220
|
||||||
|
%patch -P220 -p1 -b .cve1735
|
||||||
|
|
||||||
# Fixes for tests
|
# Fixes for tests
|
||||||
%patch -P300 -p1 -b .datetests
|
%patch -P300 -p1 -b .datetests
|
||||||
@ -1572,6 +1584,16 @@ systemctl try-restart php-fpm.service >/dev/null 2>&1 || :
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Oct 3 2025 Remi Collet <rcollet@redhat.com> - 8.0.30-4
|
||||||
|
- Fix pgsql extension does not check for errors during escaping
|
||||||
|
CVE-2025-1735
|
||||||
|
- Fix NULL Pointer Dereference in PHP SOAP Extension via Large XML Namespace Prefix
|
||||||
|
CVE-2025-6491
|
||||||
|
- Fix Null byte termination in hostnames
|
||||||
|
CVE-2025-1220
|
||||||
|
- Fix soap memory corruption
|
||||||
|
- Fix ldap_set_option() not applied on different ldap connections
|
||||||
|
|
||||||
* Thu Mar 13 2025 Remi Collet <rcollet@redhat.com> - 8.0.30-3
|
* Thu Mar 13 2025 Remi Collet <rcollet@redhat.com> - 8.0.30-3
|
||||||
- Fix libxml streams use wrong `content-type` header when requesting a redirected resource
|
- Fix libxml streams use wrong `content-type` header when requesting a redirected resource
|
||||||
CVE-2025-1219
|
CVE-2025-1219
|
||||||
|
Loading…
Reference in New Issue
Block a user