My Alpine packages repository.
https://dryabzhinsky.noip.me/packages/en/alpinelinux-support/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
5.6 KiB
217 lines
5.6 KiB
From a7ddf7b792796da9636e474e0ce514c1b566c1a8 Mon Sep 17 00:00:00 2001 |
|
From: Lucas Kanashiro <kanashiro@debian.org> |
|
Date: Tue, 29 Aug 2017 17:32:01 -0300 |
|
Subject: [PATCH] Fix buffer over-read in finish_nested_data |
|
|
|
The finish_nested_data function in ext/standard/var_unserializer.re in |
|
PHP is prone to a buffer over-read while unserializing untrusted data. |
|
Exploitation of this issue can have an unspecified impact on the |
|
integrity of PHP. |
|
|
|
This is an adaptation of this upstream commit: 61ba5f84774938617f78d65c06e5933cff2d8af3 |
|
|
|
Fixes CVE-2017-12933 |
|
Bug: https://bugs.php.net/bug.php?id=74111 |
|
--- |
|
ext/standard/tests/serialize/bug25378.phpt | 2 +- |
|
ext/standard/var_unserializer.c | 41 +++++++++++++++--------------- |
|
ext/standard/var_unserializer.re | 11 ++++---- |
|
3 files changed, 26 insertions(+), 28 deletions(-) |
|
|
|
diff --git a/ext/standard/tests/serialize/bug25378.phpt b/ext/standard/tests/serialize/bug25378.phpt |
|
index e865b96e..e95a4270 100644 |
|
--- a/ext/standard/tests/serialize/bug25378.phpt |
|
+++ b/ext/standard/tests/serialize/bug25378.phpt |
|
@@ -42,7 +42,7 @@ bool(false) |
|
Notice: unserialize(): Error at offset 17 of 33 bytes in %sbug25378.php on line %d |
|
bool(false) |
|
|
|
-Notice: unserialize(): Error at offset 33 of 32 bytes in %sbug25378.php on line %d |
|
+Notice: unserialize(): Error at offset 32 of 32 bytes in %sbug25378.php on line %d |
|
bool(false) |
|
|
|
Notice: unserialize(): Error at offset 2 of 13 bytes in %sbug25378.php on line %d |
|
diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c |
|
index 22594ad5..0fba6130 100644 |
|
--- a/ext/standard/var_unserializer.c |
|
+++ b/ext/standard/var_unserializer.c |
|
@@ -407,13 +407,12 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long |
|
|
|
static inline int finish_nested_data(UNSERIALIZE_PARAMETER) |
|
{ |
|
- if (*((*p)++) == '}') |
|
- return 1; |
|
+ if (*p >= max || **p != '}') { |
|
+ return 0; |
|
+ } |
|
|
|
-#if SOMETHING_NEW_MIGHT_LEAD_TO_CRASH_ENABLE_IF_YOU_ARE_BRAVE |
|
- zval_ptr_dtor(rval); |
|
-#endif |
|
- return 0; |
|
+ (*p)++; |
|
+ return 1; |
|
} |
|
|
|
static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce) |
|
@@ -563,7 +562,7 @@ yy2: |
|
default: goto yy3; |
|
} |
|
yy3: |
|
-#line 901 "ext/standard/var_unserializer.re" |
|
+#line 900 "ext/standard/var_unserializer.re" |
|
{ return 0; } |
|
#line 569 "<stdout>" |
|
yy4: |
|
@@ -628,7 +627,7 @@ yy13: |
|
} |
|
yy14: |
|
++YYCURSOR; |
|
-#line 895 "ext/standard/var_unserializer.re" |
|
+#line 894 "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"); |
|
@@ -698,7 +697,7 @@ yy22: |
|
} |
|
yy23: |
|
++YYCURSOR; |
|
-#line 743 "ext/standard/var_unserializer.re" |
|
+#line 742 "ext/standard/var_unserializer.re" |
|
{ |
|
size_t len, len2, len3, maxlen; |
|
long elements; |
|
@@ -909,7 +908,7 @@ yy29: |
|
} |
|
yy30: |
|
++YYCURSOR; |
|
-#line 730 "ext/standard/var_unserializer.re" |
|
+#line 729 "ext/standard/var_unserializer.re" |
|
{ |
|
long elements; |
|
if (!var_hash) return 0; |
|
@@ -980,7 +979,7 @@ yy36: |
|
} |
|
yy37: |
|
++YYCURSOR; |
|
-#line 709 "ext/standard/var_unserializer.re" |
|
+#line 708 "ext/standard/var_unserializer.re" |
|
{ |
|
long elements = parse_iv(start + 2); |
|
/* use iv() not uiv() in order to check data range */ |
|
@@ -1059,7 +1058,7 @@ yy43: |
|
} |
|
yy44: |
|
++YYCURSOR; |
|
-#line 680 "ext/standard/var_unserializer.re" |
|
+#line 679 "ext/standard/var_unserializer.re" |
|
{ |
|
size_t len, maxlen; |
|
char *str; |
|
@@ -1146,7 +1145,7 @@ yy50: |
|
} |
|
yy51: |
|
++YYCURSOR; |
|
-#line 652 "ext/standard/var_unserializer.re" |
|
+#line 651 "ext/standard/var_unserializer.re" |
|
{ |
|
size_t len, maxlen; |
|
char *str; |
|
@@ -1298,7 +1297,7 @@ yy61: |
|
} |
|
yy63: |
|
++YYCURSOR; |
|
-#line 642 "ext/standard/var_unserializer.re" |
|
+#line 641 "ext/standard/var_unserializer.re" |
|
{ |
|
#if SIZEOF_LONG == 4 |
|
use_double: |
|
@@ -1410,7 +1409,7 @@ yy73: |
|
} |
|
yy74: |
|
++YYCURSOR; |
|
-#line 627 "ext/standard/var_unserializer.re" |
|
+#line 626 "ext/standard/var_unserializer.re" |
|
{ |
|
*p = YYCURSOR; |
|
INIT_PZVAL(*rval); |
|
@@ -1484,7 +1483,7 @@ yy79: |
|
} |
|
yy81: |
|
++YYCURSOR; |
|
-#line 600 "ext/standard/var_unserializer.re" |
|
+#line 599 "ext/standard/var_unserializer.re" |
|
{ |
|
#if SIZEOF_LONG == 4 |
|
int digits = YYCURSOR - start - 3; |
|
@@ -1527,7 +1526,7 @@ yy84: |
|
} |
|
yy85: |
|
++YYCURSOR; |
|
-#line 593 "ext/standard/var_unserializer.re" |
|
+#line 592 "ext/standard/var_unserializer.re" |
|
{ |
|
*p = YYCURSOR; |
|
INIT_PZVAL(*rval); |
|
@@ -1537,7 +1536,7 @@ yy85: |
|
#line 1538 "<stdout>" |
|
yy87: |
|
++YYCURSOR; |
|
-#line 586 "ext/standard/var_unserializer.re" |
|
+#line 585 "ext/standard/var_unserializer.re" |
|
{ |
|
*p = YYCURSOR; |
|
INIT_PZVAL(*rval); |
|
@@ -1597,7 +1596,7 @@ yy91: |
|
} |
|
yy93: |
|
++YYCURSOR; |
|
-#line 563 "ext/standard/var_unserializer.re" |
|
+#line 562 "ext/standard/var_unserializer.re" |
|
{ |
|
long id; |
|
|
|
@@ -1673,7 +1672,7 @@ yy97: |
|
} |
|
yy99: |
|
++YYCURSOR; |
|
-#line 542 "ext/standard/var_unserializer.re" |
|
+#line 541 "ext/standard/var_unserializer.re" |
|
{ |
|
long id; |
|
|
|
@@ -1696,7 +1695,7 @@ yy99: |
|
} |
|
#line 1698 "<stdout>" |
|
} |
|
-#line 903 "ext/standard/var_unserializer.re" |
|
+#line 902 "ext/standard/var_unserializer.re" |
|
|
|
|
|
return 0; |
|
diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re |
|
index d4d5622b..b161fe26 100644 |
|
--- a/ext/standard/var_unserializer.re |
|
+++ b/ext/standard/var_unserializer.re |
|
@@ -411,13 +411,12 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long |
|
|
|
static inline int finish_nested_data(UNSERIALIZE_PARAMETER) |
|
{ |
|
- if (*((*p)++) == '}') |
|
- return 1; |
|
+ if (*p >= max || **p != '}') { |
|
+ return 0; |
|
+ } |
|
|
|
-#if SOMETHING_NEW_MIGHT_LEAD_TO_CRASH_ENABLE_IF_YOU_ARE_BRAVE |
|
- zval_ptr_dtor(rval); |
|
-#endif |
|
- return 0; |
|
+ (*p)++; |
|
+ return 1; |
|
} |
|
|
|
static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce) |
|
-- |
|
2.14.1 |
|
|
|
|