mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Avoid use after free in internal prop type verification
This issue only applies to debug builds: read_property can free the object, but we'd try to check the object handlers afterwards. Rewrite the check in a way that only accessed the object before the read_property call. Fixes oss-fuzz #38297.
This commit is contained in:
parent
b514e550a2
commit
6381a16f3f
15
Zend/tests/magic_get_destroy_object.phpt
Normal file
15
Zend/tests/magic_get_destroy_object.phpt
Normal file
@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
Destroy object in magic __get()
|
||||
--FILE--
|
||||
<?php
|
||||
class Test {
|
||||
function __get($name) {
|
||||
$GLOBALS["x"] = null;
|
||||
}
|
||||
}
|
||||
$x = new Test;
|
||||
var_dump($x->prop);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
NULL
|
@ -1194,15 +1194,6 @@ ZEND_API ZEND_COLD void zend_internal_call_arginfo_violation(zend_function *fbc)
|
||||
ZSTR_VAL(fbc->common.function_name));
|
||||
}
|
||||
|
||||
static void zend_verify_internal_read_property_type(zend_object *obj, zend_string *name, zval *val)
|
||||
{
|
||||
zend_property_info *prop_info =
|
||||
zend_get_property_info(obj->ce, name, /* silent */ true);
|
||||
if (prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO && ZEND_TYPE_IS_SET(prop_info->type)) {
|
||||
zend_verify_property_type(prop_info, val, /* strict */ true);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef ZEND_VERIFY_FUNC_INFO
|
||||
# define ZEND_VERIFY_FUNC_INFO 0
|
||||
#endif
|
||||
|
@ -2104,10 +2104,19 @@ ZEND_VM_C_LABEL(fetch_obj_r_fast_copy):
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/* For non-standard object handlers, verify a declared property type in debug builds.
|
||||
* Fetch prop_info before calling read_property(), as it may deallocate the object. */
|
||||
zend_property_info *prop_info = NULL;
|
||||
if (zobj->handlers->read_property != zend_std_read_property) {
|
||||
prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
|
||||
}
|
||||
#endif
|
||||
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
|
||||
#if ZEND_DEBUG
|
||||
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
|
||||
zend_verify_internal_read_property_type(zobj, name, retval);
|
||||
if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
|
||||
&& ZEND_TYPE_IS_SET(prop_info->type)) {
|
||||
zend_verify_property_type(prop_info, retval, /* strict */ true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -6288,10 +6288,19 @@ fetch_obj_r_fast_copy:
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/* For non-standard object handlers, verify a declared property type in debug builds.
|
||||
* Fetch prop_info before calling read_property(), as it may deallocate the object. */
|
||||
zend_property_info *prop_info = NULL;
|
||||
if (zobj->handlers->read_property != zend_std_read_property) {
|
||||
prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
|
||||
}
|
||||
#endif
|
||||
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
|
||||
#if ZEND_DEBUG
|
||||
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
|
||||
zend_verify_internal_read_property_type(zobj, name, retval);
|
||||
if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
|
||||
&& ZEND_TYPE_IS_SET(prop_info->type)) {
|
||||
zend_verify_property_type(prop_info, retval, /* strict */ true);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -8608,10 +8617,19 @@ fetch_obj_r_fast_copy:
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/* For non-standard object handlers, verify a declared property type in debug builds.
|
||||
* Fetch prop_info before calling read_property(), as it may deallocate the object. */
|
||||
zend_property_info *prop_info = NULL;
|
||||
if (zobj->handlers->read_property != zend_std_read_property) {
|
||||
prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
|
||||
}
|
||||
#endif
|
||||
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
|
||||
#if ZEND_DEBUG
|
||||
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
|
||||
zend_verify_internal_read_property_type(zobj, name, retval);
|
||||
if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
|
||||
&& ZEND_TYPE_IS_SET(prop_info->type)) {
|
||||
zend_verify_property_type(prop_info, retval, /* strict */ true);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -10963,10 +10981,19 @@ fetch_obj_r_fast_copy:
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/* For non-standard object handlers, verify a declared property type in debug builds.
|
||||
* Fetch prop_info before calling read_property(), as it may deallocate the object. */
|
||||
zend_property_info *prop_info = NULL;
|
||||
if (zobj->handlers->read_property != zend_std_read_property) {
|
||||
prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
|
||||
}
|
||||
#endif
|
||||
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
|
||||
#if ZEND_DEBUG
|
||||
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
|
||||
zend_verify_internal_read_property_type(zobj, name, retval);
|
||||
if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
|
||||
&& ZEND_TYPE_IS_SET(prop_info->type)) {
|
||||
zend_verify_property_type(prop_info, retval, /* strict */ true);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -15386,10 +15413,19 @@ fetch_obj_r_fast_copy:
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/* For non-standard object handlers, verify a declared property type in debug builds.
|
||||
* Fetch prop_info before calling read_property(), as it may deallocate the object. */
|
||||
zend_property_info *prop_info = NULL;
|
||||
if (zobj->handlers->read_property != zend_std_read_property) {
|
||||
prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
|
||||
}
|
||||
#endif
|
||||
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
|
||||
#if ZEND_DEBUG
|
||||
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
|
||||
zend_verify_internal_read_property_type(zobj, name, retval);
|
||||
if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
|
||||
&& ZEND_TYPE_IS_SET(prop_info->type)) {
|
||||
zend_verify_property_type(prop_info, retval, /* strict */ true);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -16809,10 +16845,19 @@ fetch_obj_r_fast_copy:
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/* For non-standard object handlers, verify a declared property type in debug builds.
|
||||
* Fetch prop_info before calling read_property(), as it may deallocate the object. */
|
||||
zend_property_info *prop_info = NULL;
|
||||
if (zobj->handlers->read_property != zend_std_read_property) {
|
||||
prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
|
||||
}
|
||||
#endif
|
||||
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
|
||||
#if ZEND_DEBUG
|
||||
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
|
||||
zend_verify_internal_read_property_type(zobj, name, retval);
|
||||
if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
|
||||
&& ZEND_TYPE_IS_SET(prop_info->type)) {
|
||||
zend_verify_property_type(prop_info, retval, /* strict */ true);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -18124,10 +18169,19 @@ fetch_obj_r_fast_copy:
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/* For non-standard object handlers, verify a declared property type in debug builds.
|
||||
* Fetch prop_info before calling read_property(), as it may deallocate the object. */
|
||||
zend_property_info *prop_info = NULL;
|
||||
if (zobj->handlers->read_property != zend_std_read_property) {
|
||||
prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
|
||||
}
|
||||
#endif
|
||||
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
|
||||
#if ZEND_DEBUG
|
||||
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
|
||||
zend_verify_internal_read_property_type(zobj, name, retval);
|
||||
if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
|
||||
&& ZEND_TYPE_IS_SET(prop_info->type)) {
|
||||
zend_verify_property_type(prop_info, retval, /* strict */ true);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -31428,10 +31482,19 @@ fetch_obj_r_fast_copy:
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/* For non-standard object handlers, verify a declared property type in debug builds.
|
||||
* Fetch prop_info before calling read_property(), as it may deallocate the object. */
|
||||
zend_property_info *prop_info = NULL;
|
||||
if (zobj->handlers->read_property != zend_std_read_property) {
|
||||
prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
|
||||
}
|
||||
#endif
|
||||
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
|
||||
#if ZEND_DEBUG
|
||||
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
|
||||
zend_verify_internal_read_property_type(zobj, name, retval);
|
||||
if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
|
||||
&& ZEND_TYPE_IS_SET(prop_info->type)) {
|
||||
zend_verify_property_type(prop_info, retval, /* strict */ true);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -33286,10 +33349,19 @@ fetch_obj_r_fast_copy:
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/* For non-standard object handlers, verify a declared property type in debug builds.
|
||||
* Fetch prop_info before calling read_property(), as it may deallocate the object. */
|
||||
zend_property_info *prop_info = NULL;
|
||||
if (zobj->handlers->read_property != zend_std_read_property) {
|
||||
prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
|
||||
}
|
||||
#endif
|
||||
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
|
||||
#if ZEND_DEBUG
|
||||
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
|
||||
zend_verify_internal_read_property_type(zobj, name, retval);
|
||||
if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
|
||||
&& ZEND_TYPE_IS_SET(prop_info->type)) {
|
||||
zend_verify_property_type(prop_info, retval, /* strict */ true);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -35756,10 +35828,19 @@ fetch_obj_r_fast_copy:
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/* For non-standard object handlers, verify a declared property type in debug builds.
|
||||
* Fetch prop_info before calling read_property(), as it may deallocate the object. */
|
||||
zend_property_info *prop_info = NULL;
|
||||
if (zobj->handlers->read_property != zend_std_read_property) {
|
||||
prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
|
||||
}
|
||||
#endif
|
||||
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
|
||||
#if ZEND_DEBUG
|
||||
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
|
||||
zend_verify_internal_read_property_type(zobj, name, retval);
|
||||
if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
|
||||
&& ZEND_TYPE_IS_SET(prop_info->type)) {
|
||||
zend_verify_property_type(prop_info, retval, /* strict */ true);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -39895,10 +39976,19 @@ fetch_obj_r_fast_copy:
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/* For non-standard object handlers, verify a declared property type in debug builds.
|
||||
* Fetch prop_info before calling read_property(), as it may deallocate the object. */
|
||||
zend_property_info *prop_info = NULL;
|
||||
if (zobj->handlers->read_property != zend_std_read_property) {
|
||||
prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
|
||||
}
|
||||
#endif
|
||||
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
|
||||
#if ZEND_DEBUG
|
||||
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
|
||||
zend_verify_internal_read_property_type(zobj, name, retval);
|
||||
if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
|
||||
&& ZEND_TYPE_IS_SET(prop_info->type)) {
|
||||
zend_verify_property_type(prop_info, retval, /* strict */ true);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -43531,10 +43621,19 @@ fetch_obj_r_fast_copy:
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/* For non-standard object handlers, verify a declared property type in debug builds.
|
||||
* Fetch prop_info before calling read_property(), as it may deallocate the object. */
|
||||
zend_property_info *prop_info = NULL;
|
||||
if (zobj->handlers->read_property != zend_std_read_property) {
|
||||
prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
|
||||
}
|
||||
#endif
|
||||
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
|
||||
#if ZEND_DEBUG
|
||||
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
|
||||
zend_verify_internal_read_property_type(zobj, name, retval);
|
||||
if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
|
||||
&& ZEND_TYPE_IS_SET(prop_info->type)) {
|
||||
zend_verify_property_type(prop_info, retval, /* strict */ true);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -48562,10 +48661,19 @@ fetch_obj_r_fast_copy:
|
||||
}
|
||||
}
|
||||
|
||||
#if ZEND_DEBUG
|
||||
/* For non-standard object handlers, verify a declared property type in debug builds.
|
||||
* Fetch prop_info before calling read_property(), as it may deallocate the object. */
|
||||
zend_property_info *prop_info = NULL;
|
||||
if (zobj->handlers->read_property != zend_std_read_property) {
|
||||
prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true);
|
||||
}
|
||||
#endif
|
||||
retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
|
||||
#if ZEND_DEBUG
|
||||
if (!EG(exception) && zobj->handlers->read_property != zend_std_read_property) {
|
||||
zend_verify_internal_read_property_type(zobj, name, retval);
|
||||
if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO
|
||||
&& ZEND_TYPE_IS_SET(prop_info->type)) {
|
||||
zend_verify_property_type(prop_info, retval, /* strict */ true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user