summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2016-08-02 01:08:42 -0700
committerAnatol Belski <ab@php.net>2016-08-17 13:59:18 +0200
commit20ce2fe8e3c211a42fee05a461a5881be9a8790e (patch)
tree023164d83844b96fefd609d282cacdbf9a1bbbd1
parent8d7766a948999b990dbd13f96fa845a26d6f8f66 (diff)
downloadphp-git-20ce2fe8e3c211a42fee05a461a5881be9a8790e.tar.gz
Fix bug #72663 - destroy broken object when unserializing
(cherry picked from commit 448c9be157f4147e121f1a2a524536c75c9c6059)
-rw-r--r--ext/standard/tests/strings/bug72663.phpt26
-rw-r--r--ext/standard/tests/strings/bug72663_2.phpt17
-rw-r--r--ext/standard/var_unserializer.c29
3 files changed, 58 insertions, 14 deletions
diff --git a/ext/standard/tests/strings/bug72663.phpt b/ext/standard/tests/strings/bug72663.phpt
new file mode 100644
index 0000000000..e61f939d4d
--- /dev/null
+++ b/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 \ No newline at end of file
diff --git a/ext/standard/tests/strings/bug72663_2.phpt b/ext/standard/tests/strings/bug72663_2.phpt
new file mode 100644
index 0000000000..ac605e9fd2
--- /dev/null
+++ b/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 \ No newline at end of file
diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
index 4f2a1fd403..6b33d84bd2 100644
--- a/ext/standard/var_unserializer.c
+++ b/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"
/*
+----------------------------------------------------------------------+
@@ -687,7 +687,8 @@ yy20:
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;
@@ -836,7 +837,7 @@ yy20:
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 <= ',') {
@@ -868,7 +869,7 @@ yy27:
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;
@@ -913,7 +914,7 @@ yy34:
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;
@@ -968,7 +969,7 @@ yy41:
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;
@@ -1021,7 +1022,7 @@ yy48:
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 <= '/') {
@@ -1118,7 +1119,7 @@ use_double:
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 <= ',') {
@@ -1193,7 +1194,7 @@ yy73:
return 1;
}
-#line 1161 "ext/standard/var_unserializer.c"
+#line 1162 "ext/standard/var_unserializer.c"
yy76:
yych = *++YYCURSOR;
if (yych == 'N') goto yy73;
@@ -1246,7 +1247,7 @@ yy79:
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;
@@ -1260,7 +1261,7 @@ yy83:
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"
@@ -1269,7 +1270,7 @@ yy87:
ZVAL_NULL(rval);
return 1;
}
-#line 1237 "ext/standard/var_unserializer.c"
+#line 1238 "ext/standard/var_unserializer.c"
yy89:
yych = *++YYCURSOR;
if (yych <= ',') {
@@ -1317,7 +1318,7 @@ yy91:
return 1;
}
-#line 1285 "ext/standard/var_unserializer.c"
+#line 1286 "ext/standard/var_unserializer.c"
yy95:
yych = *++YYCURSOR;
if (yych <= ',') {
@@ -1366,7 +1367,7 @@ yy97:
return 1;
}
-#line 1334 "ext/standard/var_unserializer.c"
+#line 1335 "ext/standard/var_unserializer.c"
}
#line 886 "ext/standard/var_unserializer.re"