Skip to content

Commit ea52706

Browse files
committed
Fix use-after-free of name in var-var with malicious error handler
Fixes oss-fuzz #54325 Closes phpGH-12732
1 parent 4d41dff commit ea52706

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.2.14
44

5+
- Core:
6+
. Fixed oss-fuzz #54325 (Use-after-free of name in var-var with malicious
7+
error handler). (ilutov)
8+
59
- DOM:
610
. Fixed bug GH-12616 (DOM: Removing XMLNS namespace node results in invalid
711
default: prefix). (nielsdos)

Zend/tests/oss_fuzz_54325.phpt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
oss-fuzz #54325: Fix use-after-free of name in var-var with malicious error handler
3+
--FILE--
4+
<?php
5+
set_error_handler(function ($errno, $errstr) {
6+
var_dump($errstr);
7+
global $x;
8+
$x = new stdClass;
9+
});
10+
11+
// Needs to be non-interned string
12+
$x = strrev('foo');
13+
$$x++;
14+
var_dump($x);
15+
?>
16+
--EXPECT--
17+
string(23) "Undefined variable $oof"
18+
object(stdClass)#2 (0) {
19+
}

Zend/zend_vm_def.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,13 +1748,20 @@ ZEND_VM_C_LABEL(fetch_this):
17481748
} else if (type == BP_VAR_IS || type == BP_VAR_UNSET) {
17491749
retval = &EG(uninitialized_zval);
17501750
} else {
1751+
if (OP1_TYPE == IS_CV) {
1752+
/* Keep name alive in case an error handler tries to free it. */
1753+
zend_string_addref(name);
1754+
}
17511755
zend_error(E_WARNING, "Undefined %svariable $%s",
17521756
(opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), ZSTR_VAL(name));
17531757
if (type == BP_VAR_RW && !EG(exception)) {
17541758
retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval));
17551759
} else {
17561760
retval = &EG(uninitialized_zval);
17571761
}
1762+
if (OP1_TYPE == IS_CV) {
1763+
zend_string_release(name);
1764+
}
17581765
}
17591766
/* GLOBAL or $$name variable may be an INDIRECT pointer to CV */
17601767
} else if (Z_TYPE_P(retval) == IS_INDIRECT) {

Zend/zend_vm_execute.h

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)