Skip to content

Commit 29dd6eb

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

File tree

4 files changed

+80
-0
lines changed

4 files changed

+80
-0
lines changed
Lines changed: 26 additions & 0 deletions
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
Lines changed: 24 additions & 0 deletions
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
Lines changed: 22 additions & 0 deletions
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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,14 @@ static void zend_calc_live_ranges(
940940
opnum--;
941941
opline--;
942942

943+
/* SEPARATE always redeclares its op1. For the purposes of live-ranges,
944+
* its declaration is irrelevant. Don't terminate the current live-range
945+
* to avoid breaking special handling of COPY_TMP. */
946+
if (opline->opcode == ZEND_SEPARATE) {
947+
ZEND_ASSERT(opline->op1.var == opline->result.var);
948+
continue;
949+
}
950+
943951
if ((opline->result_type & (IS_TMP_VAR|IS_VAR)) && !is_fake_def(opline)) {
944952
uint32_t var_num = EX_VAR_TO_NUM(opline->result.var) - var_offset;
945953
/* Defs without uses can occur for two reasons: Either because the result is

0 commit comments

Comments
 (0)