1
0
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:
Ilija Tovilo
2023-11-20 11:56:06 +01:00
parent 4d41dffb4f
commit ea52706a2a
4 changed files with 51 additions and 0 deletions

4
NEWS
View File

@@ -2,6 +2,10 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 8.2.14
- 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)

View 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) {
}

View File

@@ -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) {

21
Zend/zend_vm_execute.h generated
View File

@@ -9859,6 +9859,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)) {
@@ -9866,6 +9870,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) {
@@ -17667,6 +17674,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)) {
@@ -17674,6 +17685,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) {
@@ -47240,6 +47254,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)) {
@@ -47247,6 +47265,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) {