Skip to content

Instantly share code, notes, and snippets.

@smalyshev
Created July 27, 2015 00:11
commit e488690d957fce0dbdabe619adbe314ada498215
Author: Stanislav Malyshev <stas@php.net>
Date: Sun Jul 26 17:09:34 2015 -0700
Fix bug #70121 (unserialize() could lead to unexpected methods execution / NULL pointer deref)
diff --git a/Zend/tests/bug70121.phpt b/Zend/tests/bug70121.phpt
new file mode 100644
index 0000000..9f8b7d6
--- /dev/null
+++ b/Zend/tests/bug70121.phpt
@@ -0,0 +1,9 @@
+--TEST--
+Bug #70121 (unserialize() could lead to unexpected methods execution / NULL pointer deref)
+--FILE--
+<?php
+unserialize('O:12:"DateInterval":1:{s:4:"days";O:9:"Exception":7:{s:10:"'."\0".'*'."\0".'message";s:1:"x";s:17:"'."\0".'Exception'."\0".'string";s:1:"A";s:7:"'."\0".'*'."\0".'code";i:0;s:7:"'."\0".'*'."\0".'file";s:1:"a";s:7:"'."\0".'*'."\0".'line";i:1337;s:16:"'."\0".'Exception'."\0".'trace";a:0:{}s:19:"'."\0".'Exception'."\0".'previous";O:8:"stdClass":0:{}}}');
+?>
+OK
+--EXPECT--
+OK
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c
index 06be988..1a3ee8f 100644
--- a/Zend/zend_exceptions.c
+++ b/Zend/zend_exceptions.c
@@ -41,7 +41,7 @@ void zend_exception_set_previous(zval *exception, zval *add_previous TSRMLS_DC)
if (exception == add_previous || !add_previous || !exception) {
return;
}
- if (Z_TYPE_P(add_previous) != IS_OBJECT && !instanceof_function(Z_OBJCE_P(add_previous), default_exception_ce TSRMLS_CC)) {
+ if (Z_TYPE_P(add_previous) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(add_previous), default_exception_ce TSRMLS_CC)) {
zend_error(E_ERROR, "Cannot set non exception as previous exception");
return;
}
@@ -648,7 +648,7 @@ ZEND_METHOD(exception, __toString)
exception = getThis();
ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1, 1);
- while (exception && Z_TYPE_P(exception) == IS_OBJECT) {
+ while (exception && Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), default_exception_ce TSRMLS_CC)) {
prev_str = str;
_default_exception_get_entry(exception, "message", sizeof("message")-1, &message TSRMLS_CC);
_default_exception_get_entry(exception, "file", sizeof("file")-1, &file TSRMLS_CC);
@@ -658,6 +658,7 @@ ZEND_METHOD(exception, __toString)
convert_to_string(&file);
convert_to_long(&line);
+ trace = NULL;
fci.size = sizeof(fci);
fci.function_table = &Z_OBJCE_P(exception)->function_table;
fci.function_name = &fname;
@@ -670,7 +671,7 @@ ZEND_METHOD(exception, __toString)
zend_call_function(&fci, NULL TSRMLS_CC);
- if (Z_TYPE_P(trace) != IS_STRING) {
+ if (trace && Z_TYPE_P(trace) != IS_STRING) {
zval_ptr_dtor(&trace);
trace = NULL;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment