diff --git a/Zend/tests/gh23332.phpt b/Zend/tests/gh23332.phpt new file mode 100644 index 000000000000..29e170bebe35 --- /dev/null +++ b/Zend/tests/gh23332.phpt @@ -0,0 +1,37 @@ +--TEST-- +GH-23332: Saturation of ArrayObject iterator leads to UAF +--FILE-- + 1337]); + +$iterators = []; +for ($i = 0; $i < 255; $i++) { + $it = $owner->getIterator(); + $it->rewind(); + $iterators[] = $it; +} +unset($it); + +$array = (array) $owner; + +$pass = 0; +$retained = null; +foreach ($array as &$value) { + if (++$pass === 1) { + $retained = $array; + $array = ['replacement' => 4242]; + continue; + } + for ($i = 0; $i < 254; $i++) { + unset($iterators[$i]); + } + $retained = null; + unset($iterators[254]); +} + +echo "done\n"; +var_dump($pass); +?> +--EXPECT-- +done +int(2) diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 82d0318428fa..552ed0919753 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -632,7 +632,7 @@ ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos_ex(uint32_t idx, zval ZEND_ASSERT(idx != (uint32_t)-1); if (UNEXPECTED(iter->ht != ht) && !zend_hash_iterator_find_copy_pos(idx, ht)) { if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR) - && EXPECTED(!HT_ITERATORS_OVERFLOW(ht))) { + && EXPECTED(!HT_ITERATORS_OVERFLOW(iter->ht))) { HT_DEC_ITERATORS_COUNT(iter->ht); }