Skip to content
Permalink
Browse files Browse the repository at this point in the history
Fix bug #72663 - destroy broken object when unserializing
(cherry picked from commit 448c9be)
  • Loading branch information
smalyshev authored and weltling committed Aug 17, 2016
1 parent 8d7766a commit 20ce2fe
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 14 deletions.
26 changes: 26 additions & 0 deletions ext/standard/tests/strings/bug72663.phpt
@@ -0,0 +1,26 @@
--TEST--
Bug #72663: Create an Unexpected Object and Don't Invoke __wakeup() in Deserialization
--FILE--
<?php
class obj implements Serializable {
var $data;
function serialize() {
return serialize($this->data);
}
function unserialize($data) {
$this->data = unserialize($data);
}
}

$inner = 'a:1:{i:0;O:9:"Exception":2:{s:7:"'."\0".'*'."\0".'file";R:4;}';
$exploit = 'a:2:{i:0;C:3:"obj":'.strlen($inner).':{'.$inner.'}i:1;R:4;}';

$data = unserialize($exploit);
echo $data[1];
?>
DONE
--EXPECTF--
Notice: unserialize(): Unexpected end of serialized data in %sbug72663.php on line %d

Notice: unserialize(): Error at offset 46 of 47 bytes in %sbug72663.php on line %d
DONE
17 changes: 17 additions & 0 deletions ext/standard/tests/strings/bug72663_2.phpt
@@ -0,0 +1,17 @@
--TEST--
Bug #72663: Create an Unexpected Object and Don't Invoke __wakeup() in Deserialization
--FILE--
<?php

ini_set('session.serialize_handler', 'php_serialize');
session_start();
$sess = 'O:9:"Exception":2:{s:7:"'."\0".'*'."\0".'file";R:1;}';
session_decode($sess);
var_dump($_SESSION);
?>
DONE
--EXPECTF--
Notice: session_decode(): Unexpected end of serialized data in %sbug72663_2.php on line %d
array(0) {
}
DONE
29 changes: 15 additions & 14 deletions ext/standard/var_unserializer.c
@@ -1,4 +1,4 @@
/* Generated by re2c 0.13.5 */
/* Generated by re2c 0.13.7.5 */
#line 1 "ext/standard/var_unserializer.re"
/*
+----------------------------------------------------------------------+
Expand Down Expand Up @@ -687,7 +687,8 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
if (yybm[0+yych] & 128) {
goto yy20;
}
if (yych != ':') goto yy18;
if (yych <= '/') goto yy18;
if (yych >= ';') goto yy18;
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
Expand Down Expand Up @@ -836,7 +837,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)

return object_common2(UNSERIALIZE_PASSTHRU, elements);
}
#line 804 "ext/standard/var_unserializer.c"
#line 805 "ext/standard/var_unserializer.c"
yy25:
yych = *++YYCURSOR;
if (yych <= ',') {
Expand Down Expand Up @@ -868,7 +869,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
return object_common2(UNSERIALIZE_PASSTHRU,
object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
}
#line 836 "ext/standard/var_unserializer.c"
#line 837 "ext/standard/var_unserializer.c"
yy32:
yych = *++YYCURSOR;
if (yych == '+') goto yy33;
Expand Down Expand Up @@ -913,7 +914,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)

return finish_nested_data(UNSERIALIZE_PASSTHRU);
}
#line 881 "ext/standard/var_unserializer.c"
#line 882 "ext/standard/var_unserializer.c"
yy39:
yych = *++YYCURSOR;
if (yych == '+') goto yy40;
Expand Down Expand Up @@ -968,7 +969,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
ZVAL_STR(rval, str);
return 1;
}
#line 936 "ext/standard/var_unserializer.c"
#line 937 "ext/standard/var_unserializer.c"
yy46:
yych = *++YYCURSOR;
if (yych == '+') goto yy47;
Expand Down Expand Up @@ -1021,7 +1022,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
ZVAL_STRINGL(rval, str, len);
return 1;
}
#line 989 "ext/standard/var_unserializer.c"
#line 990 "ext/standard/var_unserializer.c"
yy53:
yych = *++YYCURSOR;
if (yych <= '/') {
Expand Down Expand Up @@ -1118,7 +1119,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL));
return 1;
}
#line 1086 "ext/standard/var_unserializer.c"
#line 1087 "ext/standard/var_unserializer.c"
yy65:
yych = *++YYCURSOR;
if (yych <= ',') {
Expand Down Expand Up @@ -1193,7 +1194,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)

return 1;
}
#line 1161 "ext/standard/var_unserializer.c"
#line 1162 "ext/standard/var_unserializer.c"
yy76:
yych = *++YYCURSOR;
if (yych == 'N') goto yy73;
Expand Down Expand Up @@ -1246,7 +1247,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
ZVAL_LONG(rval, parse_iv(start + 2));
return 1;
}
#line 1214 "ext/standard/var_unserializer.c"
#line 1215 "ext/standard/var_unserializer.c"
yy83:
yych = *++YYCURSOR;
if (yych <= '/') goto yy18;
Expand All @@ -1260,7 +1261,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
ZVAL_BOOL(rval, parse_iv(start + 2));
return 1;
}
#line 1228 "ext/standard/var_unserializer.c"
#line 1229 "ext/standard/var_unserializer.c"
yy87:
++YYCURSOR;
#line 573 "ext/standard/var_unserializer.re"
Expand All @@ -1269,7 +1270,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
ZVAL_NULL(rval);
return 1;
}
#line 1237 "ext/standard/var_unserializer.c"
#line 1238 "ext/standard/var_unserializer.c"
yy89:
yych = *++YYCURSOR;
if (yych <= ',') {
Expand Down Expand Up @@ -1317,7 +1318,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)

return 1;
}
#line 1285 "ext/standard/var_unserializer.c"
#line 1286 "ext/standard/var_unserializer.c"
yy95:
yych = *++YYCURSOR;
if (yych <= ',') {
Expand Down Expand Up @@ -1366,7 +1367,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)

return 1;
}
#line 1334 "ext/standard/var_unserializer.c"
#line 1335 "ext/standard/var_unserializer.c"
}
#line 886 "ext/standard/var_unserializer.re"

Expand Down

0 comments on commit 20ce2fe

Please sign in to comment.