Skip to content

Commit 6a7cc8f

Browse files
committed
Fix bug #73052 - Memory Corruption in During Deserialized-object Destruction
1 parent 7381d4c commit 6a7cc8f

File tree

4 files changed

+51
-31
lines changed

4 files changed

+51
-31
lines changed

Diff for: Zend/zend_objects_API.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ ZEND_API void zend_object_store_ctor_failed(zval *zobject TSRMLS_DC)
307307
zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
308308
zend_object_store_bucket *obj_bucket = &EG(objects_store).object_buckets[handle];
309309

310-
obj_bucket->bucket.obj.handlers = Z_OBJ_HT_P(zobject);;
310+
obj_bucket->bucket.obj.handlers = Z_OBJ_HT_P(zobject);
311311
obj_bucket->destructor_called = 1;
312312
}
313313

Diff for: ext/standard/tests/serialize/bug73052.phpt

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Bug #73052: Memory Corruption in During Deserialized-object Destruction
3+
--FILE--
4+
<?php
5+
6+
class obj {
7+
var $ryat;
8+
public function __destruct() {
9+
$this->ryat = null;
10+
}
11+
}
12+
13+
$poc = 'O:3:"obj":1:{';
14+
var_dump(unserialize($poc));
15+
?>
16+
--EXPECTF--
17+
Notice: unserialize(): Error at offset 13 of 13 bytes in %sbug73052.php on line %d
18+
bool(false)

Diff for: ext/standard/var_unserializer.c

+31-30
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
437437
/* We've got partially constructed object on our hands here. Wipe it. */
438438
if(Z_TYPE_PP(rval) == IS_OBJECT) {
439439
zend_hash_clean(Z_OBJPROP_PP(rval));
440+
zend_object_store_ctor_failed(*rval TSRMLS_CC);
440441
}
441442
ZVAL_NULL(*rval);
442443
return 0;
@@ -491,7 +492,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
491492

492493

493494

