mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix use-after-free of name in var-var with malicious error handler
Fixes oss-fuzz #54325 Closes GH-12732
This commit is contained in:
4
NEWS
4
NEWS
@@ -2,6 +2,10 @@ PHP NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
?? ??? ????, PHP 8.1.27
|
||||
|
||||
- Core:
|
||||
. Fixed oss-fuzz #54325 (Use-after-free of name in var-var with malicious
|
||||
error handler). (ilutov)
|
||||
|
||||
- DOM:
|
||||
. Fixed bug GH-12616 (DOM: Removing XMLNS namespace node results in invalid
|
||||
default: prefix). (nielsdos)
|
||||
|
||||
19
Zend/tests/oss_fuzz_54325.phpt
Normal file
19
Zend/tests/oss_fuzz_54325.phpt
Normal file
@@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
oss-fuzz #54325: Fix use-after-free of name in var-var with malicious error handler
|
||||
--FILE--
|
||||
<?php
|
||||
set_error_handler(function ($errno, $errstr) {
|
||||
var_dump($errstr);
|
||||
global $x;
|
||||
$x = new stdClass;
|
||||
});
|
||||
|
||||
// Needs to be non-interned string
|
||||
$x = strrev('foo');
|
||||
$$x++;
|
||||
var_dump($x);
|
||||
?>
|
||||
--EXPECT--
|
||||
string(23) "Undefined variable $oof"
|
||||
object(stdClass)#2 (0) {
|
||||
}
|
||||
@@ -1748,6 +1748,10 @@ ZEND_VM_C_LABEL(fetch_this):
|
||||
} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
|
||||
retval = &EG(uninitialized_zval);
|
||||
} else {
|
||||
if (OP1_TYPE == IS_CV) {
|
||||
/* Keep name alive in case an error handler tries to free it. */
|
||||
zend_string_addref(name);
|
||||
}
|
||||
zend_error(E_WARNING, "Undefined %svariable $%s",
|
||||
(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), ZSTR_VAL(name));
|
||||
if (type == BP_VAR_RW && !EG(exception)) {
|
||||
@@ -1755,6 +1759,9 @@ ZEND_VM_C_LABEL(fetch_this):
|
||||
} else {
|
||||
retval = &EG(uninitialized_zval);
|
||||
}
|
||||
if (OP1_TYPE == IS_CV) {
|
||||
zend_string_release(name);
|
||||
}
|
||||
}
|
||||
/* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
|
||||
} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
|
||||
|
||||
@@ -9755,6 +9755,10 @@ fetch_this:
|
||||
} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
|
||||
retval = &EG(uninitialized_zval);
|
||||
} else {
|
||||
if (IS_CONST == IS_CV) {
|
||||
/* Keep name alive in case an error handler tries to free it. */
|
||||
zend_string_addref(name);
|
||||
}
|
||||
zend_error(E_WARNING, "Undefined %svariable $%s",
|
||||
(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), ZSTR_VAL(name));
|
||||
if (type == BP_VAR_RW && !EG(exception)) {
|
||||
@@ -9762,6 +9766,9 @@ fetch_this:
|
||||
} else {
|
||||
retval = &EG(uninitialized_zval);
|
||||
}
|
||||
if (IS_CONST == IS_CV) {
|
||||
zend_string_release(name);
|
||||
}
|
||||
}
|
||||
/* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
|
||||
} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
|
||||
@@ -17560,6 +17567,10 @@ fetch_this:
|
||||
} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
|
||||
retval = &EG(uninitialized_zval);
|
||||
} else {
|
||||
if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
|
||||
/* Keep name alive in case an error handler tries to free it. */
|
||||
zend_string_addref(name);
|
||||
}
|
||||
zend_error(E_WARNING, "Undefined %svariable $%s",
|
||||
(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), ZSTR_VAL(name));
|
||||
if (type == BP_VAR_RW && !EG(exception)) {
|
||||
@@ -17567,6 +17578,9 @@ fetch_this:
|
||||
} else {
|
||||
retval = &EG(uninitialized_zval);
|
||||
}
|
||||
if ((IS_TMP_VAR|IS_VAR) == IS_CV) {
|
||||
zend_string_release(name);
|
||||
}
|
||||
}
|
||||
/* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
|
||||
} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
|
||||
@@ -47008,6 +47022,10 @@ fetch_this:
|
||||
} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
|
||||
retval = &EG(uninitialized_zval);
|
||||
} else {
|
||||
if (IS_CV == IS_CV) {
|
||||
/* Keep name alive in case an error handler tries to free it. */
|
||||
zend_string_addref(name);
|
||||
}
|
||||
zend_error(E_WARNING, "Undefined %svariable $%s",
|
||||
(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), ZSTR_VAL(name));
|
||||
if (type == BP_VAR_RW && !EG(exception)) {
|
||||
@@ -47015,6 +47033,9 @@ fetch_this:
|
||||
} else {
|
||||
retval = &EG(uninitialized_zval);
|
||||
}
|
||||
if (IS_CV == IS_CV) {
|
||||
zend_string_release(name);
|
||||
}
|
||||
}
|
||||
/* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
|
||||
} else if (Z_TYPE_P(retval) == IS_INDIRECT) {
|
||||
|
||||
Reference in New Issue
Block a user