Fix GH-11016: Heap buffer overflow in ZEND_ADD_ARRAY_UNPACK_SPEC_HANDLER (#11021)

Not enough space was reserved for the packed resulting array because of
some confusion in the meaning of nr of used slots vs nr of elements.

Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
This commit is contained in:
Niels Dossche 2023-04-06 21:55:11 +02:00 committed by GitHub
parent 2ef1930ad3
commit ede8adb2e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 2 deletions

20
Zend/tests/gh11016.phpt Normal file
View file

@ -0,0 +1,20 @@
--TEST--
GH-11016 (Heap buffer overflow in ZEND_ADD_ARRAY_UNPACK_SPEC_HANDLER)
--FILE--
<?php
function number() {
return 6;
}
// We need to use a function to trick the optimizer *not* to optimize the array to a constant
$x = [number() => 0, ...[1, 1, 1]];
print_r($x);
?>
--EXPECT--
Array
(
[6] => 0
[7] => 1
[8] => 1
[9] => 1
)

View file

@ -6128,7 +6128,7 @@ ZEND_VM_C_LABEL(add_unpack_again):
zval *val;
if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) {
zend_hash_extend(result_ht, zend_hash_num_elements(result_ht) + zend_hash_num_elements(ht), 1);
zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1);
ZEND_HASH_FILL_PACKED(result_ht) {
ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
if (UNEXPECTED(Z_ISREF_P(val)) &&

View file

@ -2652,7 +2652,7 @@ add_unpack_again:
zval *val;
if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) {
zend_hash_extend(result_ht, zend_hash_num_elements(result_ht) + zend_hash_num_elements(ht), 1);
zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1);
ZEND_HASH_FILL_PACKED(result_ht) {
ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
if (UNEXPECTED(Z_ISREF_P(val)) &&