Skip to content

Commit 3798eb6

Browse files
committed
Fix bug #72562 - destroy var_hash properly
1 parent aa82e99 commit 3798eb6

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

ext/session/session.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -866,7 +866,7 @@ PS_SERIALIZER_DECODE_FUNC(php_serialize) /* {{{ */
866866
if (php_var_unserialize(&session_vars, &val, endptr, &var_hash TSRMLS_CC)) {
867867
var_push_dtor(&var_hash, &session_vars);
868868
}
869-
869+
870870
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
871871
if (PS(http_session_vars)) {
872872
zval_ptr_dtor(&PS(http_session_vars));
@@ -931,6 +931,7 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */
931931
namelen = ((unsigned char)(*p)) & (~PS_BIN_UNDEF);
932932

933933
if (namelen < 0 || namelen > PS_BIN_MAX || (p + namelen) >= endptr) {
934+
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
934935
return FAILURE;
935936
}
936937

ext/session/tests/bug72562.phpt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
--TEST--
2+
Bug #72562: Use After Free in unserialize() with Unexpected Session Deserialization
3+
--SKIPIF--
4+
<?php include('skipif.inc'); ?>
5+
--FILE--
6+
<?php
7+
8+
ini_set('session.serialize_handler', 'php_binary');
9+
session_start();
10+
$sess = "\x1xi:1;\x2y";
11+
session_decode($sess);
12+
$uns_1 = '{';
13+
$out_1[] = unserialize($uns_1);
14+
unset($out_1);
15+
$fakezval = ptr2str(1122334455);
16+
$fakezval .= ptr2str(0);
17+
$fakezval .= "\x00\x00\x00\x00";
18+
$fakezval .= "\x01";
19+
$fakezval .= "\x00";
20+
$fakezval .= "\x00\x00";
21+
for ($i = 0; $i < 5; $i++) {
22+
$v[$i] = $fakezval.$i;
23+
}
24+
$uns_2 = 'R:2;';
25+
$out_2 = unserialize($uns_2);
26+
var_dump($out_2);
27+
28+
function ptr2str($ptr)
29+
{
30+
$out = '';
31+
for ($i = 0; $i < 8; $i++) {
32+
$out .= chr($ptr & 0xff);
33+
$ptr >>= 8;
34+
}
35+
return $out;
36+
}
37+
?>
38+
--EXPECTF--
39+
Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s/bug72562.php on line %d
40+
41+
Notice: unserialize(): Error at offset 0 of 1 bytes in %s/bug72562.php on line %d
42+
43+
Notice: unserialize(): Error at offset 4 of 4 bytes in %s/bug72562.php on line %d
44+
bool(false)

0 commit comments

Comments
 (0)