php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #66609 php crashes with __get() and ++ operator in some cases
Submitted: 2014-01-30 04:23 UTC Modified: 2015-03-06 09:27 UTC
From: drewparoski at gmail dot com Assigned: laruence
Status: Closed Package: Reproducible crash
PHP Version: 5.5.8 OS: CentOS Linux 6.3
Private report: No CVE-ID:
 [2014-01-30 04:23 UTC] drewparoski at gmail dot com
Description:
------------
When I run the test script under PHP 5.6.0alpha1 (downloaded and built today from http://downloads.php.net/tyrael/php-5.6.0alpha1.tar.gz), it causes the php process to crash. I can consistently reproduce this problem on my machine. I've also been able to reproduce it with various builds of PHP 5.5.0.

I've included the backtrace from the crash.

Test script:
---------------
<?php
$bar = new Bar;
$foo = new Foo;
class Bar {
  public function __get($x) {
    global $foo;
    $foo->asd++;
  }
}
class Foo {
  public function __get($x) {
    global $bar;
    $bar->lol++;
  }
}
$foo->blah++;
echo "Done\n";

Expected result:
----------------
Done


Actual result:
--------------
... the php process crashes, below is the stacktrace from the coredump ...

Core was generated by `/opt/bin/php segv.php'.
Program terminated with signal 11, Segmentation fault.
#0  0x00000000007462ef in zend_post_incdec_property_helper_SPEC_CV_CONST (
    incdec_op=0x6b7db0 <increment_function>, execute_data=0x7f0734740238)
    at /data/users/andrewparoski/php-5.6.0alpha1/Zend/zend_vm_execute.h:32154
32154				Z_OBJ_HT_P(object)->write_property(object, property, z_copy, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
(gdb) bt
#0  0x00000000007462ef in zend_post_incdec_property_helper_SPEC_CV_CONST (
    incdec_op=0x6b7db0 <increment_function>, execute_data=0x7f0734740238)
    at /data/users/andrewparoski/php-5.6.0alpha1/Zend/zend_vm_execute.h:32154
#1  0x0000000000727f20 in execute_ex (execute_data=0x7f0734740238)
    at /data/users/andrewparoski/php-5.6.0alpha1/Zend/zend_vm_execute.h:363
#2  0x00000000006bb6e9 in zend_execute_scripts (type=8, retval=0x0,
    file_count=3) at /data/users/andrewparoski/php-5.6.0alpha1/Zend/zend.c:1330
#3  0x000000000065bec9 in php_execute_script (primary_file=0x7fffa7647360)
    at /data/users/andrewparoski/php-5.6.0alpha1/main/main.c:2542
#4  0x000000000075e7fc in do_cli (argc=2, argv=0xdd2000)
    at /data/users/andrewparoski/php-5.6.0alpha1/sapi/cli/php_cli.c:994
#5  0x000000000075ef98 in main (argc=2, argv=0xdd2000)
    at /data/users/andrewparoski/php-5.6.0alpha1/sapi/cli/php_cli.c:1378


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-01-30 06:20 UTC] krakjoe@php.net
looks an awful look like infinite recursion to me ...
 [2014-01-30 08:56 UTC] drewparoski at gmail dot com
If you add an echo statement to each __get() method, you can see that Bar::__get() and Foo::__get() collectively only get called 3 times before the crash happens. So I don't think the php process is crashing because of stack overflow in this case. Looking at the faulting machine instruction in gdb (which tries to dereference $rax when it is 0), I think that either Z_OBJ_HT_P(object) is null or Z_OBJ_HT_P(object)->write_property is null for some reason.
 [2014-02-04 01:38 UTC] drewparoski at gmail dot com
-PHP Version: 5.6.0alpha1 +PHP Version: 5.5.8
 [2014-02-04 01:38 UTC] drewparoski at gmail dot com
Verified this happens on PHP 5.5.8, which is the current official release. Updated the version number for this bug accordingly, though it's worth noting this bug still happens on PHP 5.6.0alpha1 as well.
 [2015-02-17 01:32 UTC] vort dot fu at gmail dot com
definitely not recursion related.

(gdb) r poc-php-66609.php 0x12345678
Starting program: /Users/vortfu/Downloads/php-5.6.5/sapi/cli/php poc-php-66609.php 0x12345678

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000012345678
 [2015-03-06 09:05 UTC] laruence@php.net
-Assigned To: +Assigned To: laruence
 [2015-03-06 09:27 UTC] laruence@php.net
A more simple fix could be:

diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index a795a75..5945452 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -754,6 +754,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR
 				}
 				z = value;
 			}
+			object = *object_ptr;
 			ZVAL_COPY_VALUE(retval, z);
 			zendi_zval_copy_ctor(*retval);
 			ALLOC_ZVAL(z_copy);

thanks
 [2015-03-10 09:15 UTC] laruence@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=6a6c273893178bb9b59c117e31761fe0193d0c9f
Log: Fixed bug #66609 (php crashes with __get() and ++ operator in some cases)
 [2015-03-10 09:15 UTC] laruence@php.net
-Status: Assigned +Status: Closed
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Mon May 29 05:01:44 2017 UTC