summaryrefslogtreecommitdiffstats
path: root/bug72663.patch
diff options
context:
space:
mode:
Diffstat (limited to 'bug72663.patch')
-rw-r--r--bug72663.patch206
1 files changed, 206 insertions, 0 deletions
diff --git a/bug72663.patch b/bug72663.patch
new file mode 100644
index 0000000..498a58e
--- /dev/null
+++ b/bug72663.patch
@@ -0,0 +1,206 @@
+Backported from 5.6.25 by Remi.
+
+From c1cfd6a9fe23765191ea2f654790c7b127d4b797 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Tue, 2 Aug 2016 01:08:42 -0700
+Subject: [PATCH] Fix bug #72663 - destroy broken object when unserializing
+
+---
+ ext/standard/tests/strings/bug72663.phpt | 26 +++++++++++
+ ext/standard/tests/strings/bug72663_2.phpt | 17 ++++++++
+ ext/standard/var_unserializer.c | 70 ++++++++++++++++--------------
+ ext/standard/var_unserializer.re | 5 ++-
+ 4 files changed, 84 insertions(+), 34 deletions(-)
+ create mode 100644 ext/standard/tests/strings/bug72663.phpt
+ create mode 100644 ext/standard/tests/strings/bug72663_2.phpt
+
+diff --git a/ext/standard/tests/strings/bug72663.phpt b/ext/standard/tests/strings/bug72663.phpt
+new file mode 100644
+index 0000000..e61f939
+--- /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 0000000..ac605e9
+--- /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 1e45b03..e4ddecf 100644
+--- a/ext/standard/var_unserializer.c
++++ b/ext/standard/var_unserializer.c
+@@ -437,6 +437,9 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
+ }
+
+ if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_PP(rval), elements, 1)) {
++ /* We've got partially constructed object on our hands here. Wipe it */
++ zend_hash_clean(Z_OBJPROP_PP(rval));
++ ZVAL_NULL(*rval);
+ return 0;
+ }
+
+diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
+index d1d4ef9..c1c18c9 100644
+--- a/ext/standard/var_unserializer.re
++++ b/ext/standard/var_unserializer.re
+@@ -443,6 +443,9 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
+ }
+
+ if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_PP(rval), elements, 1)) {
++ /* We've got partially constructed object on our hands here. Wipe it. */
++ zend_hash_clean(Z_OBJPROP_PP(rval));
++ ZVAL_NULL(*rval);
+ return 0;
+ }
+
+From b25f44098fdc8cecfd62d0fc5422c23d8747dcd2 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Thu, 4 Aug 2016 00:03:31 -0700
+Subject: [PATCH] Update comment
+
+---
+ ext/standard/var_unserializer.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
+index e4ddecf..1d459ae 100644
+--- a/ext/standard/var_unserializer.c
++++ b/ext/standard/var_unserializer.c
+@@ -437,7 +437,7 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
+ }
+
+ if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_PP(rval), elements, 1)) {
+- /* We've got partially constructed object on our hands here. Wipe it */
++ /* We've got partially constructed object on our hands here. Wipe it. */
+ zend_hash_clean(Z_OBJPROP_PP(rval));
+ ZVAL_NULL(*rval);
+ return 0;
+From 75c0dbdd028ffa20eae5cf3a2fae194961464b8b Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sun, 7 Aug 2016 15:33:29 -0700
+Subject: [PATCH] Improve fix for #72663
+
+---
+ ext/standard/tests/strings/bug72663_3.phpt | 18 ++++++++
+ ext/standard/var_unserializer.c | 68 ++++++++++++++++--------------
+ ext/standard/var_unserializer.re | 8 +++-
+ 3 files changed, 62 insertions(+), 32 deletions(-)
+ create mode 100644 ext/standard/tests/strings/bug72663_3.phpt
+
+diff --git a/ext/standard/tests/strings/bug72663_3.phpt b/ext/standard/tests/strings/bug72663_3.phpt
+new file mode 100644
+index 0000000..e336bc8
+--- /dev/null
++++ b/ext/standard/tests/strings/bug72663_3.phpt
+@@ -0,0 +1,18 @@
++--TEST--
++Bug #72663: Create an Unexpected Object and Don't Invoke __wakeup() in Deserialization
++--FILE--
++<?php
++class obj {
++ var $ryat;
++ function __wakeup() {
++ $this->ryat = str_repeat('A', 0x112);
++ }
++}
++
++$poc = 'O:8:"stdClass":1:{i:0;O:3:"obj":1:{s:4:"ryat";R:1;';
++unserialize($poc);
++?>
++DONE
++--EXPECTF--
++Notice: unserialize(): Error at offset 51 of 50 bytes in %sbug72663_3.php on line %d
++DONE
+\ No newline at end of file
+diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
+index 1d459ae..c8e6f8a 100644
+--- a/ext/standard/var_unserializer.c
++++ b/ext/standard/var_unserializer.c
+@@ -438,11 +438,17 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
+
+ if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_PP(rval), elements, 1)) {
+ /* We've got partially constructed object on our hands here. Wipe it. */
+- zend_hash_clean(Z_OBJPROP_PP(rval));
++ if(Z_TYPE_PP(rval) == IS_OBJECT) {
++ zend_hash_clean(Z_OBJPROP_PP(rval));
++ }
+ ZVAL_NULL(*rval);
+ return 0;
+ }
+
++ if (Z_TYPE_PP(rval) != IS_OBJECT) {
++ return 0;
++ }
++
+ if (Z_OBJCE_PP(rval) != PHP_IC_ENTRY &&
+ zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) {
+ INIT_PZVAL(&fname);
+diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
+index c1c18c9..11b93c5 100644
+--- a/ext/standard/var_unserializer.re
++++ b/ext/standard/var_unserializer.re
+@@ -444,11 +444,17 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
+
+ if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_PP(rval), elements, 1)) {
+ /* We've got partially constructed object on our hands here. Wipe it. */
+- zend_hash_clean(Z_OBJPROP_PP(rval));
++ if(Z_TYPE_PP(rval) == IS_OBJECT) {
++ zend_hash_clean(Z_OBJPROP_PP(rval));
++ }
+ ZVAL_NULL(*rval);
+ return 0;
+ }
+
++ if (Z_TYPE_PP(rval) != IS_OBJECT) {
++ return 0;
++ }
++
+ if (Z_OBJCE_PP(rval) != PHP_IC_ENTRY &&
+ zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) {
+ INIT_PZVAL(&fname);