Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit 2e62cee

Browse files
author
AJ Christensen
committed
Backport CVE-2014-8142 / bug #68594 to 5.3.29
1 parent babeca3 commit 2e62cee

File tree

4 files changed

+30
-33
lines changed

4 files changed

+30
-33
lines changed

NEWS

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3-
14 Aug 2014, PHP 5.3.29
3+
7 Jan 2015, PHP 5.3.29 (Security Release)
4+
- Core:
5+
. Fixed bug #68594 (Use after free vulnerability in unserialize()). (fujin)
46

7+
14 Aug 2014, PHP 5.3.29
58
- Core:
69
. Fixed bug #66127 (Segmentation fault with ArrayObject unset). (Stas)
710
. Fixed bug #67247 (spl_fixedarray_resize integer overflow). (Stas)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
Bug #68545 Use after free vulnerability in unserialize()
3+
--FILE--
4+
<?php
5+
for ($i=4; $i<100; $i++) {
6+
$m = new StdClass();
7+
8+
$u = array(1);
9+
10+
$m->aaa = array(1,2,&$u,4,5);
11+
$m->bbb = 1;
12+
$m->ccc = &$u;
13+
$m->ddd = str_repeat("A", $i);
14+
15+
$z = serialize($m);
16+
$z = str_replace("bbb", "aaa", $z);
17+
$y = unserialize($z);
18+
$z = serialize($y);
19+
}
20+
?>
21+
===DONE===
22+
--EXPECTF--
23+
===DONE===

