]> granicus.if.org Git - php/commitdiff
Increase serialize_lock while decoding session
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 25 Sep 2019 09:02:23 +0000 (11:02 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 25 Sep 2019 09:02:23 +0000 (11:02 +0200)
Avoid leaking state between Serializable::unserialize() and
session_decode().

ext/session/session.c
ext/standard/tests/serialize/bug70219_1.phpt

index 671968e8da30e57ee02d32f8c15ffb2a7a8b2ca7..01c2d4b85a5608854622e7ee6dac69075e4efe59 100644 (file)
@@ -244,11 +244,18 @@ static zend_string *php_session_encode(void) /* {{{ */
 
 static int php_session_decode(zend_string *data) /* {{{ */
 {
+       int res;
        if (!PS(serializer)) {
                php_error_docref(NULL, E_WARNING, "Unknown session.serialize_handler. Failed to decode session object");
                return FAILURE;
        }
-       if (PS(serializer)->decode(ZSTR_VAL(data), ZSTR_LEN(data)) == FAILURE) {
+       /* Make sure that any uses of unserialize() during session decoding do not share
+        * state with any unserialize() that is already in progress (e.g. because we are
+        * currently inside Serializable::unserialize(). */
+       BG(serialize_lock)++;
+       res = PS(serializer)->decode(ZSTR_VAL(data), ZSTR_LEN(data));
+       BG(serialize_lock)--;
+       if (res == FAILURE) {
                php_session_destroy();
                php_session_track_init();
                php_error_docref(NULL, E_WARNING, "Failed to decode session object. Session has been destroyed");
index 6bbc593b345d92e7834ba1d42f631c05073e2b03..6492a9a21e306ba5477c74f2b9ba1181f0f70815 100644 (file)
@@ -18,6 +18,7 @@ class obj implements Serializable {
     }
     function unserialize($data) {
         session_decode($data);
+        return null;
     }
 }
 
@@ -33,20 +34,18 @@ for ($i = 0; $i < 5; $i++) {
 var_dump($data);
 var_dump($_SESSION);
 ?>
---EXPECTF--
+--EXPECT--
 array(2) {
   [0]=>
-  object(obj)#%d (1) {
+  object(obj)#1 (1) {
     ["data"]=>
     NULL
   }
   [1]=>
-  object(obj)#%d (1) {
+  object(obj)#2 (1) {
     ["data"]=>
     NULL
   }
 }
-object(obj)#1 (1) {
-  ["data"]=>
-  NULL
+array(0) {
 }