-
-
Save anonymous/25caa2f05e6f556ab4c0fe1684763961 to your computer and use it in GitHub Desktop.
Patch for 73052
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 9ed121184869100b721cf744fa2326715da0889c | |
Author: Stanislav Malyshev <stas@php.net> | |
Date: Sun Sep 11 21:19:29 2016 -0700 | |
Fix bug #73052 - Memory Corruption in During Deserialized-object Destruction | |
diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c | |
index 56c47b7..cdc0b69 100644 | |
--- a/Zend/zend_objects_API.c | |
+++ b/Zend/zend_objects_API.c | |
@@ -307,7 +307,7 @@ ZEND_API void zend_object_store_ctor_failed(zval *zobject TSRMLS_DC) | |
zend_object_handle handle = Z_OBJ_HANDLE_P(zobject); | |
zend_object_store_bucket *obj_bucket = &EG(objects_store).object_buckets[handle]; | |
- obj_bucket->bucket.obj.handlers = Z_OBJ_HT_P(zobject);; | |
+ obj_bucket->bucket.obj.handlers = Z_OBJ_HT_P(zobject); | |
obj_bucket->destructor_called = 1; | |
} | |
diff --git a/ext/standard/tests/serialize/bug73052.phpt b/ext/standard/tests/serialize/bug73052.phpt | |
new file mode 100644 | |
index 0000000..63b484b | |
--- /dev/null | |
+++ b/ext/standard/tests/serialize/bug73052.phpt | |
@@ -0,0 +1,18 @@ | |
+--TEST-- | |
+Bug #73052: Memory Corruption in During Deserialized-object Destruction | |
+--FILE-- | |
+<?php | |
+ | |
+class obj { | |
+ var $ryat; | |
+ public function __destruct() { | |
+ $this->ryat = null; | |
+ } | |
+} | |
+ | |
+$poc = 'O:3:"obj":1:{'; | |
+var_dump(unserialize($poc)); | |
+?> | |
+--EXPECTF-- | |
+Notice: unserialize(): Error at offset 13 of 13 bytes in %sbug73052.php on line %d | |
+bool(false) | |
diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c | |
index c8e6f8a..5491492 100644 | |
--- a/ext/standard/var_unserializer.c | |
+++ b/ext/standard/var_unserializer.c | |
@@ -437,6 +437,7 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements) | |
/* We've got partially constructed object on our hands here. Wipe it. */ | |
if(Z_TYPE_PP(rval) == IS_OBJECT) { | |
zend_hash_clean(Z_OBJPROP_PP(rval)); | |
+ zend_object_store_ctor_failed(*rval TSRMLS_CC); | |
} | |
ZVAL_NULL(*rval); | |
return 0; | |
@@ -491,7 +492,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) | |
-#line 495 "ext/standard/var_unserializer.c" | |
+#line 496 "ext/standard/var_unserializer.c" | |
{ | |
YYCTYPE yych; | |
static const unsigned char yybm[] = { | |
@@ -551,9 +552,9 @@ yy2: | |
yych = *(YYMARKER = ++YYCURSOR); | |
if (yych == ':') goto yy95; | |
yy3: | |
-#line 860 "ext/standard/var_unserializer.re" | |
+#line 861 "ext/standard/var_unserializer.re" | |
{ return 0; } | |
-#line 557 "ext/standard/var_unserializer.c" | |
+#line 558 "ext/standard/var_unserializer.c" | |
yy4: | |
yych = *(YYMARKER = ++YYCURSOR); | |
if (yych == ':') goto yy89; | |
@@ -596,13 +597,13 @@ yy13: | |
goto yy3; | |
yy14: | |
++YYCURSOR; | |
-#line 854 "ext/standard/var_unserializer.re" | |
+#line 855 "ext/standard/var_unserializer.re" | |
{ | |
/* this is the case where we have less data than planned */ | |
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data"); | |
return 0; /* not sure if it should be 0 or 1 here? */ | |
} | |
-#line 606 "ext/standard/var_unserializer.c" | |
+#line 607 "ext/standard/var_unserializer.c" | |
yy16: | |
yych = *++YYCURSOR; | |
goto yy3; | |
@@ -633,7 +634,7 @@ yy20: | |
yych = *++YYCURSOR; | |
if (yych != '"') goto yy18; | |
++YYCURSOR; | |
-#line 707 "ext/standard/var_unserializer.re" | |
+#line 708 "ext/standard/var_unserializer.re" | |
{ | |
size_t len, len2, len3, maxlen; | |
long elements; | |
@@ -780,7 +781,7 @@ yy20: | |
return object_common2(UNSERIALIZE_PASSTHRU, elements); | |
} | |
-#line 784 "ext/standard/var_unserializer.c" | |
+#line 785 "ext/standard/var_unserializer.c" | |
yy25: | |
yych = *++YYCURSOR; | |
if (yych <= ',') { | |
@@ -805,7 +806,7 @@ yy27: | |
yych = *++YYCURSOR; | |
if (yych != '"') goto yy18; | |
++YYCURSOR; | |
-#line 698 "ext/standard/var_unserializer.re" | |
+#line 699 "ext/standard/var_unserializer.re" | |
{ | |
if (!var_hash) return 0; | |
@@ -814,7 +815,7 @@ yy27: | |
return object_common2(UNSERIALIZE_PASSTHRU, | |
object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); | |
} | |
-#line 818 "ext/standard/var_unserializer.c" | |
+#line 819 "ext/standard/var_unserializer.c" | |
yy32: | |
yych = *++YYCURSOR; | |
if (yych == '+') goto yy33; | |
@@ -835,7 +836,7 @@ yy34: | |
yych = *++YYCURSOR; | |
if (yych != '{') goto yy18; | |
++YYCURSOR; | |
-#line 677 "ext/standard/var_unserializer.re" | |
+#line 678 "ext/standard/var_unserializer.re" | |
{ | |
long elements = parse_iv(start + 2); | |
/* use iv() not uiv() in order to check data range */ | |
@@ -856,7 +857,7 @@ yy34: | |
return finish_nested_data(UNSERIALIZE_PASSTHRU); | |
} | |
-#line 860 "ext/standard/var_unserializer.c" | |
+#line 861 "ext/standard/var_unserializer.c" | |
yy39: | |
yych = *++YYCURSOR; | |
if (yych == '+') goto yy40; | |
@@ -877,7 +878,7 @@ yy41: | |
yych = *++YYCURSOR; | |
if (yych != '"') goto yy18; | |
++YYCURSOR; | |
-#line 642 "ext/standard/var_unserializer.re" | |
+#line 643 "ext/standard/var_unserializer.re" | |
{ | |
size_t len, maxlen; | |
char *str; | |
@@ -912,7 +913,7 @@ yy41: | |
ZVAL_STRINGL(*rval, str, len, 0); | |
return 1; | |
} | |
-#line 916 "ext/standard/var_unserializer.c" | |
+#line 917 "ext/standard/var_unserializer.c" | |
yy46: | |
yych = *++YYCURSOR; | |
if (yych == '+') goto yy47; | |
@@ -933,7 +934,7 @@ yy48: | |
yych = *++YYCURSOR; | |
if (yych != '"') goto yy18; | |
++YYCURSOR; | |
-#line 609 "ext/standard/var_unserializer.re" | |
+#line 610 "ext/standard/var_unserializer.re" | |
{ | |
size_t len, maxlen; | |
char *str; | |
@@ -966,7 +967,7 @@ yy48: | |
ZVAL_STRINGL(*rval, str, len, 1); | |
return 1; | |
} | |
-#line 970 "ext/standard/var_unserializer.c" | |
+#line 971 "ext/standard/var_unserializer.c" | |
yy53: | |
yych = *++YYCURSOR; | |
if (yych <= '/') { | |
@@ -1054,7 +1055,7 @@ yy61: | |
} | |
yy63: | |
++YYCURSOR; | |
-#line 599 "ext/standard/var_unserializer.re" | |
+#line 600 "ext/standard/var_unserializer.re" | |
{ | |
#if SIZEOF_LONG == 4 | |
use_double: | |
@@ -1064,7 +1065,7 @@ use_double: | |
ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL)); | |
return 1; | |
} | |
-#line 1068 "ext/standard/var_unserializer.c" | |
+#line 1069 "ext/standard/var_unserializer.c" | |
yy65: | |
yych = *++YYCURSOR; | |
if (yych <= ',') { | |
@@ -1123,7 +1124,7 @@ yy73: | |
yych = *++YYCURSOR; | |
if (yych != ';') goto yy18; | |
++YYCURSOR; | |
-#line 584 "ext/standard/var_unserializer.re" | |
+#line 585 "ext/standard/var_unserializer.re" | |
{ | |
*p = YYCURSOR; | |
INIT_PZVAL(*rval); | |
@@ -1138,7 +1139,7 @@ yy73: | |
return 1; | |
} | |
-#line 1142 "ext/standard/var_unserializer.c" | |
+#line 1143 "ext/standard/var_unserializer.c" | |
yy76: | |
yych = *++YYCURSOR; | |
if (yych == 'N') goto yy73; | |
@@ -1165,7 +1166,7 @@ yy79: | |
if (yych <= '9') goto yy79; | |
if (yych != ';') goto yy18; | |
++YYCURSOR; | |
-#line 557 "ext/standard/var_unserializer.re" | |
+#line 558 "ext/standard/var_unserializer.re" | |
{ | |
#if SIZEOF_LONG == 4 | |
int digits = YYCURSOR - start - 3; | |
@@ -1192,7 +1193,7 @@ yy79: | |
ZVAL_LONG(*rval, parse_iv(start + 2)); | |
return 1; | |
} | |
-#line 1196 "ext/standard/var_unserializer.c" | |
+#line 1197 "ext/standard/var_unserializer.c" | |
yy83: | |
yych = *++YYCURSOR; | |
if (yych <= '/') goto yy18; | |
@@ -1200,24 +1201,24 @@ yy83: | |
yych = *++YYCURSOR; | |
if (yych != ';') goto yy18; | |
++YYCURSOR; | |
-#line 550 "ext/standard/var_unserializer.re" | |
+#line 551 "ext/standard/var_unserializer.re" | |
{ | |
*p = YYCURSOR; | |
INIT_PZVAL(*rval); | |
ZVAL_BOOL(*rval, parse_iv(start + 2)); | |
return 1; | |
} | |
-#line 1211 "ext/standard/var_unserializer.c" | |
+#line 1212 "ext/standard/var_unserializer.c" | |
yy87: | |
++YYCURSOR; | |
-#line 543 "ext/standard/var_unserializer.re" | |
+#line 544 "ext/standard/var_unserializer.re" | |
{ | |
*p = YYCURSOR; | |
INIT_PZVAL(*rval); | |
ZVAL_NULL(*rval); | |
return 1; | |
} | |
-#line 1221 "ext/standard/var_unserializer.c" | |
+#line 1222 "ext/standard/var_unserializer.c" | |
yy89: | |
yych = *++YYCURSOR; | |
if (yych <= ',') { | |
@@ -1240,7 +1241,7 @@ yy91: | |
if (yych <= '9') goto yy91; | |
if (yych != ';') goto yy18; | |
++YYCURSOR; | |
-#line 520 "ext/standard/var_unserializer.re" | |
+#line 521 "ext/standard/var_unserializer.re" | |
{ | |
long id; | |
@@ -1263,7 +1264,7 @@ yy91: | |
return 1; | |
} | |
-#line 1267 "ext/standard/var_unserializer.c" | |
+#line 1268 "ext/standard/var_unserializer.c" | |
yy95: | |
yych = *++YYCURSOR; | |
if (yych <= ',') { | |
@@ -1286,7 +1287,7 @@ yy97: | |
if (yych <= '9') goto yy97; | |
if (yych != ';') goto yy18; | |
++YYCURSOR; | |
-#line 499 "ext/standard/var_unserializer.re" | |
+#line 500 "ext/standard/var_unserializer.re" | |
{ | |
long id; | |
@@ -1307,9 +1308,9 @@ yy97: | |
return 1; | |
} | |
-#line 1311 "ext/standard/var_unserializer.c" | |
+#line 1312 "ext/standard/var_unserializer.c" | |
} | |
-#line 862 "ext/standard/var_unserializer.re" | |
+#line 863 "ext/standard/var_unserializer.re" | |
return 0; | |
diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re | |
index 11b93c5..ce84bf5 100644 | |
--- a/ext/standard/var_unserializer.re | |
+++ b/ext/standard/var_unserializer.re | |
@@ -441,6 +441,7 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements) | |
/* We've got partially constructed object on our hands here. Wipe it. */ | |
if(Z_TYPE_PP(rval) == IS_OBJECT) { | |
zend_hash_clean(Z_OBJPROP_PP(rval)); | |
+ zend_object_store_ctor_failed(*rval TSRMLS_CC); | |
} | |
ZVAL_NULL(*rval); | |
return 0; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment