Skip to content

Commit 27affd8

Browse files
committed
Fix GH-18018: RC1 data returned from offsetGet causes UAF in ArrayObject
We should first check truthiness and only after that destroy the value. Closes GH-18034.
1 parent 945f5b8 commit 27affd8

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ PHP NEWS
2020
. Fixed bug GH-17989 (mb_output_handler crash with unset
2121
http_output_conv_mimetypes). (nielsdos)
2222

23+
- SPL:
24+
. Fixed bug GH-18018 (RC1 data returned from offsetGet causes UAF in
25+
ArrayObject). (nielsdos)
26+
2327
- Treewide:
2428
. Fixed bug GH-17736 (Assertion failure zend_reference_destroy()). (nielsdos)
2529

ext/spl/spl_array.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -641,12 +641,14 @@ static bool spl_array_has_dimension_ex(bool check_inherited, zend_object *object
641641
}
642642
}
643643

644+
/* empty() check the value is not falsy, isset() only check it is not null */
645+
bool result = check_empty ? zend_is_true(value) : Z_TYPE_P(value) != IS_NULL;
646+
644647
if (value == &rv) {
645648
zval_ptr_dtor(&rv);
646649
}
647650

648-
/* empty() check the value is not falsy, isset() only check it is not null */
649-
return check_empty ? zend_is_true(value) : Z_TYPE_P(value) != IS_NULL;
651+
return result;
650652
} /* }}} */
651653

652654
static int spl_array_has_dimension(zend_object *object, zval *offset, int check_empty) /* {{{ */

ext/spl/tests/gh18018.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
GH-18018 (RC1 data returned from offsetGet causes UAF in ArrayObject)
3+
--FILE--
4+
<?php
5+
class Crap extends ArrayObject
6+
{
7+
public function offsetGet($offset): mixed
8+
{
9+
return [random_int(1,1)];
10+
}
11+
}
12+
13+
$values = ['qux' => 1];
14+
15+
$object = new Crap($values);
16+
17+
var_dump(empty($object['qux']));
18+
?>
19+
--EXPECT--
20+
bool(false)

0 commit comments

Comments
 (0)