diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | Zend/tests/bug79793.phpt | 32 | ||||
-rw-r--r-- | Zend/zend_execute.c | 7 |
3 files changed, 40 insertions, 1 deletions
@@ -23,6 +23,8 @@ PHP NEWS (Nikita) . Fixed bug #79784 (Use after free if changing array during undef var during array write fetch). (Nikita) + . Fixed bug #79793 (Use after free if string used in undefined index warning + is changed). (Nikita) - Fileinfo: . Fixed bug #79756 (finfo_file crash (FILEINFO_MIME)). (cmb) diff --git a/Zend/tests/bug79793.phpt b/Zend/tests/bug79793.phpt new file mode 100644 index 0000000000..9e4e2e20be --- /dev/null +++ b/Zend/tests/bug79793.phpt @@ -0,0 +1,32 @@ +--TEST-- +Bug #79793: Use after free if string used in undefined index warning is changed +--FILE-- +<?php + +$key = "foo"; +$key .= "bar"; +set_error_handler(function($_, $m) use (&$key) { + echo "$m\n"; + $key .= "baz"; +}); + +$ary = []; +$ary[$key]++; +var_dump($ary); +$ary[$key] += 1; +var_dump($ary); + +?> +--EXPECT-- +Undefined index: foobar +array(1) { + ["foobar"]=> + int(1) +} +Undefined index: foobarbaz +array(2) { + ["foobar"]=> + int(1) + ["foobarbaz"]=> + int(1) +} diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 5aed92ff45..59c151fe66 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2181,10 +2181,15 @@ str_index: retval = &EG(uninitialized_zval); break; case BP_VAR_RW: + /* Key may be released while throwing the undefined index warning. */ + zend_string_addref(offset_key); if (UNEXPECTED(zend_undefined_index_write(ht, offset_key) == FAILURE)) { + zend_string_release(offset_key); return NULL; } - /* break missing intentionally */ + retval = zend_hash_add_new(ht, offset_key, &EG(uninitialized_zval)); + zend_string_release(offset_key); + break; case BP_VAR_W: retval = zend_hash_add_new(ht, offset_key, &EG(uninitialized_zval)); break; |