Skip to content

Commit b8ef7c3

Browse files
committed
Increase serialize_lock while decoding session
Avoid leaking state between Serializable::unserialize() and session_decode().
1 parent b100d51 commit b8ef7c3

File tree

2 files changed

+13
-7
lines changed

2 files changed

+13
-7
lines changed

ext/session/session.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,18 @@ static zend_string *php_session_encode(void) /* {{{ */
244244

245245
static int php_session_decode(zend_string *data) /* {{{ */
246246
{
247+
int res;
247248
if (!PS(serializer)) {
248249
php_error_docref(NULL, E_WARNING, "Unknown session.serialize_handler. Failed to decode session object");
249250
return FAILURE;
250251
}
251-
if (PS(serializer)->decode(ZSTR_VAL(data), ZSTR_LEN(data)) == FAILURE) {
252+
/* Make sure that any uses of unserialize() during session decoding do not share
253+
* state with any unserialize() that is already in progress (e.g. because we are
254+
* currently inside Serializable::unserialize(). */
255+
BG(serialize_lock)++;
256+
res = PS(serializer)->decode(ZSTR_VAL(data), ZSTR_LEN(data));
257+
BG(serialize_lock)--;
258+
if (res == FAILURE) {
252259
php_session_destroy();
253260
php_session_track_init();
254261
php_error_docref(NULL, E_WARNING, "Failed to decode session object. Session has been destroyed");

ext/standard/tests/serialize/bug70219_1.phpt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class obj implements Serializable {
1818
}
1919
function unserialize($data) {
2020
session_decode($data);
21+
return null;
2122
}
2223
}
2324

@@ -33,20 +34,18 @@ for ($i = 0; $i < 5; $i++) {
3334
var_dump($data);
3435
var_dump($_SESSION);
3536
?>
36-
--EXPECTF--
37+
--EXPECT--
3738
array(2) {
3839
[0]=>
39-
object(obj)#%d (1) {
40+
object(obj)#1 (1) {
4041
["data"]=>
4142
NULL
4243
}
4344
[1]=>
44-
object(obj)#%d (1) {
45+
object(obj)#2 (1) {
4546
["data"]=>
4647
NULL
4748
}
4849
}
49-
object(obj)#1 (1) {
50-
["data"]=>
51-
NULL
50+
array(0) {
5251
}

0 commit comments

Comments
 (0)