diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-09-25 11:02:23 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-09-25 11:02:23 +0200 |
commit | b8ef7c35abd31666d9fb317db4b09a9eef0ede6c (patch) | |
tree | d7a724708c1403b769a429a858affdbfcf6f93d4 /ext/session | |
parent | b100d51ba2668f9d3a051531575171a7184dc1c6 (diff) | |
download | php-git-b8ef7c35abd31666d9fb317db4b09a9eef0ede6c.tar.gz |
Increase serialize_lock while decoding session
Avoid leaking state between Serializable::unserialize() and
session_decode().
Diffstat (limited to 'ext/session')
-rw-r--r-- | ext/session/session.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/ext/session/session.c b/ext/session/session.c index 671968e8da..01c2d4b85a 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -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"); |