]> granicus.if.org Git - php/commitdiff
Fix #69793 - limit what we accept when unserializing exception
authorStanislav Malyshev <stas@php.net>
Mon, 27 Jul 2015 08:38:27 +0000 (01:38 -0700)
committerStanislav Malyshev <stas@php.net>
Sun, 2 Aug 2015 05:02:26 +0000 (22:02 -0700)
Zend/zend_exceptions.c
ext/standard/tests/serialize/bug69152.phpt
ext/standard/tests/serialize/bug69793.phpt [new file with mode: 0644]

index 1a3ee8f434e4870677333aeb268503f2e0b20642..82b777a958dc419a309ac79c47eda90167454139 100644 (file)
@@ -218,6 +218,33 @@ ZEND_METHOD(exception, __construct)
 }
 /* }}} */
 
+/* {{{ proto Exception::__wakeup()
+   Exception unserialize checks */
+#define CHECK_EXC_TYPE(name, type) \
+       value = zend_read_property(default_exception_ce, object, name, sizeof(name)-1, 0 TSRMLS_CC); \
+       if(value && Z_TYPE_P(value) != type) { \
+               zval *tmp; \
+               MAKE_STD_ZVAL(tmp); \
+               ZVAL_STRINGL(tmp, name, sizeof(name)-1, 1); \
+               Z_OBJ_HANDLER_P(object, unset_property)(object, tmp, 0 TSRMLS_CC); \
+               zval_ptr_dtor(&tmp); \
+       }
+
+ZEND_METHOD(exception, __wakeup)
+{
+       zval *value;
+       zval *object = getThis();
+       HashTable *intern_ht = zend_std_get_properties(getThis() TSRMLS_CC);
+       CHECK_EXC_TYPE("message", IS_STRING);
+       CHECK_EXC_TYPE("string", IS_STRING);
+       CHECK_EXC_TYPE("code", IS_LONG);
+       CHECK_EXC_TYPE("file", IS_STRING);
+       CHECK_EXC_TYPE("line", IS_LONG);
+       CHECK_EXC_TYPE("trace", IS_ARRAY);
+       CHECK_EXC_TYPE("previous", IS_OBJECT);
+}
+/* }}} */
+
 /* {{{ proto ErrorException::__construct(string message, int code, int severity [, string filename [, int lineno [, Exception previous]]])
    ErrorException constructor */
 ZEND_METHOD(error_exception, __construct)
@@ -728,6 +755,7 @@ ZEND_END_ARG_INFO()
 const static zend_function_entry default_exception_functions[] = {
        ZEND_ME(exception, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
        ZEND_ME(exception, __construct, arginfo_exception___construct, ZEND_ACC_PUBLIC)
+       ZEND_ME(exception, __wakeup, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
        ZEND_ME(exception, getMessage, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
        ZEND_ME(exception, getCode, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
        ZEND_ME(exception, getFile, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
index 4e741685ccd043ede839e898e3952cbaddafae59..bc2b302ddb75da9cfacea209287a732d8cdaf2bb 100644 (file)
@@ -9,6 +9,7 @@ $x->test();
 
 ?>
 --EXPECTF--
+Notice: Undefined property: Exception::$previous in %s on line %d
 exception 'Exception' in %s:%d
 Stack trace:
 #0 {main}
diff --git a/ext/standard/tests/serialize/bug69793.phpt b/ext/standard/tests/serialize/bug69793.phpt
new file mode 100644 (file)
index 0000000..134b4dd
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+Bug #69793: Remotely triggerable stack exhaustion via recursive method calls
+--FILE--
+<?php
+$e = unserialize('O:9:"Exception":7:{s:17:"'."\0".'Exception'."\0".'string";s:1:"a";s:7:"'."\0".'*'."\0".'code";i:0;s:7:"'."\0".'*'."\0".'file";R:1;s:7:"'."\0".'*'."\0".'line";i:1337;s:16:"'."\0".'Exception'."\0".'trace";a:0:{}s:19:"'."\0".'Exception'."\0".'previous";i:10;s:10:"'."\0".'*'."\0".'message";N;}');
+
+var_dump($e."");
+?>
+--EXPECTF--
+Notice: Undefined property: Exception::$message in %s/bug69793.php on line %d
+
+Notice: Undefined property: Exception::$file in %s/bug69793.php on line %d
+
+Notice: Undefined property: Exception::$previous in %s/bug69793.php on line %d
+string(53) "exception 'Exception' in :1337
+Stack trace:
+#0 {main}"