Bug #65784 [Asn->Csd]: Segfault with finally
| From: | nikic@php.net | Date: | Wed, 11 May 2016 14:27:55 +0000 |
| Subject: | Bug #65784 [Asn->Csd]: Segfault with finally | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-201015@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=65784&edit=1
ID: 65784
Updated by: nikic@php.net
Reported by: r dot wilczek at web-appz dot de
Summary: Segfault with finally
-Status: Assigned
+Status: Closed
Type: Bug
Package: *General Issues
Operating System: Linux
PHP Version: 5.5.4
Assigned To: laruence
Block user comment: N
Private report: N
New Comment:
Closing this as it's fixed in 5.6 and 5.5 is no longer supported for bugfixes.
Previous Comments:
------------------------------------------------------------------------
[2014-04-10 14:08:43] tony2001@php.net
Related To: Bug #67037
------------------------------------------------------------------------
[2013-12-13 07:39:51] laruence@php.net
unfortunately, this bug only fixed in 5.6 +, we can not apply the fix to 5.5 because of ABI BC.
https://github.com/php/php-src/commit/794a888a48715af5a97e3af9a8bdd88b20432f53
thanks
------------------------------------------------------------------------
[2013-12-09 03:24:23] phpmpan at mpan dot pl
Minimal code to reproduce:
-------------------------------------------------------
function foo() {
try {
throw new \Exception();
return true;
} finally {
try {
throw new \Exception();
} catch (\Exception $e) {
}
}
}
$bar = foo();
-------------------------------------------------------
Clean gdb backtrace from
php -f for master snap:
-------------------------------------------------------
#0 0x0000000000639587 in zval_isref_p (pz=0x0)
at /tmp/php-master-201312082230/Zend/zend.h:415
#1 0x000000000063d47f in zend_assign_to_variable (variable_ptr_ptr=0x7ffff7fc3bc0,
value=0x0) at /tmp/php-master-201312082230/Zend/zend_execute.c:916
#2 0x000000000069d558 in ZEND_ASSIGN_SPEC_CV_VAR_HANDLER (execute_data=0x7ffff7f891f0)
at /tmp/php-master-201312082230/Zend/zend_vm_execute.h:36797
#3 0x000000000063f4dd in execute_ex (execute_data=0x7ffff7f891f0)
at /tmp/php-master-201312082230/Zend/zend_vm_execute.h:363
#4 0x000000000063f54e in zend_execute (op_array=0x7ffff7fc0498)
at /tmp/php-master-201312082230/Zend/zend_vm_execute.h:388
#5 0x0000000000600773 in zend_execute_scripts (type=8, retval=0x0, file_count=3)
at /tmp/php-master-201312082230/Zend/zend.c:1334
#6 0x000000000057a2b9 in php_execute_script (primary_file=0x7fffffffe490)
at /tmp/php-master-201312082230/main/main.c:2507
#7 0x00000000006a8cf6 in do_cli (argc=3, argv=0xa3ba90)
at /tmp/php-master-201312082230/sapi/cli/php_cli.c:994
#8 0x00000000006a9cc4 in main (argc=3, argv=0xa3ba90)
at /tmp/php-master-201312082230/sapi/cli/php_cli.c:1378
-------------------------------------------------------
A quick dive into the code suggests that something bad happens around the catch. After this piece of
code FAST_RET, instead of passing the outer exception higher, goes to ASSIGN. However, the function
never provides a return value to copy from and as a result an unexpected NULL flies
around ZEND_ASSIGN_SPEC_CV_VAR_HANDLER.
------------------------------------------------------------------------
[2013-11-25 20:33:43] crussell52 at gmail dot com
core-dump info from my example:
#0 zval_delref_p (execute_data=0xb7f12234) at /opt/src/apache2.4/php-5.5.5/Zend/zend.h:409
#1 zend_pzval_unlock_func (execute_data=0xb7f12234) at
/opt/src/apache2.4/php-5.5.5/Zend/zend_execute.c:72
#2 _get_zval_ptr_var (execute_data=0xb7f12234) at
/opt/src/apache2.4/php-5.5.5/Zend/zend_execute.c:186
#3 ZEND_ASSIGN_SPEC_CV_VAR_HANDLER (execute_data=0xb7f12234) at
/opt/src/apache2.4/php-5.5.5/Zend/zend_vm_execute.h:36995
#4 0x012b7496 in execute_ex (execute_data=0xb7f12234) at
/opt/src/apache2.4/php-5.5.5/Zend/zend_vm_execute.h:363
#5 0x007f3f35 in xdebug_execute_ex (execute_data=0xb7f12234) at
/opt/src/apache2.4/xdebug-2.2.3/xdebug.c:1437
#6 0x012cf5cf in ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER (execute_data=0xb7f12160) at
/opt/src/apache2.4/php-5.5.5/Zend/zend_vm_execute.h:13418
#7 0x012b7496 in execute_ex (execute_data=0xb7f12160) at
/opt/src/apache2.4/php-5.5.5/Zend/zend_vm_execute.h:363
#8 0x007f3f35 in xdebug_execute_ex (execute_data=0xb7f12160) at
/opt/src/apache2.4/xdebug-2.2.3/xdebug.c:1437
#9 0x01286fe5 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at
/opt/src/apache2.4/php-5.5.5/Zend/zend.c:1320
#10 0x0122a3cf in php_execute_script (primary_file=0xbfd233c0) at
/opt/src/apache2.4/php-5.5.5/main/main.c:2489
#11 0x0132812b in php_handler (r=0x9eb98c8) at
/opt/src/apache2.4/php-5.5.5/sapi/apache2handler/sapi_apache2.c:667
#12 0x08098037 in ?? ()
------------------------------------------------------------------------
[2013-11-25 20:16:54] crussell52 at gmail dot com
The following script in php 5.5.5 demonstrates this problem.
Note, my testing indicates that all of these conditions must be true:
1. Exception is thrown in try block.
2. An Exception is thrown AND handled during execution of
the corresponding finally block.
3. The return value must be referenced.
-----------------
class Executor
{
public function go()
{
try
{
// 1. Throw exception in try block.
throw new Exception("Failed to do something!");
return true;
}
finally
{
// 2. Throw and handle exception within finally block.
// Note, this step could occur in a function/method which
// is called within the finally block.
try
{
throw new Exception("Failed to clean up.");
}
catch (Exception $E) { /* Ignore */ }
}
}
}
$Executor = new Executor();
// 3. Reference the return value.
$value = $Executor->go();
-----------------
#3 is interesting and threw me off a bit while trying to come up
with a reproduction script. See the following variations and
outcome:
$value = $Executor->go(); // fail
echo $Executor->go(); // fail
$Executor->go(); // success
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=65784
--
Edit this bug report at https://bugs.php.net/bug.php?id=65784&edit=1