File php-CVE-2016-7478.patch of Package php5.openSUSE_Leap_42.1_Update
Index: php-5.5.14/Zend/zend_exceptions.c
===================================================================
--- php-5.5.14.orig/Zend/zend_exceptions.c 2017-02-15 11:08:10.837102569 +0100
+++ php-5.5.14/Zend/zend_exceptions.c 2017-02-15 11:11:34.376559092 +0100
@@ -221,13 +221,9 @@ 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); \
+ value = zend_read_property(default_exception_ce, object, name, sizeof(name)-1, 1 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_unset_property(default_exception_ce, object, name, sizeof(name)-1 TSRMLS_CC); \
}
ZEND_METHOD(exception, __wakeup)
@@ -241,7 +237,12 @@ ZEND_METHOD(exception, __wakeup)
CHECK_EXC_TYPE("file", IS_STRING);
CHECK_EXC_TYPE("line", IS_LONG);
CHECK_EXC_TYPE("trace", IS_ARRAY);
- CHECK_EXC_TYPE("previous", IS_OBJECT);
+ value = zend_read_property(default_exception_ce, object, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
+ if (value && Z_TYPE_P(value) != IS_NULL && (Z_TYPE_P(value) != IS_OBJECT ||
+ !instanceof_function(Z_OBJCE_P(value), default_exception_ce TSRMLS_CC) ||
+ value == object)) {
+ zend_unset_property(default_exception_ce, object, "previous", sizeof("previous")-1 TSRMLS_CC);
+ }
}
/* }}} */
@@ -718,7 +719,11 @@ ZEND_METHOD(exception, __toString)
zval_dtor(&file);
zval_dtor(&line);
- exception = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 0 TSRMLS_CC);
+ Z_OBJPROP_P(exception)->nApplyCount++;
+ exception = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
+ if (exception && Z_TYPE_P(exception) == IS_OBJECT && Z_OBJPROP_P(exception)->nApplyCount > 0) {
+ break;
+ }
if (trace) {
zval_ptr_dtor(&trace);
@@ -727,6 +732,17 @@ ZEND_METHOD(exception, __toString)
}
zval_dtor(&fname);
+ /* Reset apply counts */
+ exception = getThis();
+ while (exception && Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), default_exception_ce TSRMLS_CC)) {
+ if(Z_OBJPROP_P(exception)->nApplyCount) {
+ Z_OBJPROP_P(exception)->nApplyCount--;
+ } else {
+ break;
+ }
+ exception = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
+ }
+
/* We store the result in the private property string so we can access
* the result in uncaught exception handlers without memleaks. */
zend_update_property_string(default_exception_ce, getThis(), "string", sizeof("string")-1, str TSRMLS_CC);