Skip to content

Commit ef2c459

Browse files
iluuu1994bukka
authored andcommitted
Use-after-free for ??= due to incorrect live-range calculation
Fixes GHSA-rwp7-7vc6-8477
1 parent acf2f49 commit ef2c459

5 files changed

+82
-0
lines changed

NEWS

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ PHP NEWS
3131
`__callStatic` is allowed). (timwolla)
3232
. Fixed bug GH-17797 (zend_test_compile_string crash on invalid
3333
script path). (David Carlier)
34+
. Fixed GHSA-rwp7-7vc6-8477 (Reference counting in php_request_shutdown
35+
causes Use-After-Free). (CVE-2024-11235) (ilutov)
3436

3537
- DOM:
3638
. Fixed bug GH-17847 (xinclude destroys live node). (nielsdos)
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
GHSA-rwp7-7vc6-8477: Use-after-free for ??= due to incorrect live-range calculation
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
public function foo() {
8+
return $this;
9+
}
10+
11+
public function __set($name, $value) {
12+
throw new Exception('Hello');
13+
}
14+
}
15+
16+
$foo = new Foo();
17+
18+
try {
19+
$foo->foo()->baz ??= 1;
20+
} catch (Exception $e) {
21+
echo $e->getMessage();
22+
}
23+
24+
?>
25+
--EXPECT--
26+
Hello
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
GHSA-rwp7-7vc6-8477: Use-after-free for ??= due to incorrect live-range calculation
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
public int $prop;
8+
9+
public function foo() {
10+
return $this;
11+
}
12+
}
13+
14+
$foo = new Foo();
15+
16+
try {
17+
$foo->foo()->prop ??= 'foo';
18+
} catch (Error $e) {
19+
echo $e->getMessage();
20+
}
21+
22+
?>
23+
--EXPECT--
24+
Cannot assign string to property Foo::$prop of type int
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
GHSA-rwp7-7vc6-8477: Use-after-free for ??= due to incorrect live-range calculation
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
public int $prop;
8+
}
9+
10+
function newFoo() {
11+
return new Foo();
12+
}
13+
14+
try {
15+
newFoo()->prop ??= 'foo';
16+
} catch (Error $e) {
17+
echo $e->getMessage();
18+
}
19+
20+
?>
21+
--EXPECT--
22+
Cannot assign string to property Foo::$prop of type int

Zend/zend_opcode.c

+8
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,14 @@ static void zend_calc_live_ranges(
922922
opnum--;
923923
opline--;
924924

925+
/* SEPARATE always redeclares its op1. For the purposes of live-ranges,
926+
* its declaration is irrelevant. Don't terminate the current live-range
927+
* to avoid breaking special handling of COPY_TMP. */
928+
if (opline->opcode == ZEND_SEPARATE) {
929+
ZEND_ASSERT(opline->op1.var == opline->result.var);
930+
continue;
931+
}
932+
925933
if ((opline->result_type & (IS_TMP_VAR|IS_VAR)) && !is_fake_def(opline)) {
926934
uint32_t var_num = EX_VAR_TO_NUM(opline->result.var) - var_offset;
927935
/* Defs without uses can occur for two reasons: Either because the result is

0 commit comments

Comments
 (0)