Fix GH-14741: Segmentation fault in Zend/zend_types.h

The create_obj handler of InternalIterator is overwritten, but not the
clone_obj handler. This is not allowed.
In PHP 8.2 this didn't cause a segfault because the standard object
handler was used for the clone instead of the internal handler.
So then it allocates and frees the object using the standard object handlers.
In 8.3 however, the object is created using the standard object handler and
freed using the custom handler, resulting in the buffer overflow.
Even though bisect points to 1e1ea4f this only reveals the bug.

Closes GH-14882.
This commit is contained in:
Niels Dossche 2024-07-09 00:14:28 +02:00
parent 43e3f577b9
commit eb8c3cb79a
No known key found for this signature in database
GPG key ID: B8A8AD166DF0E2E5
3 changed files with 19 additions and 0 deletions

1
NEWS
View file

@ -9,6 +9,7 @@ PHP NEWS
. Fixed bug GH-14590 (Memory leak in FPM test gh13563-conf-bool-env.phpt. . Fixed bug GH-14590 (Memory leak in FPM test gh13563-conf-bool-env.phpt.
(nielsdos) (nielsdos)
. Fixed OSS-Fuzz #69765. (nielsdos) . Fixed OSS-Fuzz #69765. (nielsdos)
. Fixed bug GH-14741 (Segmentation fault in Zend/zend_types.h). (nielsdos)
- Dom: - Dom:
. Fixed bug GH-14702 (DOMDocument::xinclude() crash). (nielsdos) . Fixed bug GH-14702 (DOMDocument::xinclude() crash). (nielsdos)

View file

@ -666,6 +666,7 @@ ZEND_API void zend_register_interfaces(void)
memcpy(&zend_internal_iterator_handlers, zend_get_std_object_handlers(), memcpy(&zend_internal_iterator_handlers, zend_get_std_object_handlers(),
sizeof(zend_object_handlers)); sizeof(zend_object_handlers));
zend_internal_iterator_handlers.clone_obj = NULL;
zend_internal_iterator_handlers.free_obj = zend_internal_iterator_free; zend_internal_iterator_handlers.free_obj = zend_internal_iterator_free;
} }
/* }}} */ /* }}} */

View file

@ -0,0 +1,17 @@
--TEST--
GH-14741 (Segmentation fault in Zend/zend_types.h)
--EXTENSIONS--
zend_test
--FILE--
<?php
$subject = new \ZendTest\Iterators\TraversableTest();
$it = $subject->getIterator();
try {
clone $it;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECT--
Trying to clone an uncloneable object of class InternalIterator
TraversableTest::drop