From 69d75d731eb5cd8d322252b391be8130d4bc59df Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Wed, 12 Mar 2025 19:39:58 +0100 Subject: [PATCH] Fix GH-18018: RC1 data returned from offsetGet causes UAF in ArrayObject We should first check truthiness and only after that destroy the value. --- ext/spl/spl_array.c | 6 ++++-- ext/spl/tests/gh18018.phpt | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 ext/spl/tests/gh18018.phpt diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index bd03a8aae0189..8d4541797a1c5 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -641,12 +641,14 @@ static bool spl_array_has_dimension_ex(bool check_inherited, zend_object *object } } + /* empty() check the value is not falsy, isset() only check it is not null */ + bool result = check_empty ? zend_is_true(value) : Z_TYPE_P(value) != IS_NULL; + if (value == &rv) { zval_ptr_dtor(&rv); } - /* empty() check the value is not falsy, isset() only check it is not null */ - return check_empty ? zend_is_true(value) : Z_TYPE_P(value) != IS_NULL; + return result; } /* }}} */ static int spl_array_has_dimension(zend_object *object, zval *offset, int check_empty) /* {{{ */ diff --git a/ext/spl/tests/gh18018.phpt b/ext/spl/tests/gh18018.phpt new file mode 100644 index 0000000000000..06fa7fc3d0e55 --- /dev/null +++ b/ext/spl/tests/gh18018.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-18018 (RC1 data returned from offsetGet causes UAF in ArrayObject) +--FILE-- + 1]; + +$object = new Crap($values); + +var_dump(empty($object['qux'])); +?> +--EXPECT-- +bool(false)