[PHP-CVS] [php-src] PHP-8.4: Fix GH-23043: broken session id code can cause zend_mm_heap corrupted

[email protected] (ndossche) Wed, 5 Aug 2026 08:30:53 +0000
Newsgroups php.cvs
Message-ID <[email protected]>
Author: ndossche (ndossche)
Date: 2026-08-05T10:24:42+02:00

Commit: https://github.com/php/php-src/commit/9366c61247f797e611a09f14478fc75a0b4edd33
Raw diff: https://github.com/php/php-src/commit/9366c61247f797e611a09f14478fc75a0b4edd33.diff

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.

Closes GH-23046.

Changed paths:
  A  ext/session/tests/user_session_module/gh23043.phpt
  M  NEWS
  M  ext/session/session.c


Diff:

diff --git a/NEWS b/NEWS
index 378643836c80..474db936ef15 100644
--- a/NEWS
+++ b/NEWS
@@ -37,6 +37,11 @@ PHP                                                                        NEWS
   . Fixed segfault in ReflectionMethod::createFromMethodName() on an
     uninstantiable subclass. (iliaal)
 
+- Session:
+  . Fix corruption in mod_mm. (ndossche)
+  . Fixed bug GH-23043 (broken session id code can cause zend_mm_heap
+    corrupted). (ndossche)
+
 - Sockets:
   . Fixed various memory related issues in ext/sockets. (David Carlier)
 
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--
+<?php
+ob_start();
+class a extends SessionHandler {
+    function read($b): string {
+        return "";
+    }
+    function create_sid(): string {
+        var_dump(session_id());
+        return '';
+    }
+}
+$c = new a;
+session_set_save_handler($c);
+session_start();
+session_write_close();
+session_start();
+?>
+--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