diff options
author | Stanislav Malyshev <stas@php.net> | 2015-07-26 17:09:34 -0700 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2015-07-26 17:10:24 -0700 |
commit | e488690d957fce0dbdabe619adbe314ada498215 (patch) | |
tree | 735a0cb13dfd5d08efbd347ec6d68837fb89d0d2 | |
parent | c96d08b27226193dd51f2b50e84272235c6aaa69 (diff) | |
download | php-git-e488690d957fce0dbdabe619adbe314ada498215.tar.gz |
Fix bug #70121 (unserialize() could lead to unexpected methods execution / NULL pointer deref)
-rw-r--r-- | Zend/tests/bug70121.phpt | 9 | ||||
-rw-r--r-- | Zend/zend_exceptions.c | 17 |
2 files changed, 18 insertions, 8 deletions
diff --git a/Zend/tests/bug70121.phpt b/Zend/tests/bug70121.phpt new file mode 100644 index 0000000000..9f8b7d6055 --- /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 06be9885d5..1a3ee8f434 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; } @@ -586,7 +586,7 @@ ZEND_METHOD(exception, getTraceAsString) int res_len = 0, *len = &res_len, num = 0; DEFAULT_0_PARAMS; - + trace = zend_read_property(default_exception_ce, getThis(), "trace", sizeof("trace")-1, 1 TSRMLS_CC); if(Z_TYPE_P(trace) != IS_ARRAY) { RETURN_FALSE; @@ -602,8 +602,8 @@ ZEND_METHOD(exception, getTraceAsString) TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); efree(s_tmp); - res[res_len] = '\0'; - RETURN_STRINGL(res, res_len, 0); + res[res_len] = '\0'; + RETURN_STRINGL(res, res_len, 0); } /* }}} */ @@ -640,15 +640,15 @@ ZEND_METHOD(exception, __toString) int len = 0; zend_fcall_info fci; zval fname; - + DEFAULT_0_PARAMS; - + str = estrndup("", 0); 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; } |