]> granicus.if.org Git - php/commitdiff
Fix #79091: heap use-after-free in session_create_id()
authorChristoph M. Becker <cmbecker69@gmx.de>
Mon, 20 Jan 2020 17:05:00 +0000 (18:05 +0100)
committerStanislav Malyshev <stas@php.net>
Tue, 21 Jan 2020 05:43:42 +0000 (21:43 -0800)
If the `new_id` is released, we must not use it again.

ext/session/session.c
ext/session/tests/bug79091.phpt [new file with mode: 0644]

index 65fb30697cb2d9df7c5ca70d4c37544b212d85d9..f470067faf047644b155272334d44087ffbde23c 100644 (file)
@@ -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 (file)
index 0000000..1d14427
--- /dev/null
@@ -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