Skip to content

Commit

Permalink
Fixed bug #79784
Browse files Browse the repository at this point in the history
The fix here is essentially the same as for bug #78598, just for
the undefined variable notice, rather than the undefined index one.
  • Loading branch information
nikic committed Jul 7, 2020
1 parent b0014ad commit 62bec0e
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 3 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ PHP NEWS
(Nikita)
. Fixed bug #78598 (Changing array during undef index RW error segfaults).
(Nikita)
. Fixed bug #79784 (Use after free if changing array during undef var during
array write fetch). (Nikita)

- Fileinfo:
. Fixed bug #79756 (finfo_file crash (FILEINFO_MIME)). (cmb)
Expand Down
20 changes: 20 additions & 0 deletions Zend/tests/bug79784.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
Bug #79784: Use after free if changing array during undef var during array write fetch
--FILE--
<?php
set_error_handler(function () {
$GLOBALS['a'] = null;
});

$a[$c] = 'x' ;
var_dump($a);
$a[$c] .= 'x' ;
var_dump($a);
$a[$c][$c] = 'x' ;
var_dump($a);

?>
--EXPECT--
NULL
NULL
NULL
19 changes: 16 additions & 3 deletions Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -2067,12 +2067,25 @@ static ZEND_COLD void zend_binary_assign_op_dim_slow(zval *container, zval *dim
FREE_OP(free_op_data1);
}

static zend_never_inline zend_uchar slow_index_convert(const zval *dim, zend_value *value EXECUTE_DATA_DC)
static zend_never_inline zend_uchar slow_index_convert(HashTable *ht, const zval *dim, zend_value *value EXECUTE_DATA_DC)
{
switch (Z_TYPE_P(dim)) {
case IS_UNDEF:
case IS_UNDEF: {
/* The array may be destroyed while throwing the notice.
* Temporarily increase the refcount to detect this situation. */
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
GC_ADDREF(ht);
}
ZVAL_UNDEFINED_OP2();
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
zend_array_destroy(ht);
return IS_NULL;
}
if (EG(exception)) {
return IS_NULL;
}
/* break missing intentionally */
}
case IS_NULL:
value->str = ZSTR_EMPTY_ALLOC();
return IS_STRING;
Expand Down Expand Up @@ -2182,7 +2195,7 @@ static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht
goto try_again;
} else {
zend_value val;
zend_uchar t = slow_index_convert(dim, &val EXECUTE_DATA_CC);
zend_uchar t = slow_index_convert(ht, dim, &val EXECUTE_DATA_CC);

if (t == IS_STRING) {
offset_key = val.str;
Expand Down

0 comments on commit 62bec0e

Please sign in to comment.