Skip to content

Commit 20ce2fe

Browse files
smalyshevweltling
authored andcommitted
Fix bug #72663 - destroy broken object when unserializing
(cherry picked from commit 448c9be)
1 parent 8d7766a commit 20ce2fe

File tree

3 files changed

+58
-14
lines changed

3 files changed

+58
-14
lines changed

Diff for: ext/standard/tests/strings/bug72663.phpt

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
Bug #72663: Create an Unexpected Object and Don't Invoke __wakeup() in Deserialization
3+
--FILE--
4+
<?php
5+
class obj implements Serializable {
6+
var $data;
7+
function serialize() {
8+
return serialize($this->data);
9+
}
10+
function unserialize($data) {
11+
$this->data = unserialize($data);
12+
}
13+
}
14+
15+
$inner = 'a:1:{i:0;O:9:"Exception":2:{s:7:"'."\0".'*'."\0".'file";R:4;}';
16+
$exploit = 'a:2:{i:0;C:3:"obj":'.strlen($inner).':{'.$inner.'}i:1;R:4;}';
17+
18+
$data = unserialize($exploit);
19+
echo $data[1];
20+
?>
21+
DONE
22+
--EXPECTF--
23+
Notice: unserialize(): Unexpected end of serialized data in %sbug72663.php on line %d
24+
25+
Notice: unserialize(): Error at offset 46 of 47 bytes in %sbug72663.php on line %d
26+
DONE

Diff for: ext/standard/tests/strings/bug72663_2.phpt

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Bug #72663: Create an Unexpected Object and Don't Invoke __wakeup() in Deserialization
3+
--FILE--
4+
<?php
5+
6+
ini_set('session.serialize_handler', 'php_serialize');
7+
session_start();
8+
$sess = 'O:9:"Exception":2:{s:7:"'."\0".'*'."\0".'file";R:1;}';
9+
session_decode($sess);
10+
var_dump($_SESSION);
11+
?>
12+
DONE
13+
--EXPECTF--
14+
Notice: session_decode(): Unexpected end of serialized data in %sbug72663_2.php on line %d
15+
array(0) {
16+
}
17+
DONE

Diff for: ext/standard/var_unserializer.c

+15-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Generated by re2c 0.13.5 */
1+
/* Generated by re2c 0.13.7.5 */
22
#line 1 "ext/standard/var_unserializer.re"
33
/*
44
+----------------------------------------------------------------------+
@@ -687,7 +687,8 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
687687
if (yybm[0+yych] & 128) {
688688
goto yy20;
689689
}
690-
if (yych != ':') goto yy18;
690+
if (yych <= '/') goto yy18;
691+
if (yych >= ';') goto yy18;
691692
yych = *++YYCURSOR;
692693
if (yych != '"') goto yy18;
693694
++YYCURSOR;
@@ -836,7 +837,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
836837

837838
return object_common2(UNSERIALIZE_PASSTHRU, elements);
838839
}
839-
#line 804 "ext/standard/var_unserializer.c"
840+
#line 805 "ext/standard/var_unserializer.c"
840841
yy25:
841842
yych = *++YYCURSOR;
842843
if (yych <= ',') {
@@ -868,7 +869,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
868869
return object_common2(UNSERIALIZE_PASSTHRU,
869870
object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
870871
}
871-
#line 836 "ext/standard/var_unserializer.c"
872+
#line 837 "ext/standard/var_unserializer.c"
872873
yy32:
873874
yych = *++YYCURSOR;
874875
if (yych == '+') goto yy33;
@@ -913,7 +914,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
913914

914915
return finish_nested_data(UNSERIALIZE_PASSTHRU);
915916
}
916-
#line 881 "ext/standard/var_unserializer.c"
917+
#line 882 "ext/standard/var_unserializer.c"
917918
yy39:
918919
yych = *++YYCURSOR;
919920
if (yych == '+') goto yy40;
@@ -968,7 +969,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
968969
ZVAL_STR(rval, str);
969970
return 1;
970971
}
971-
#line 936 "ext/standard/var_unserializer.c"
972+
#line 937 "ext/standard/var_unserializer.c"
972973
yy46:
973974
yych = *++YYCURSOR;
974975
if (yych == '+') goto yy47;
@@ -1021,7 +1022,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
10211022
ZVAL_STRINGL(rval, str, len);
10221023
return 1;
10231024
}
1024-
#line 989 "ext/standard/var_unserializer.c"
1025+
#line 990 "ext/standard/var_unserializer.c"
10251026
yy53:
10261027
yych = *++YYCURSOR;
10271028
if (yych <= '/') {
@@ -1118,7 +1119,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
11181119
ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL));
11191120
return 1;
11201121
}
1121-
#line 1086 "ext/standard/var_unserializer.c"
1122+
#line 1087 "ext/standard/var_unserializer.c"
11221123
yy65:
11231124
yych = *++YYCURSOR;
11241125
if (yych <= ',') {
@@ -1193,7 +1194,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
11931194

11941195
return 1;
11951196
}
1196-
#line 1161 "ext/standard/var_unserializer.c"
1197+
#line 1162 "ext/standard/var_unserializer.c"
11971198
yy76:
11981199
yych = *++YYCURSOR;
11991200
if (yych == 'N') goto yy73;
@@ -1246,7 +1247,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
12461247
ZVAL_LONG(rval, parse_iv(start + 2));
12471248
return 1;
12481249
}
1249-
#line 1214 "ext/standard/var_unserializer.c"
1250+
#line 1215 "ext/standard/var_unserializer.c"
12501251
yy83:
12511252
yych = *++YYCURSOR;
12521253
if (yych <= '/') goto yy18;
@@ -1260,7 +1261,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
12601261
ZVAL_BOOL(rval, parse_iv(start + 2));
12611262
return 1;
12621263
}
1263-
#line 1228 "ext/standard/var_unserializer.c"
1264+
#line 1229 "ext/standard/var_unserializer.c"
12641265
yy87:
12651266
++YYCURSOR;
12661267
#line 573 "ext/standard/var_unserializer.re"
@@ -1269,7 +1270,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
12691270
ZVAL_NULL(rval);
12701271
return 1;
12711272
}
1272-
#line 1237 "ext/standard/var_unserializer.c"
1273+
#line 1238 "ext/standard/var_unserializer.c"
12731274
yy89:
12741275
yych = *++YYCURSOR;
12751276
if (yych <= ',') {
@@ -1317,7 +1318,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
13171318

13181319
return 1;
13191320
}
1320-
#line 1285 "ext/standard/var_unserializer.c"
1321+
#line 1286 "ext/standard/var_unserializer.c"
13211322
yy95:
13221323
yych = *++YYCURSOR;
13231324
if (yych <= ',') {
@@ -1366,7 +1367,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
13661367

13671368
return 1;
13681369
}
1369-
#line 1334 "ext/standard/var_unserializer.c"
1370+
#line 1335 "ext/standard/var_unserializer.c"
13701371
}
13711372
#line 886 "ext/standard/var_unserializer.re"
13721373

0 commit comments

Comments
 (0)