php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81587 MultipleIterator Segmentation fault w/ SimpleXMLElement attached
Submitted: 2021-11-03 14:01 UTC Modified: 2021-11-04 09:28 UTC
From: hanskrentel at yahoo dot de Assigned:
Status: Closed Package: SPL related
PHP Version: 8.0.12 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: hanskrentel at yahoo dot de
New email:
PHP Version: OS:

 

 [2021-11-03 14:01 UTC] hanskrentel at yahoo dot de
Description:
------------
Since PHP 8.0 SimpleXMLElement is an Iterator and it is
possibe to attach it to a MultipleIterator (TypeError earlier).

Attached to a MultipleIterator and iterating the MultipleIterator makes
PHP exit code 139 (interrupted by signal 11: SIGSEGV - Segmentation fault)

Starting with PHP 8.1rc1 this is not an issue any longer.

Test script:
---------------
$mi = new MultipleIterator();
$mi->attachIterator(new SimpleXMLElement('<r/>'));
$mi->rewind();

Expected result:
----------------
Process exited with code 0

Actual result:
--------------
Output for 8.0.0 - 8.0.12: Process exited with code 139.
https://3v4l.org/DhLc0

A workaround is available: Wrapping the SimpleXMLElement inside an
IteratorIterator prevents the segmentation fault:

$mi = new MultipleIterator();
$mi->attachIterator(new IteratorIterator(new SimpleXMLElement('<r/>')));
$mi->rewind();

https://3v4l.org/C962A

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-11-03 19:19 UTC] requinix@php.net
-Status: Open +Status: Verified
 [2021-11-03 19:19 UTC] requinix@php.net
0x0000555555c77eef in zend_call_method (object=0x7ffff4481060, obj_ce=0x555556e52730, fn_proxy=0x28, function_name=0x5555566743da "rewind", function_name_len=6,
    retval_ptr=0x0, param_count=0, arg1=0x0, arg2=0x0) at /home/ubuntu/php/php-8.0.12/src/Zend/zend_interfaces.c:54
54              if (!fn_proxy || !*fn_proxy) {

(gdb) bt
#0  0x0000555555c77eef in zend_call_method (object=0x7ffff4481060, obj_ce=0x555556e52730, fn_proxy=0x28, function_name=0x5555566743da "rewind", function_name_len=6,
    retval_ptr=0x0, param_count=0, arg1=0x0, arg2=0x0) at /home/ubuntu/php/php-8.0.12/src/Zend/zend_interfaces.c:54
#1  0x00005555559f4684 in zim_MultipleIterator_rewind (execute_data=0x7ffff44140f0, return_value=0x7fffffffa740)
    at /home/ubuntu/php/php-8.0.12/src/ext/spl/spl_observer.c:1032
#2  0x0000555555bfd061 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER () at /home/ubuntu/php/php-8.0.12/src/Zend/zend_vm_execute.h:1755
#3  0x0000555555c6cd87 in execute_ex (ex=0x7ffff4414020) at /home/ubuntu/php/php-8.0.12/src/Zend/zend_vm_execute.h:54199
#4  0x0000555555c724e8 in zend_execute (op_array=0x7ffff445d280, return_value=0x0) at /home/ubuntu/php/php-8.0.12/src/Zend/zend_vm_execute.h:58518
#5  0x0000555555bc2e77 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/ubuntu/php/php-8.0.12/src/Zend/zend.c:1680
#6  0x0000555555b2425c in php_execute_script (primary_file=0x7fffffffcf40) at /home/ubuntu/php/php-8.0.12/src/main/main.c:2524
#7  0x0000555555cb34b7 in do_cli (argc=2, argv=0x555556c2df00) at /home/ubuntu/php/php-8.0.12/src/sapi/cli/php_cli.c:949
#8  0x0000555555cb4513 in main (argc=2, argv=0x555556c2df00) at /home/ubuntu/php/php-8.0.12/src/sapi/cli/php_cli.c:1337
 [2021-11-04 09:28 UTC] nikic@php.net
The fix in PHP 8.1 here is somewhat accidental: When class declarations were migrated to stubs, the declaration order was changed: Now we generally always implement Iterator before assigning get_iterator. This means that the code in zend_implement_iterator that avoids initializing iterator_funcs_ptr for custom get_iterator will no longer trigger in practice, and iterator_funcs_ptr will always be allocated. To avoid confusion and subtle dependency on class initialization order, the special handling there should probably get dropped and iterator_funcs_ptr be initialized unconditionally.

As far as MultipleIterator is concerned, I'd say the proper fix here would be to go through the get_iterator interface rather than manually calling Iterator methods. But as MultipleIterator is based on SplObjectStorage in a weird way, we can't easily do this. So we should just check whether iterator_funcs_ptr is null  for PHP 8.0.
 [2021-11-04 09:39 UTC] git@php.net
Automatic comment on behalf of nikic
Revision: https://github.com/php/php-src/commit/4b9fbc6627cc17869fb43826e30299f6e716178b
Log: Fixed bug #81587
 [2021-11-04 09:39 UTC] git@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 04:01:29 2024 UTC