Skip to content

Commit 4d22781

Browse files
committed
Fix #69793 - limit what we accept when unserializing exception
1 parent 863bf29 commit 4d22781

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

Zend/zend_exceptions.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
@@ -728,6 +755,7 @@ ZEND_END_ARG_INFO()
728755
const static zend_function_entry default_exception_functions[] = {
729756
ZEND_ME(exception, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
730757
ZEND_ME(exception, __construct, arginfo_exception___construct, ZEND_ACC_PUBLIC)
758+
ZEND_ME(exception, __wakeup, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
731759
ZEND_ME(exception, getMessage, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
732760
ZEND_ME(exception, getCode, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
733761
ZEND_ME(exception, getFile, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)

ext/standard/tests/serialize/bug69152.phpt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ $x->test();
99

1010
?>
1111
--EXPECTF--
12+
Notice: Undefined property: Exception::$previous in %s on line %d
1213
exception 'Exception' in %s:%d
1314
Stack trace:
1415
#0 {main}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Bug #69793: Remotely triggerable stack exhaustion via recursive method calls
3+
--FILE--
4+
<?php
5+
$e = unserialize('O:9:"Exception":7:{s:17:"'."\0".'Exception'."\0".'string";s:1:"a";s:7:"'."\0".'*'."\0".'code";i:0;s:7:"'."\0".'*'."\0".'file";R:1;s:7:"'."\0".'*'."\0".'line";i:1337;s:16:"'."\0".'Exception'."\0".'trace";a:0:{}s:19:"'."\0".'Exception'."\0".'previous";i:10;s:10:"'."\0".'*'."\0".'message";N;}');
6+
7+
var_dump($e."");
8+
?>
9+
--EXPECTF--
10+
Notice: Undefined property: Exception::$message in %s/bug69793.php on line %d
11+
12+
Notice: Undefined property: Exception::$file in %s/bug69793.php on line %d
13+
14+
Notice: Undefined property: Exception::$previous in %s/bug69793.php on line %d
15+
string(53) "exception 'Exception' in :1337
16+
Stack trace:
17+
#0 {main}"

0 commit comments

Comments
 (0)