ext/standard/var_unserializer.c

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/* Generated by re2c 0.13.5 on Wed Sep 28 15:40:15 2011 */
2-
#line 1 "ext/standard/var_unserializer.re"
32
/*
43
+----------------------------------------------------------------------+
54
| PHP Version 5 |
@@ -190,7 +189,6 @@ static char *unserialize_str(const unsigned char **p, size_t *len, size_t maxlen
190189
#define YYMARKER marker
191190

192191

193-
#line 198 "ext/standard/var_unserializer.re"
194192

195193

196194

@@ -403,7 +401,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
403401

404402

405403

406-
#line 407 "ext/standard/var_unserializer.c"
407404
{
408405
YYCTYPE yych;
409406
static const unsigned char yybm[] = {
@@ -463,9 +460,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
463460
yych = *(YYMARKER = ++YYCURSOR);
464461
if (yych == ':') goto yy95;
465462
yy3:
466-
#line 729 "ext/standard/var_unserializer.re"
467463
{ return 0; }
468-
#line 469 "ext/standard/var_unserializer.c"
469464
yy4:
470465
yych = *(YYMARKER = ++YYCURSOR);
471466
if (yych == ':') goto yy89;
@@ -508,13 +503,11 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
508503
goto yy3;
509504
yy14:
510505
++YYCURSOR;
511-
#line 723 "ext/standard/var_unserializer.re"
512506
{
513507
/* this is the case where we have less data than planned */
514508
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
515509
return 0; /* not sure if it should be 0 or 1 here? */
516510
}
517-
#line 518 "ext/standard/var_unserializer.c"
518511
yy16:
519512
yych = *++YYCURSOR;
520513
goto yy3;
@@ -544,7 +537,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
544537
yych = *++YYCURSOR;
545538
if (yych != '"') goto yy18;
546539
++YYCURSOR;
547-
#line 606 "ext/standard/var_unserializer.re"
548540
{
549541
size_t len, len2, len3, maxlen;
550542
long elements;
@@ -661,7 +653,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
661653

662654
return object_common2(UNSERIALIZE_PASSTHRU, elements);
663655
}
664-
#line 665 "ext/standard/var_unserializer.c"
665656
yy25:
666657
yych = *++YYCURSOR;
667658
if (yych <= ',') {
@@ -686,15 +677,13 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
686677
yych = *++YYCURSOR;
687678
if (yych != '"') goto yy18;
688679
++YYCURSOR;
689-
#line 598 "ext/standard/var_unserializer.re"
690680
{
691681

692682
INIT_PZVAL(*rval);
693683

694684
return object_common2(UNSERIALIZE_PASSTHRU,
695685
object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
696686
}
697-
#line 698 "ext/standard/var_unserializer.c"
698687
yy32:
699688
yych = *++YYCURSOR;
700689
if (yych == '+') goto yy33;
@@ -715,7 +704,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
715704
yych = *++YYCURSOR;
716705
if (yych != '{') goto yy18;
717706
++YYCURSOR;
718-
#line 578 "ext/standard/var_unserializer.re"
719707
{
720708
long elements = parse_iv(start + 2);
721709
/* use iv() not uiv() in order to check data range */
@@ -735,7 +723,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
735723

736724
return finish_nested_data(UNSERIALIZE_PASSTHRU);
737725
}
738-
#line 739 "ext/standard/var_unserializer.c"
739726
yy39:
740727
yych = *++YYCURSOR;
741728
if (yych == '+') goto yy40;
@@ -756,7 +743,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
756743
yych = *++YYCURSOR;
757744
if (yych != '"') goto yy18;
758745
++YYCURSOR;
759-
#line 549 "ext/standard/var_unserializer.re"
760746
{
761747
size_t len, maxlen;
762748
char *str;
@@ -785,7 +771,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
785771
ZVAL_STRINGL(*rval, str, len, 0);
786772
return 1;
787773
}
788-
#line 789 "ext/standard/var_unserializer.c"
789774
yy46:
790775
yych = *++YYCURSOR;
791776
if (yych == '+') goto yy47;
@@ -806,7 +791,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
806791
yych = *++YYCURSOR;
807792
if (yych != '"') goto yy18;
808793
++YYCURSOR;
809-
#line 521 "ext/standard/var_unserializer.re"
810794
{
811795
size_t len, maxlen;
812796
char *str;
@@ -834,7 +818,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
834818
ZVAL_STRINGL(*rval, str, len, 1);
835819
return 1;
836820
}
837-
#line 838 "ext/standard/var_unserializer.c"
838821
yy53:
839822
yych = *++YYCURSOR;
840823
if (yych <= '/') {
@@ -922,7 +905,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
922905
}
923906
yy63:
924907
++YYCURSOR;
925-
#line 511 "ext/standard/var_unserializer.re"
926908
{
927909
#if SIZEOF_LONG == 4
928910
use_double:
@@ -932,7 +914,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
932914
ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
933915
return 1;
934916
}
935-
#line 936 "ext/standard/var_unserializer.c"
936917
yy65:
937918
yych = *++YYCURSOR;
938919
if (yych <= ',') {
@@ -991,7 +972,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
991972
yych = *++YYCURSOR;
992973
if (yych != ';') goto yy18;
993974
++YYCURSOR;
994-
#line 496 "ext/standard/var_unserializer.re"
995975
{
996976
*p = YYCURSOR;
997977
INIT_PZVAL(*rval);
@@ -1006,7 +986,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
1006986

1007987
return 1;
1008988
}
1009-
#line 1010 "ext/standard/var_unserializer.c"
1010989
yy76:
1011990
yych = *++YYCURSOR;
1012991
if (yych == 'N') goto yy73;
@@ -1033,7 +1012,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
10331012
if (yych <= '9') goto yy79;
10341013
if (yych != ';') goto yy18;
10351014
++YYCURSOR;
1036-
#line 469 "ext/standard/var_unserializer.re"
10371015
{
10381016
#if SIZEOF_LONG == 4
10391017
int digits = YYCURSOR - start - 3;
@@ -1060,32 +1038,27 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
10601038
ZVAL_LONG(*rval, parse_iv(start + 2));
10611039
return 1;
10621040
}
1063-
#line 1064 "ext/standard/var_unserializer.c"
10641041
yy83:
10651042
yych = *++YYCURSOR;
10661043
if (yych <= '/') goto yy18;
10671044
if (yych >= '2') goto yy18;
10681045
yych = *++YYCURSOR;
10691046
if (yych != ';') goto yy18;
10701047
++YYCURSOR;
1071-
#line 462 "ext/standard/var_unserializer.re"
10721048
{
10731049
*p = YYCURSOR;
10741050
INIT_PZVAL(*rval);
10751051
ZVAL_BOOL(*rval, parse_iv(start + 2));
10761052
return 1;
10771053
}
1078-
#line 1079 "ext/standard/var_unserializer.c"
10791054
yy87:
10801055
++YYCURSOR;
1081-
#line 455 "ext/standard/var_unserializer.re"
10821056
{
10831057
*p = YYCURSOR;
10841058
INIT_PZVAL(*rval);
10851059
ZVAL_NULL(*rval);
10861060
return 1;
10871061
}
1088-
#line 1089 "ext/standard/var_unserializer.c"
10891062
yy89:
10901063
yych = *++YYCURSOR;
10911064
if (yych <= ',') {
@@ -1108,7 +1081,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
11081081
if (yych <= '9') goto yy91;
11091082
if (yych != ';') goto yy18;
11101083
++YYCURSOR;
1111-
#line 432 "ext/standard/var_unserializer.re"
11121084
{
11131085
long id;
11141086

@@ -1131,7 +1103,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
11311103

11321104
return 1;
11331105
}
1134-
#line 1135 "ext/standard/var_unserializer.c"
11351106
yy95:
11361107
yych = *++YYCURSOR;
11371108
if (yych <= ',') {
@@ -1154,7 +1125,6 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
11541125
if (yych <= '9') goto yy97;
11551126
if (yych != ';') goto yy18;
11561127
++YYCURSOR;
1157-
#line 411 "ext/standard/var_unserializer.re"
11581128
{
11591129
long id;
11601130

@@ -1175,9 +1145,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
11751145

11761146
return 1;
11771147
}
1178-
#line 1179 "ext/standard/var_unserializer.c"
11791148
}
1180-
#line 731 "ext/standard/var_unserializer.re"
11811149

11821150

11831151
return 0;

ext/standard/var_unserializer.re

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,9 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long
304304
} else {
305305
/* object properties should include no integers */
306306
convert_to_string(key);
307+
if (zend_symtable_find(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, (void **)&old_data)==SUCCESS) {
308+
var_push_dtor(var_hash, old_data);
309+
}
307310
zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data,
308311
sizeof data, NULL);
309312
}

0 commit comments

Comments
 (0)