Skip to content

Commit e488690

Browse files
committed
Fix bug #70121 (unserialize() could lead to unexpected methods execution / NULL pointer deref)
1 parent c96d08b commit e488690

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

Zend/tests/bug70121.phpt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
--TEST--
2+
Bug #70121 (unserialize() could lead to unexpected methods execution / NULL pointer deref)
3+
--FILE--
4+
<?php
5+
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:{}}}');
6+
?>
7+
OK
8+
--EXPECT--
9+
OK

Zend/zend_exceptions.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void zend_exception_set_previous(zval *exception, zval *add_previous TSRMLS_DC)
4141
if (exception == add_previous || !add_previous || !exception) {
4242
return;
4343
}
44-
if (Z_TYPE_P(add_previous) != IS_OBJECT && !instanceof_function(Z_OBJCE_P(add_previous), default_exception_ce TSRMLS_CC)) {
44+
if (Z_TYPE_P(add_previous) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(add_previous), default_exception_ce TSRMLS_CC)) {
4545
zend_error(E_ERROR, "Cannot set non exception as previous exception");
4646
return;
4747
}
@@ -586,7 +586,7 @@ ZEND_METHOD(exception, getTraceAsString)
586586
int res_len = 0, *len = &res_len, num = 0;
587587

588588
DEFAULT_0_PARAMS;
589-
589+
590590
trace = zend_read_property(default_exception_ce, getThis(), "trace", sizeof("trace")-1, 1 TSRMLS_CC);
591591
if(Z_TYPE_P(trace) != IS_ARRAY) {
592592
RETURN_FALSE;
@@ -602,8 +602,8 @@ ZEND_METHOD(exception, getTraceAsString)
602602
TRACE_APPEND_STRL(s_tmp, strlen(s_tmp));
603603
efree(s_tmp);
604604

605-
res[res_len] = '\0';
606-
RETURN_STRINGL(res, res_len, 0);
605+
res[res_len] = '\0';
606+
RETURN_STRINGL(res, res_len, 0);
607607
}
608608
/* }}} */
609609

@@ -640,15 +640,15 @@ ZEND_METHOD(exception, __toString)
640640
int len = 0;
641641
zend_fcall_info fci;
642642
zval fname;
643-
643+
644644
DEFAULT_0_PARAMS;
645-
645+
646646
str = estrndup("", 0);
647647

648648
exception = getThis();
649649
ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1, 1);
650650

651-
while (exception && Z_TYPE_P(exception) == IS_OBJECT) {
651+
while (exception && Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), default_exception_ce TSRMLS_CC)) {
652652
prev_str = str;
653653
_default_exception_get_entry(exception, "message", sizeof("message")-1, &message TSRMLS_CC);
654654
_default_exception_get_entry(exception, "file", sizeof("file")-1, &file TSRMLS_CC);
@@ -658,6 +658,7 @@ ZEND_METHOD(exception, __toString)
658658
convert_to_string(&file);
659659
convert_to_long(&line);
660660

661+
trace = NULL;
661662
fci.size = sizeof(fci);
662663
fci.function_table = &Z_OBJCE_P(exception)->function_table;
663664
fci.function_name = &fname;
@@ -670,7 +671,7 @@ ZEND_METHOD(exception, __toString)
670671

671672
zend_call_function(&fci, NULL TSRMLS_CC);
672673

673-
if (Z_TYPE_P(trace) != IS_STRING) {
674+
if (trace && Z_TYPE_P(trace) != IS_STRING) {
674675
zval_ptr_dtor(&trace);
675676
trace = NULL;
676677
}

0 commit comments

Comments
 (0)