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

ndossche <[email protected]>
Newsgroups gmane.comp.php.cvs.general
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.