From 6e664a04cb8fec50dd19195d4c9b29fb8ac83b21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Tue, 10 Mar 2026 20:06:34 +0100 Subject: [PATCH 1/5] reflection: Check against the known string in `is_closure_invoke()` (#21402) This can likely succeed by just comparing pointers in a majority of cases. --- ext/reflection/php_reflection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 2f44d6be7bd2..e44a746ff084 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -191,7 +191,7 @@ static zend_always_inline uint32_t prop_get_flags(const property_reference *ref) static inline bool is_closure_invoke(const zend_class_entry *ce, const zend_string *lcname) { return ce == zend_ce_closure - && zend_string_equals_literal(lcname, ZEND_INVOKE_FUNC_NAME); + && zend_string_equals(lcname, ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE)); } static zend_function *_copy_function(zend_function *fptr) /* {{{ */ From 3073948885d95c42ab4ce97109edb2b8f4dc6ed4 Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Tue, 10 Mar 2026 20:27:48 +0100 Subject: [PATCH 2/5] Revert "ext/session: Fix memory leak due to multiple exception happening during session abort" This reverts commit 0acde1194513ff69c491f3c1ebe103c3774dc7fd. The patch is incorrect as described in GH-21200 in the post-merge comments. --- NEWS | 4 --- ext/session/session.c | 11 +----- ...sessionhandler_validateid_return_type.phpt | 35 ------------------- .../session_set_save_handler_class_012.phpt | 2 -- 4 files changed, 1 insertion(+), 51 deletions(-) delete mode 100644 ext/session/tests/sessionhandler_validateid_return_type.phpt diff --git a/NEWS b/NEWS index 9f2b1ed85e20..5380688ce3da 100644 --- a/NEWS +++ b/NEWS @@ -13,10 +13,6 @@ PHP NEWS . Fixed preprocessor silently guarding PGSQL_SUPPRESS_TIMESTAMPS support due to a typo. (KentarouTakeda) -- Session: - . Fix memory leak due to multiple exception happening during session abort. - (arshidkv12) - - SNMP: . Fixed bug GH-21336 (SNMP::setSecurity() undefined behavior with NULL arguments). (David Carlier) diff --git a/ext/session/session.c b/ext/session/session.c index f8d963b48947..70e1673d87f5 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -41,7 +41,6 @@ #include "ext/standard/url_scanner_ex.h" #include "ext/standard/info.h" #include "zend_smart_str.h" -#include "zend_exceptions.h" #include "ext/standard/url.h" #include "ext/standard/basic_functions.h" #include "ext/standard/head.h" @@ -1744,16 +1743,8 @@ PHPAPI php_session_status php_get_session_status(void) static zend_result php_session_abort(void) /* {{{ */ { if (PS(session_status) == php_session_active) { - if ((PS(mod_data) || PS(mod_user_implemented)) && PS(mod)->s_close) { - zend_object *old_exception = EG(exception); - EG(exception) = NULL; - + if (PS(mod_data) || PS(mod_user_implemented)) { PS(mod)->s_close(&PS(mod_data)); - if (!EG(exception)) { - EG(exception) = old_exception; - } else if (old_exception) { - zend_exception_set_previous(EG(exception), old_exception); - } } PS(session_status) = php_session_none; return SUCCESS; diff --git a/ext/session/tests/sessionhandler_validateid_return_type.phpt b/ext/session/tests/sessionhandler_validateid_return_type.phpt deleted file mode 100644 index a10069458820..000000000000 --- a/ext/session/tests/sessionhandler_validateid_return_type.phpt +++ /dev/null @@ -1,35 +0,0 @@ ---TEST-- -SessionHandler::validateId must return bool ---INI-- -session.use_strict_mode=1 ---EXTENSIONS-- -session ---SKIPIF-- - ---FILE-- -getMessage(), "\n"; -} - -session_write_close(); - -try { - session_start(); -} catch (Throwable $e) { - echo $e->getMessage(), "\n"; -} -?> ---EXPECTF-- -Session id must be a string diff --git a/ext/session/tests/user_session_module/session_set_save_handler_class_012.phpt b/ext/session/tests/user_session_module/session_set_save_handler_class_012.phpt index a532dff7f821..f96206efbb64 100644 --- a/ext/session/tests/user_session_module/session_set_save_handler_class_012.phpt +++ b/ext/session/tests/user_session_module/session_set_save_handler_class_012.phpt @@ -43,8 +43,6 @@ var_dump(session_id(), $oldHandler, ini_get('session.save_handler'), $handler->i --EXPECTF-- *** Testing session_set_save_handler() : incorrect arguments for existing handler open *** Open: - -Warning: SessionHandler::close(): Parent session handler is not open in %s on line %d SessionHandler::open() expects exactly 2 arguments, 0 given Warning: Undefined global variable $_SESSION in %s on line %d From ea8aab92208186799112d1aa53dde56685332f37 Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Sun, 8 Mar 2026 23:00:49 +0100 Subject: [PATCH 3/5] Fix memory leak in shm_get_var() when variable is corrupted This path wasn't tested (clearly). To trigger this we use FFI, which seemed like the easiest way that doesn't involve using another process messing with the shared memory. Closes GH-21388. --- NEWS | 3 ++ ext/sysvshm/sysvshm.c | 8 ++++-- ext/sysvshm/tests/shm_get_var_leak.phpt | 37 +++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 ext/sysvshm/tests/shm_get_var_leak.phpt diff --git a/NEWS b/NEWS index 5380688ce3da..542447107fac 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,9 @@ PHP NEWS . Fixed bug GH-20627 (Cannot identify some avif images with getimagesize). (y-guyon) +- Sysvshm: + . Fix memory leak in shm_get_var() when variable is corrupted. (ndossche) + 12 Mar 2026, PHP 8.4.19 - Core: diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c index 332a8b47af1b..3fa7c77add34 100644 --- a/ext/sysvshm/sysvshm.c +++ b/ext/sysvshm/sysvshm.c @@ -309,11 +309,13 @@ PHP_FUNCTION(shm_get_var) shm_data = &shm_var->mem; PHP_VAR_UNSERIALIZE_INIT(var_hash); - if (php_var_unserialize(return_value, (const unsigned char **) &shm_data, (unsigned char *) shm_data + shm_var->length, &var_hash) != 1) { + int res = php_var_unserialize(return_value, (const unsigned char **) &shm_data, (unsigned char *) shm_data + shm_var->length, &var_hash); + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + if (res != 1) { php_error_docref(NULL, E_WARNING, "Variable data in shared memory is corrupted"); - RETVAL_FALSE; + zval_ptr_dtor(return_value); + RETURN_FALSE; } - PHP_VAR_UNSERIALIZE_DESTROY(var_hash); } /* }}} */ diff --git a/ext/sysvshm/tests/shm_get_var_leak.phpt b/ext/sysvshm/tests/shm_get_var_leak.phpt new file mode 100644 index 000000000000..037bad7c41d7 --- /dev/null +++ b/ext/sysvshm/tests/shm_get_var_leak.phpt @@ -0,0 +1,37 @@ +--TEST-- +shm_get_var() leaks if variable is corrupted +--EXTENSIONS-- +sysvshm +ffi +--INI-- +ffi.enable=1 +--SKIPIF-- + +--FILE-- +shmat($ffi->shmget($key, 0, 0), $ffi->new('void *'), 0); + +$ptr[0x40 + 13] = 0; // Corrupt first byte of second element of serialized data + +var_dump(shm_get_var($s, 0)); + +shm_remove($s); + +?> +--EXPECTF-- +Warning: shm_get_var(): Variable data in shared memory is corrupted in %s on line %d +bool(false) From ae0bf447b475a367977fc432f6976536e8c9408e Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Tue, 10 Mar 2026 20:51:51 +0100 Subject: [PATCH 4/5] soap: Fix const-generic compile warning --- ext/soap/php_encoding.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 73245fd1a181..bce33124429a 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -2529,8 +2529,7 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data) if (data && (attr = get_attribute(data->properties,"arrayType")) && attr->children && attr->children->content) { - const char *type; - char *end, *ns; + char *type, *end, *ns; xmlNsPtr nsptr; parse_namespace(attr->children->content, &type, &ns); From c4c1261196f7ef72ad74c0c4b3c934b6f8fb4546 Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Tue, 10 Mar 2026 21:06:20 +0100 Subject: [PATCH 5/5] soap: Fix const violation --- ext/soap/php_encoding.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index bce33124429a..f704c624875a 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -2529,23 +2529,25 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data) if (data && (attr = get_attribute(data->properties,"arrayType")) && attr->children && attr->children->content) { - char *type, *end, *ns; + const char *type; + char *end, *ns; xmlNsPtr nsptr; parse_namespace(attr->children->content, &type, &ns); + char *type_dup = estrdup(type); nsptr = xmlSearchNs(attr->doc, attr->parent, BAD_CAST(ns)); - end = strrchr(type,'['); + end = strrchr(type_dup,'['); if (end) { *end = '\0'; dimension = calc_dimension(end+1); dims = get_position(dimension, end+1); } if (nsptr != NULL) { - enc = get_encoder(SOAP_GLOBAL(sdl), (char*)nsptr->href, type); + enc = get_encoder(SOAP_GLOBAL(sdl), (char*)nsptr->href, type_dup); } if (ns) {efree(ns);} - + if (type_dup) efree(type_dup); } else if ((attr = get_attribute(data->properties,"itemType")) && attr->children && attr->children->content) {