summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2020-01-20 18:05:00 +0100
committerStanislav Malyshev <stas@php.net>2020-01-20 21:43:42 -0800
commitf79c7742746907d676989cb7f97fb4f7cd26789f (patch)
tree74eb9c8b2a31f7defe5fc009aa692745bf399b84
parent864f5ef12f588b30236f80cb60021485a4a78f9a (diff)
downloadphp-git-f79c7742746907d676989cb7f97fb4f7cd26789f.tar.gz
Fix #79091: heap use-after-free in session_create_id()
If the `new_id` is released, we must not use it again.
-rw-r--r--ext/session/session.c1
-rw-r--r--ext/session/tests/bug79091.phpt67
2 files changed, 68 insertions, 0 deletions
diff --git a/ext/session/session.c b/ext/session/session.c
index 65fb30697c..f470067faf 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -2198,6 +2198,7 @@ static PHP_FUNCTION(session_create_id)
/* Detect collision and retry */
if (PS(mod)->s_validate_sid(&PS(mod_data), new_id) == FAILURE) {
zend_string_release(new_id);
+ new_id = NULL;
continue;
}
break;
diff --git a/ext/session/tests/bug79091.phpt b/ext/session/tests/bug79091.phpt
new file mode 100644
index 0000000000..1d14427159
--- /dev/null
+++ b/ext/session/tests/bug79091.phpt
@@ -0,0 +1,67 @@
+--TEST--
+Bug #79091 (heap use-after-free in session_create_id())
+--SKIPIF--
+<?php
+if (!extension_loaded('session')) die('skip session extension not available');
+?>
+--FILE--
+<?php
+class MySessionHandler implements SessionHandlerInterface, SessionIdInterface, SessionUpdateTimestampHandlerInterface
+{
+ public function close()
+ {
+ return true;
+ }
+
+ public function destroy($session_id)
+ {
+ return true;
+ }
+
+ public function gc($maxlifetime)
+ {
+ return true;
+ }
+
+ public function open($save_path, $session_name)
+ {
+ return true;
+ }
+
+ public function read($session_id)
+ {
+ return '';
+ }
+
+ public function write($session_id, $session_data)
+ {
+ return true;
+ }
+
+ public function create_sid()
+ {
+ return uniqid();
+ }
+
+ public function updateTimestamp($key, $val)
+ {
+ return true;
+ }
+
+ public function validateId($key)
+ {
+ return false;
+ }
+}
+
+ob_start();
+var_dump(session_set_save_handler(new MySessionHandler()));
+var_dump(session_start());
+ob_flush();
+session_create_id();
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+
+Warning: session_create_id(): Failed to create new ID in %s on line %d