494-
#line 495 "ext/standard/var_unserializer.c"
495+
#line 496 "ext/standard/var_unserializer.c"
495496
{
496497
YYCTYPE yych;
497498
static const unsigned char yybm[] = {
@@ -551,9 +552,9 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
551552
yych = *(YYMARKER = ++YYCURSOR);
552553
if (yych == ':') goto yy95;
553554
yy3:
554-
#line 860 "ext/standard/var_unserializer.re"
555+
#line 861 "ext/standard/var_unserializer.re"
555556
{ return 0; }
556-
#line 557 "ext/standard/var_unserializer.c"
557+
#line 558 "ext/standard/var_unserializer.c"
557558
yy4:
558559
yych = *(YYMARKER = ++YYCURSOR);
559560
if (yych == ':') goto yy89;
@@ -596,13 +597,13 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
596597
goto yy3;
597598
yy14:
598599
++YYCURSOR;
599-
#line 854 "ext/standard/var_unserializer.re"
600+
#line 855 "ext/standard/var_unserializer.re"
600601
{
601602
/* this is the case where we have less data than planned */
602603
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
603604
return 0; /* not sure if it should be 0 or 1 here? */
604605
}
605-
#line 606 "ext/standard/var_unserializer.c"
606+
#line 607 "ext/standard/var_unserializer.c"
606607
yy16:
607608
yych = *++YYCURSOR;
608609
goto yy3;
@@ -633,7 +634,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
633634
yych = *++YYCURSOR;
634635
if (yych != '"') goto yy18;
635636
++YYCURSOR;
636-
#line 707 "ext/standard/var_unserializer.re"
637+
#line 708 "ext/standard/var_unserializer.re"
637638
{
638639
size_t len, len2, len3, maxlen;
639640
long elements;
@@ -780,7 +781,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
780781

781782
return object_common2(UNSERIALIZE_PASSTHRU, elements);
782783
}
783-
#line 784 "ext/standard/var_unserializer.c"
784+
#line 785 "ext/standard/var_unserializer.c"
784785
yy25:
785786
yych = *++YYCURSOR;
786787
if (yych <= ',') {
@@ -805,7 +806,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
805806
yych = *++YYCURSOR;
806807
if (yych != '"') goto yy18;
807808
++YYCURSOR;
808-
#line 698 "ext/standard/var_unserializer.re"
809+
#line 699 "ext/standard/var_unserializer.re"
809810
{
810811
if (!var_hash) return 0;
811812

@@ -814,7 +815,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
814815
return object_common2(UNSERIALIZE_PASSTHRU,
815816
object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
816817
}
817-
#line 818 "ext/standard/var_unserializer.c"
818+
#line 819 "ext/standard/var_unserializer.c"
818819
yy32:
819820
yych = *++YYCURSOR;
820821
if (yych == '+') goto yy33;
@@ -835,7 +836,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
835836
yych = *++YYCURSOR;
836837
if (yych != '{') goto yy18;
837838
++YYCURSOR;
838-
#line 677 "ext/standard/var_unserializer.re"
839+
#line 678 "ext/standard/var_unserializer.re"
839840
{
840841
long elements = parse_iv(start + 2);
841842
/* use iv() not uiv() in order to check data range */
@@ -856,7 +857,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
856857

857858
return finish_nested_data(UNSERIALIZE_PASSTHRU);
858859
}
859-
#line 860 "ext/standard/var_unserializer.c"
860+
#line 861 "ext/standard/var_unserializer.c"
860861
yy39:
861862
yych = *++YYCURSOR;
862863
if (yych == '+') goto yy40;
@@ -877,7 +878,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
877878
yych = *++YYCURSOR;
878879
if (yych != '"') goto yy18;
879880
++YYCURSOR;
880-
#line 642 "ext/standard/var_unserializer.re"
881+
#line 643 "ext/standard/var_unserializer.re"
881882
{
882883
size_t len, maxlen;
883884
char *str;
@@ -912,7 +913,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
912913
ZVAL_STRINGL(*rval, str, len, 0);
913914
return 1;
914915
}
915-
#line 916 "ext/standard/var_unserializer.c"
916+
#line 917 "ext/standard/var_unserializer.c"
916917
yy46:
917918
yych = *++YYCURSOR;
918919
if (yych == '+') goto yy47;
@@ -933,7 +934,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
933934
yych = *++YYCURSOR;
934935
if (yych != '"') goto yy18;
935936
++YYCURSOR;
936-
#line 609 "ext/standard/var_unserializer.re"
937+
#line 610 "ext/standard/var_unserializer.re"
937938
{
938939
size_t len, maxlen;
939940
char *str;
@@ -966,7 +967,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
966967
ZVAL_STRINGL(*rval, str, len, 1);
967968
return 1;
968969
}
969-
#line 970 "ext/standard/var_unserializer.c"
970+
#line 971 "ext/standard/var_unserializer.c"
970971
yy53:
971972
yych = *++YYCURSOR;
972973
if (yych <= '/') {
@@ -1054,7 +1055,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
10541055
}
10551056
yy63:
10561057
++YYCURSOR;
1057-
#line 599 "ext/standard/var_unserializer.re"
1058+
#line 600 "ext/standard/var_unserializer.re"
10581059
{
10591060
#if SIZEOF_LONG == 4
10601061
use_double:
@@ -1064,7 +1065,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
10641065
ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
10651066
return 1;
10661067
}
1067-
#line 1068 "ext/standard/var_unserializer.c"
1068+
#line 1069 "ext/standard/var_unserializer.c"
10681069
yy65:
10691070
yych = *++YYCURSOR;
10701071
if (yych <= ',') {
@@ -1123,7 +1124,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
11231124
yych = *++YYCURSOR;
11241125
if (yych != ';') goto yy18;
11251126
++YYCURSOR;
1126-
#line 584 "ext/standard/var_unserializer.re"
1127+
#line 585 "ext/standard/var_unserializer.re"
11271128
{
11281129
*p = YYCURSOR;
11291130
INIT_PZVAL(*rval);
@@ -1138,7 +1139,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
11381139

11391140
return 1;
11401141
}
1141-
#line 1142 "ext/standard/var_unserializer.c"
1142+
#line 1143 "ext/standard/var_unserializer.c"
11421143
yy76:
11431144
yych = *++YYCURSOR;
11441145
if (yych == 'N') goto yy73;
@@ -1165,7 +1166,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
11651166
if (yych <= '9') goto yy79;
11661167
if (yych != ';') goto yy18;
11671168
++YYCURSOR;
1168-
#line 557 "ext/standard/var_unserializer.re"
1169+
#line 558 "ext/standard/var_unserializer.re"
11691170
{
11701171
#if SIZEOF_LONG == 4
11711172
int digits = YYCURSOR - start - 3;
@@ -1192,32 +1193,32 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
11921193
ZVAL_LONG(*rval, parse_iv(start + 2));
11931194
return 1;
11941195
}
1195-
#line 1196 "ext/standard/var_unserializer.c"
1196+
#line 1197 "ext/standard/var_unserializer.c"
11961197
yy83:
11971198
yych = *++YYCURSOR;
11981199
if (yych <= '/') goto yy18;
11991200
if (yych >= '2') goto yy18;
12001201
yych = *++YYCURSOR;
12011202
if (yych != ';') goto yy18;
12021203
++YYCURSOR;
1203-
#line 550 "ext/standard/var_unserializer.re"
1204+
#line 551 "ext/standard/var_unserializer.re"
12041205
{
12051206
*p = YYCURSOR;
12061207
INIT_PZVAL(*rval);
12071208
ZVAL_BOOL(*rval, parse_iv(start + 2));
12081209
return 1;
12091210
}
1210-
#line 1211 "ext/standard/var_unserializer.c"
1211+
#line 1212 "ext/standard/var_unserializer.c"
12111212
yy87:
12121213
++YYCURSOR;
1213-
#line 543 "ext/standard/var_unserializer.re"
1214+
#line 544 "ext/standard/var_unserializer.re"
12141215
{
12151216
*p = YYCURSOR;
12161217
INIT_PZVAL(*rval);
12171218
ZVAL_NULL(*rval);
12181219
return 1;
12191220
}
1220-
#line 1221 "ext/standard/var_unserializer.c"
1221+
#line 1222 "ext/standard/var_unserializer.c"
12211222
yy89:
12221223
yych = *++YYCURSOR;
12231224
if (yych <= ',') {
@@ -1240,7 +1241,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
12401241
if (yych <= '9') goto yy91;
12411242
if (yych != ';') goto yy18;
12421243
++YYCURSOR;
1243-
#line 520 "ext/standard/var_unserializer.re"
1244+
#line 521 "ext/standard/var_unserializer.re"
12441245
{
12451246
long id;
12461247

@@ -1263,7 +1264,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
12631264

12641265
return 1;
12651266
}
1266-
#line 1267 "ext/standard/var_unserializer.c"
1267+
#line 1268 "ext/standard/var_unserializer.c"
12671268
yy95:
12681269
yych = *++YYCURSOR;
12691270
if (yych <= ',') {
@@ -1286,7 +1287,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
12861287
if (yych <= '9') goto yy97;
12871288
if (yych != ';') goto yy18;
12881289
++YYCURSOR;
1289-
#line 499 "ext/standard/var_unserializer.re"
1290+
#line 500 "ext/standard/var_unserializer.re"
12901291
{
12911292
long id;
12921293

@@ -1307,9 +1308,9 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
13071308

13081309
return 1;
13091310
}
1310-
#line 1311 "ext/standard/var_unserializer.c"
1311+
#line 1312 "ext/standard/var_unserializer.c"
13111312
}
1312-
#line 862 "ext/standard/var_unserializer.re"
1313+
#line 863 "ext/standard/var_unserializer.re"
13131314

13141315

13151316
return 0;

Diff for: ext/standard/var_unserializer.re

+1
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
441441
/* We've got partially constructed object on our hands here. Wipe it. */
442442
if(Z_TYPE_PP(rval) == IS_OBJECT) {
443443
zend_hash_clean(Z_OBJPROP_PP(rval));
444+
zend_object_store_ctor_failed(*rval TSRMLS_CC);
444445
}
445446
ZVAL_NULL(*rval);
446447
return 0;

0 commit comments

Comments
 (0)