php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #63914 zend_do_fcall_common_helper_SPEC does not handle exceptions properly
Submitted: 2013-01-06 00:35 UTC Modified: 2013-03-25 03:16 UTC
Votes:1
Avg. Score:2.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: whatthejeff at gmail dot com Assigned: dmitry (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: Irrelevant OS: All
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: whatthejeff at gmail dot com
New email:
PHP Version: OS:

 

 [2013-01-06 00:35 UTC] whatthejeff at gmail dot com
Description:
------------
The `zend_verify_arg_type` check in `zend_do_fcall_common_helper_SPEC` can 
generate unhanded exceptions when a user-defined error handler is set. This can 
lead to the following unexpected behaviors:

 * xdebug (and similar extensions using `execute_internal`) with PHP <= 5.4 will 
segfault (http://bugs.xdebug.org/view.php?id=897)
 * xdebug (and similar extensions using `execute_internal`) with PHP 5.5+ will 
continue to execute the internal function in an inconsistant state.
 * PHP without xdebug-like extensions will continue to execute the internal 
function, even though it's unnecessary.

---

NOTE: I will send a pull request on github shortly.

Test script:
---------------
<?php
class PHPUnit_Util_ErrorHandler
{
    public static function handleError($errno, $errstr, $errfile, $errline)
    {
        throw new Exception;
    }
}

set_error_handler(
  array('PHPUnit_Util_ErrorHandler', 'handleError'),
  E_ALL | E_STRICT
);

$dom = new DOMDocument;
$dom->saveXML('foo');

Expected result:
----------------
Fatal error: Uncaught exception 'Exception' in 
/home/whatthejeff/php2/segfault.php:6
Stack trace:
#0 [internal function]: PHPUnit_Util_ErrorHandler::handleError(4096, 'Argument 1 
pass...', '/home/whattheje...', 16, Array)
#1 /home/whatthejeff/php2/segfault.php(16): DOMDocument->saveXML('foo')
#2 {main}
  thrown in /home/whatthejeff/php2/segfault.php on line 6

Actual result:
--------------
GDB session with PHP 5.4 / xdebug (edited for brevity):
-------------------------------------------------------

[whatthejeff@xdebug php2]$ gdb php

...

(gdb) break zend_vm_execute.h:628
Breakpoint 1 at 0x870e1d: file /home/whatthejeff/php2/Zend/zend_vm_execute.h, line 
628.
(gdb) break zend_vm_execute.h:639
Breakpoint 2 at 0x870eb8: file /home/whatthejeff/php2/Zend/zend_vm_execute.h, line 
639.
(gdb) run segfault.php
Starting program: /usr/local/bin/php segfault.php

...

Breakpoint 1, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac0f8, 
tsrm_ls=0xff0090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:629
629			if (fbc->common.arg_info) {
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.80.el6_3.6.x86_64 
nss-softokn-freebl-3.12.9-11.el6.x86_64 zlib-1.2.3-27.el6.x86_64
(gdb) c
Continuing.

Breakpoint 2, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac0f8, 
tsrm_ls=0xff0090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:640
640			if (!zend_execute_internal) {
(gdb) 
Continuing.

Breakpoint 1, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac0f8, 
tsrm_ls=0xff0090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:629
629			if (fbc->common.arg_info) {
(gdb) 
Continuing.

Breakpoint 2, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac0f8, 
tsrm_ls=0xff0090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:640
640			if (!zend_execute_internal) {
(gdb) 
Continuing.

Breakpoint 1, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac0f8, 
tsrm_ls=0xff0090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:629
629			if (fbc->common.arg_info) {
(gdb) 
Continuing.

Breakpoint 1, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac310, 
tsrm_ls=0xff0090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:629
629			if (fbc->common.arg_info) {
(gdb) 
Continuing.

Breakpoint 2, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac310, 
tsrm_ls=0xff0090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:640
640			if (!zend_execute_internal) {
(gdb) 
Continuing.

Breakpoint 2, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac0f8, 
tsrm_ls=0xff0090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:640
640			if (!zend_execute_internal) {
(gdb) step
644				zend_execute_internal(execute_data, 
RETURN_VALUE_USED(opline) TSRMLS_CC);
(gdb) 
xdebug_execute_internal (current_execute_data=0x7ffff7fac0f8, return_value_used=0, 
tsrm_ls=0xff0090) at /home/whatthejeff/xdebug/xdebug.c:1506

...

(gdb) 
1547			execute_internal(current_execute_data, return_value_used 
TSRMLS_CC);
(gdb) step
execute_internal (execute_data_ptr=0x7ffff7fac0f8, return_value_used=0, 
tsrm_ls=0xff0090) at /home/whatthejeff/php2/Zend/zend_execute.c:1479
1479		zval **return_value_ptr = &(*(temp_variable *)((char *) 
execute_data_ptr->Ts + execute_data_ptr->opline->result.var)).var.ptr;
(gdb) 
1480		((zend_internal_function *) execute_data_ptr-
>function_state.function)->handler(execute_data_ptr->opline->extended_value, 
*return_value_ptr, 
(execute_data_ptr->function_state.function->common.fn_flags & 
ZEND_ACC_RETURN_REFERENCE)?return_value_ptr:NULL, execute_data_ptr->object, 
return_value_used TSRMLS_CC);
(gdb) step
zif_dom_document_savexml (ht=0, return_value=0x0, return_value_ptr=0x0, 
this_ptr=0x7ffff7fe5e00, return_value_used=0, tsrm_ls=0xff0090) at 
/home/whatthejeff/php2/ext/dom/document.c:1790

...

1842			xmlDocDumpFormatMemory(docp, &mem, &size, format);
(gdb) 
1843			if (options & LIBXML_SAVE_NOEMPTYTAG) {
(gdb) 
1846			if (!size) {
(gdb) 
1849			RETVAL_STRINGL(mem, size, 1);
(gdb) 

Program received signal SIGSEGV, Segmentation fault.
0x00000000005778de in zif_dom_document_savexml (ht=0, return_value=0x0, 
return_value_ptr=0x0, this_ptr=0x7ffff7fe5e00, return_value_used=0, 
tsrm_ls=0xff0090)
    at /home/whatthejeff/php2/ext/dom/document.c:1849
1849			RETVAL_STRINGL(mem, size, 1);



GDB session with PHP 5.5 / xdebug (edited for brevity):
-------------------------------------------------------

whatthejeff@xdebug php2]$ gdb php

...

(gdb) break zend_vm_execute.h:532
Breakpoint 1 at 0x87a1b0: file /home/whatthejeff/php2/Zend/zend_vm_execute.h, line 
532.
(gdb) break zend_vm_execute.h:543
Breakpoint 2 at 0x87a24b: file /home/whatthejeff/php2/Zend/zend_vm_execute.h, line 
543.
(gdb) run segfault.php 
Starting program: /usr/local/bin/php segfault.php

...

Breakpoint 1, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac238, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:533
533			if (fbc->common.arg_info) {
(gdb) c
Continuing.

Breakpoint 2, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac238, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:544
544			if (!zend_execute_internal) {
(gdb) c
Continuing.

Breakpoint 1, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac238, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:533
533			if (fbc->common.arg_info) {
(gdb) c
Continuing.

Breakpoint 2, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac238, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:544
544			if (!zend_execute_internal) {
(gdb) c
Continuing.

Breakpoint 1, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac238, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:533
533			if (fbc->common.arg_info) {
(gdb) c
Continuing.

Breakpoint 1, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac380, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:533
533			if (fbc->common.arg_info) {
(gdb) c
Continuing.

Breakpoint 2, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac380, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:544
544			if (!zend_execute_internal) {
(gdb) c
Continuing.

Breakpoint 2, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac238, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:544
544			if (!zend_execute_internal) {
(gdb) n
548				zend_execute_internal(execute_data, NULL, 
RETURN_VALUE_USED(opline) TSRMLS_CC);
(gdb) step
xdebug_execute_internal (current_execute_data=0x7ffff7fac238, fci=0x0, 
return_value_used=0, tsrm_ls=0x100f090) at /home/whatthejeff/xdebug/xdebug.c:1506

...

1553			execute_internal(current_execute_data, fci, 
return_value_used TSRMLS_CC);
(gdb) step
execute_internal (execute_data_ptr=0x7ffff7fac238, fci=0x0, return_value_used=0, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_execute.c:1481

...

1487			((zend_internal_function *) execute_data_ptr-
>function_state.function)->handler(execute_data_ptr->opline->extended_value, 
*return_value_ptr,
(gdb) step
zif_dom_document_savexml (ht=0, return_value=0x10917c0, return_value_ptr=0x0, 
this_ptr=0x7ffff7fe3cc8, return_value_used=0, tsrm_ls=0x100f090) at 
/home/whatthejeff/php2/ext/dom/document.c:1790

...

1800		if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, 
getThis(), "O|O!l", &id, dom_document_class_entry, &nodep, dom_node_class_entry, 
&options) 
== FAILURE) {
(gdb) step
zend_parse_method_parameters (num_args=0, tsrm_ls=0x100f090, 
this_ptr=0x7ffff7fe3cc8, type_spec=0xa76075 "O|O!l") at 
/home/whatthejeff/php2/Zend/zend_API.c:906

...

zif_dom_document_savexml (ht=0, return_value=0x10917c0, return_value_ptr=0x0, 
this_ptr=0x7ffff7fe3cc8, return_value_used=0, tsrm_ls=0x100f090) at 
/home/whatthejeff/php2/ext/dom/document.c:1804
1804		DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
(gdb) 

...

(gdb) 
1849			RETVAL_STRINGL(mem, size, 1);
(gdb) 
1850			xmlFree(mem);



GDB session with PHP 5.5 (edited for brevity):
----------------------------------------------

[whatthejeff@xdebug php2]$ gdb php

...

(gdb) break zend_vm_execute.h:532
Breakpoint 1 at 0x87a1b0: file /home/whatthejeff/php2/Zend/zend_vm_execute.h, line 
532.
(gdb) break zend_vm_execute.h:543
Breakpoint 2 at 0x87a24b: file /home/whatthejeff/php2/Zend/zend_vm_execute.h, line 
543.
(gdb) run segfault.php
Starting program: /usr/local/bin/php segfault.php

...

Breakpoint 1, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac238, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:533
533			if (fbc->common.arg_info) {
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.80.el6_3.6.x86_64 
nss-softokn-freebl-3.12.9-11.el6.x86_64 zlib-1.2.3-27.el6.x86_64
(gdb) c
Continuing.

Breakpoint 2, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac238, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:544
544			if (!zend_execute_internal) {
(gdb) c
Continuing.

Breakpoint 1, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac238, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:533
533			if (fbc->common.arg_info) {
(gdb) c
Continuing.

Breakpoint 2, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac238, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:544
544			if (!zend_execute_internal) {
(gdb) c
Continuing.

Breakpoint 1, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac238, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:533
533			if (fbc->common.arg_info) {
(gdb) c
Continuing.

Breakpoint 1, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac380, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:533
533			if (fbc->common.arg_info) {
(gdb) c
Continuing.

Breakpoint 2, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac380, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:544
544			if (!zend_execute_internal) {
(gdb) c
Continuing.

Breakpoint 2, zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7fac238, 
tsrm_ls=0x100f090) at /home/whatthejeff/php2/Zend/zend_vm_execute.h:544
544			if (!zend_execute_internal) {
(gdb) step
546				fbc->internal_function.handler(opline-
>extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) 
? &ret->var.ptr 
: NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
(gdb) 
zif_dom_document_savexml (ht=1, return_value=0x7ffff7fe3918, return_value_ptr=0x0, 
this_ptr=0x7ffff7fe4e30, return_value_used=0, tsrm_ls=0x100f090)
    at /home/whatthejeff/php2/ext/dom/document.c:1790

...

(gdb) 
1800		if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, 
getThis(), "O|O!l", &id, dom_document_class_entry, &nodep, dom_node_class_entry, 
&options) 
== FAILURE) {
(gdb) 
1801			return;


Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-01-06 01:27 UTC] whatthejeff at gmail dot com
Pull request added: https://github.com/php/php-src/pull/250
 [2013-03-25 03:16 UTC] stas@php.net
Dmitry, could you review the proposed patch?
 [2013-03-25 03:16 UTC] stas@php.net
-Assigned To: +Assigned To: dmitry
 [2013-03-25 11:48 UTC] dmitry@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=c4686b4de93a89e8265331b0d4a6a7954ccbae95
Log: Fixed bug #63914 (zend_do_fcall_common_helper_SPEC does not handle exceptions properly). (Jeff Welch)
 [2013-03-25 11:48 UTC] dmitry@php.net
-Status: Assigned +Status: Closed
 [2013-03-25 11:49 UTC] dmitry@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=c4686b4de93a89e8265331b0d4a6a7954ccbae95
Log: Fixed bug #63914 (zend_do_fcall_common_helper_SPEC does not handle exceptions properly). (Jeff Welch)
 [2014-10-07 23:19 UTC] stas@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=c4686b4de93a89e8265331b0d4a6a7954ccbae95
Log: Fixed bug #63914 (zend_do_fcall_common_helper_SPEC does not handle exceptions properly). (Jeff Welch)
 [2014-10-07 23:30 UTC] stas@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=c4686b4de93a89e8265331b0d4a6a7954ccbae95
Log: Fixed bug #63914 (zend_do_fcall_common_helper_SPEC does not handle exceptions properly). (Jeff Welch)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 12:01:29 2024 UTC