From eb168c6675c474a406aec1a6016e2949386d5c0f Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Tue, 4 Aug 2026 20:58:56 +0200 Subject: [PATCH 1/2] session: fix corruption in mod_mm --- ext/session/mod_mm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/session/mod_mm.c b/ext/session/mod_mm.c index b997a2bdcff5..75ee713e9f09 100644 --- a/ext/session/mod_mm.c +++ b/ext/session/mod_mm.c @@ -351,7 +351,7 @@ PS_READ_FUNC(mm) && ps_mm_key_exists(data, key) == FAILURE) { /* key points to PS(id), but cannot change here. */ if (key) { - efree(PS(id)); + zend_string_release_ex(PS(id), false); PS(id) = NULL; } PS(id) = PS(mod)->s_create_sid((void **)&data); From 0d6e73c9f04c187b9f3e258f3a71fbf5e5550d26 Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Tue, 4 Aug 2026 21:00:40 +0200 Subject: [PATCH 2/2] Fix GH-23043: broken session id code can cause zend_mm_heap corrupted The id must be reset to NULL before calling code that can invoke userland code, as the id remains visible after release due to a stale pointer. --- ext/session/session.c | 3 ++ .../tests/user_session_module/gh23043.phpt | 35 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 ext/session/tests/user_session_module/gh23043.phpt diff --git a/ext/session/session.c b/ext/session/session.c index ba71d709a536..6380505ae951 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -443,6 +443,7 @@ static zend_result php_session_initialize(void) /* {{{ */ if (!PS(id) || !ZSTR_VAL(PS(id))[0]) { if (PS(id)) { zend_string_release_ex(PS(id), 0); + PS(id) = NULL; } PS(id) = PS(mod)->s_create_sid(&PS(mod_data)); if (!PS(id)) { @@ -460,6 +461,7 @@ static zend_result php_session_initialize(void) /* {{{ */ ) { if (PS(id)) { zend_string_release_ex(PS(id), 0); + PS(id) = NULL; } PS(id) = PS(mod)->s_create_sid(&PS(mod_data)); if (!PS(id)) { @@ -2440,6 +2442,7 @@ PHP_FUNCTION(session_regenerate_id) /* Try to generate non-existing ID */ while (limit-- && PS(mod)->s_validate_sid(&PS(mod_data), PS(id)) == SUCCESS) { zend_string_release_ex(PS(id), 0); + PS(id) = NULL; PS(id) = PS(mod)->s_create_sid(&PS(mod_data)); if (!PS(id)) { PS(mod)->s_close(&PS(mod_data)); diff --git a/ext/session/tests/user_session_module/gh23043.phpt b/ext/session/tests/user_session_module/gh23043.phpt new file mode 100644 index 000000000000..e3528884a79a --- /dev/null +++ b/ext/session/tests/user_session_module/gh23043.phpt @@ -0,0 +1,35 @@ +--TEST-- +GH-23043 (broken session id code can cause zend_mm_heap corrupted) +--EXTENSIONS-- +session +--CREDITS-- +lmaltsis +--FILE-- + +--EXPECTF-- +string(0) "" + +Warning: SessionHandler::write(): Session ID is too long or contains illegal characters. Only the A-Z, a-z, 0-9, "-", and "," characters are allowed in %s on line %d + +Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: , handler: a::write) in %s on line %d +string(0) "" + +Warning: SessionHandler::write(): Session ID is too long or contains illegal characters. Only the A-Z, a-z, 0-9, "-", and "," characters are allowed in Unknown on line 0 + +Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: , handler: a::write) in Unknown on line 0