Skip to content

Commit ed709d5

Browse files
committed
Merge branch 'PHP-5.5' into PHP-5.6
* PHP-5.5: update NEWS fix test update NEWS Fix bug #70019 - limit extracted files to given directory Do not do convert_to_* on unserialize, it messes up references Fix #69793 - limit what we accept when unserializing exception Fixed bug #70169 (Use After Free Vulnerability in unserialize() with SplDoublyLinkedList) Fixed bug #70166 - Use After Free Vulnerability in unserialize() with SPLArrayObject ignore signatures for packages too Fix bug #70168 - Use After Free Vulnerability in unserialize() with SplObjectStorage Fixed bug #69892 Fix bug #70014 - use RAND_bytes instead of deprecated RAND_pseudo_bytes Improved fix for Bug #69441 Fix bug #70068 (Dangling pointer in the unserialization of ArrayObject items) Fix bug #70121 (unserialize() could lead to unexpected methods execution / NULL pointer deref) Fix bug #70081: check types for SOAP variables Conflicts: ext/soap/php_http.c ext/spl/spl_observer.c
2 parents 8d31e46 + d52c485 commit ed709d5

22 files changed

+403
-153
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
*.tar.gz
2121
*.tar.bz2
2222
*.tar.xz
23+
*.tar.gz.asc
24+
*.tar.bz2.asc
25+
*.tar.xz.asc
2326
.FBCIndex
2427
.FBCLockFolder
2528
.deps

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: 37 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
}
@@ -218,6 +218,33 @@ ZEND_METHOD(exception, __construct)
218218
}
219219
/* }}} */
220220

221+
/* {{{ proto Exception::__wakeup()
222+
Exception unserialize checks */
223+
#define CHECK_EXC_TYPE(name, type) \
224+
value = zend_read_property(default_exception_ce, object, name, sizeof(name)-1, 0 TSRMLS_CC); \
225+
if(value && Z_TYPE_P(value) != type) { \
226+
zval *tmp; \
227+
MAKE_STD_ZVAL(tmp); \
228+
ZVAL_STRINGL(tmp, name, sizeof(name)-1, 1); \
229+
Z_OBJ_HANDLER_P(object, unset_property)(object, tmp, 0 TSRMLS_CC); \
230+
zval_ptr_dtor(&tmp); \
231+
}
232+
233+
ZEND_METHOD(exception, __wakeup)
234+
{
235+
zval *value;
236+
zval *object = getThis();
237+
HashTable *intern_ht = zend_std_get_properties(getThis() TSRMLS_CC);
238+
CHECK_EXC_TYPE("message", IS_STRING);
239+
CHECK_EXC_TYPE("string", IS_STRING);
240+
CHECK_EXC_TYPE("code", IS_LONG);
241+
CHECK_EXC_TYPE("file", IS_STRING);
242+
CHECK_EXC_TYPE("line", IS_LONG);
243+
CHECK_EXC_TYPE("trace", IS_ARRAY);
244+
CHECK_EXC_TYPE("previous", IS_OBJECT);
245+
}
246+
/* }}} */
247+
221248
/* {{{ proto ErrorException::__construct(string message, int code, int severity [, string filename [, int lineno [, Exception previous]]])
222249
ErrorException constructor */
223250
ZEND_METHOD(error_exception, __construct)
@@ -586,7 +613,7 @@ ZEND_METHOD(exception, getTraceAsString)
586613
int res_len = 0, *len = &res_len, num = 0;
587614

588615
DEFAULT_0_PARAMS;
589-
616+
590617
trace = zend_read_property(default_exception_ce, getThis(), "trace", sizeof("trace")-1, 1 TSRMLS_CC);
591618
if (Z_TYPE_P(trace) != IS_ARRAY) {
592619
RETURN_FALSE;
@@ -602,8 +629,8 @@ ZEND_METHOD(exception, getTraceAsString)
602629
TRACE_APPEND_STRL(s_tmp, strlen(s_tmp));
603630
efree(s_tmp);
604631

605-
res[res_len] = '\0';
606-
RETURN_STRINGL(res, res_len, 0);
632+
res[res_len] = '\0';
633+
RETURN_STRINGL(res, res_len, 0);
607634
}
608635
/* }}} */
609636

@@ -640,15 +667,15 @@ ZEND_METHOD(exception, __toString)
640667
int len = 0;
641668
zend_fcall_info fci;
642669
zval fname;
643-
670+
644671
DEFAULT_0_PARAMS;
645-
672+
646673
str = estrndup("", 0);
647674

648675
exception = getThis();
649676
ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1, 1);
650677

651-
while (exception && Z_TYPE_P(exception) == IS_OBJECT) {
678+
while (exception && Z_TYPE_P(exception) == IS_OBJECT && instanceof_function(Z_OBJCE_P(exception), default_exception_ce TSRMLS_CC)) {
652679
prev_str = str;
653680
_default_exception_get_entry(exception, "message", sizeof("message")-1, &message TSRMLS_CC);
654681
_default_exception_get_entry(exception, "file", sizeof("file")-1, &file TSRMLS_CC);
@@ -658,6 +685,7 @@ ZEND_METHOD(exception, __toString)
658685
convert_to_string(&file);
659686
convert_to_long(&line);
660687

688+
trace = NULL;
661689
fci.size = sizeof(fci);
662690
fci.function_table = &Z_OBJCE_P(exception)->function_table;
663691
fci.function_name = &fname;
@@ -670,7 +698,7 @@ ZEND_METHOD(exception, __toString)
670698

671699
zend_call_function(&fci, NULL TSRMLS_CC);
672700

673-
if (Z_TYPE_P(trace) != IS_STRING) {
701+
if (trace && Z_TYPE_P(trace) != IS_STRING) {
674702
zval_ptr_dtor(&trace);
675703
trace = NULL;
676704
}
@@ -727,6 +755,7 @@ ZEND_END_ARG_INFO()
727755
const static zend_function_entry default_exception_functions[] = {
728756
ZEND_ME(exception, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
729757
ZEND_ME(exception, __construct, arginfo_exception___construct, ZEND_ACC_PUBLIC)
758+
ZEND_ME(exception, __wakeup, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
730759
ZEND_ME(exception, getMessage, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
731760
ZEND_ME(exception, getCode, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
732761
ZEND_ME(exception, getFile, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)

0 commit comments

Comments
 (0)