Skip to content

Commit

Permalink
Fix GH-14741: Segmentation fault in Zend/zend_types.h
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nielsdos committed Jul 8, 2024
1 parent 43e3f57 commit eb8c3cb
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 0 deletions.
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ PHP NEWS
. Fixed bug GH-14590 (Memory leak in FPM test gh13563-conf-bool-env.phpt.
(nielsdos)
. Fixed OSS-Fuzz #69765. (nielsdos)
. Fixed bug GH-14741 (Segmentation fault in Zend/zend_types.h). (nielsdos)

- Dom:
. Fixed bug GH-14702 (DOMDocument::xinclude() crash). (nielsdos)
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_interfaces.c
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,7 @@ ZEND_API void zend_register_interfaces(void)

memcpy(&zend_internal_iterator_handlers, zend_get_std_object_handlers(),
sizeof(zend_object_handlers));
zend_internal_iterator_handlers.clone_obj = NULL;
zend_internal_iterator_handlers.free_obj = zend_internal_iterator_free;
}
/* }}} */
17 changes: 17 additions & 0 deletions ext/zend_test/tests/gh14741.phpt
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit eb8c3cb

Please sign in to comment.