diff options
author | Stanislav Malyshev <stas@php.net> | 2016-08-02 01:08:42 -0700 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2016-08-17 13:59:18 +0200 |
commit | 20ce2fe8e3c211a42fee05a461a5881be9a8790e (patch) | |
tree | 023164d83844b96fefd609d282cacdbf9a1bbbd1 | |
parent | 8d7766a948999b990dbd13f96fa845a26d6f8f66 (diff) | |
download | php-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.phpt | 26 | ||||
-rw-r--r-- | ext/standard/tests/strings/bug72663_2.phpt | 17 | ||||
-rw-r--r-- | ext/standard/var_unserializer.c | 29 |
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" |