php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70601 Segfault in gc_remove_from_buffer()
Submitted: 2015-09-29 03:45 UTC Modified: 2015-10-04 02:39 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:1 (50.0%)
From: p at wspnr dot com Assigned: laruence
Status: Closed Package: Reproducible crash
PHP Version: 5.6Git-2015-09-29 (Git) OS: Debian x86_64
Private report: No CVE-ID:
 [2015-09-29 03:45 UTC] p at wspnr dot com
Description:
------------
There is a reliable segfault observed in one of our applications. After the first segfault, each additional request also results in a segfault. The only solution is to restart PHP-FPM.

This has been tested and reproduced on several machines, all running Debian Jessie.

This bug has been observed on 5.6.12 and 5.6.15-dev (latest Git). It HAS NOT been observed on 7.0.0RC3 or 7.1.0-dev (latest Git).




 

Test script:
---------------
I have tried to create a short test script to reproduce the bug, but have been unsuccessful. It happens reliably in one high-load use case where 100+ requests are sent to the server almost concurrently. Each request creates many objects, so it is possible that GC is triggered. After ~30 requests are processed, the first crash happens.

Expected result:
----------------
No crash, or at least a sensible error message.

Actual result:
--------------
Core was generated by `php-fpm: pool www                                                 '.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00000000009fdc2e in gc_remove_from_buffer (root=0x596d7c <zm_startup_dom+20924>) at Zend/zend_gc.h:189
189             root->next->prev = root->prev;
(gdb) bt
#0  0x00000000009fdc2e in gc_remove_from_buffer (root=0x596d7c <zm_startup_dom+20924>) at Zend/zend_gc.h:189
#1  0x00000000009fdbf4 in gc_remove_zval_from_buffer (zv=0x7f3652bddda0) at Zend/zend_gc.c:260
#2  0x00000000009ad125 in i_zval_ptr_dtor (zval_ptr=0x7f3652bddda0, __zend_filename=0xf8eadb "/.../php-src/Zend/zend_variables.c", __zend_lineno=188) at Zend/zend_execute.h:78
#3  0x00000000009acc56 in _zval_ptr_dtor (zval_ptr=0x2840318, __zend_filename=0xf8eadb "/.../php-src/Zend/zend_variables.c", __zend_lineno=188) at Zend/zend_execute_API.c:424
#4  0x00000000009c4ba1 in _zval_ptr_dtor_wrapper (zval_ptr=0x2840318) at Zend/zend_variables.c:188
#5  0x00000000009dee9e in zend_hash_destroy (ht=0x283e678) at Zend/zend_hash.c:548
#6  0x00000000009c46f9 in _zval_dtor_func (zvalue=0x25fef38, __zend_filename=0xf8db06 "Zend/zend_execute.h", __zend_lineno=79) at Zend/zend_variables.c:45
#7  0x0000000000a7085c in _zval_dtor (zvalue=0x25fef38, __zend_filename=0xf8db06 "Zend/zend_execute.h", __zend_lineno=79) at Zend/zend_variables.h:35
#8  0x0000000000a7062a in i_zval_ptr_dtor (zval_ptr=0x25fef38, __zend_filename=0xf8db06 "Zend/zend_execute.h", __zend_lineno=308) at Zend/zend_execute.h:79
#9  0x0000000000a70727 in zend_vm_stack_clear_multiple (nested=0) at Zend/zend_execute.h:308
#10 0x0000000000a6f561 in zend_do_fcall_common_helper_SPEC (execute_data=0x2723740) at Zend/zend_vm_execute.h:650
#11 0x0000000000a2a873 in ZEND_DO_FCALL_SPEC_CONST_HANDLER (execute_data=0x2723740) at Zend/zend_vm_execute.h:2602
#12 0x0000000000a14138 in execute_ex (execute_data=0x2723740) at Zend/zend_vm_execute.h:363
#13 0x0000000000a1421e in zend_execute (op_array=0x275cf38) at Zend/zend_vm_execute.h:388
#14 0x00000000009c8e87 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at Zend/zend.c:1341
#15 0x00000000009139f8 in php_execute_script (primary_file=0x7ffe0a895820) at main/main.c:2597
#16 0x0000000000aa891b in main (argc=4, argv=0x7ffe0a8959a8) at /.../php-src/sapi/fpm/fpm/fpm_main.c:1964

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-10-02 14:25 UTC] laruence@php.net
-Status: Open +Status: Feedback
 [2015-10-02 14:25 UTC] laruence@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.

I am sorry, but if no reproduce script provided, we can not do much things here..
 [2015-10-03 10:11 UTC] p at wspnr dot com
-Status: Feedback +Status: Open
 [2015-10-03 10:11 UTC] p at wspnr dot com
After some poking around with gdb, I've managed to narrow the issue down.
It only happens with opcache enabled, and with concurrent requests. I was using `ab -n 10000 -c 100 "http://my.server/crash.php"` to test.

The following code causes the issue to appear:

-- BEGIN CODE --

<?php

class a {
	const
            REPLACEMENTS_PASS_1 = [
        	"\x00" => "", "\x01" => "", "\x02" => "", "\x03" => "", 
		"\x04" => "", "\x05" => "", "\x06" => "", "\x07" => "", 
		"\x08" => "", "\x0B" => "", "\x0C" => "", "\x0D" => "", 
		"\x0E" => "", "\x0F" => "", "\x10" => "", "\x11" => "", 
		"\x12" => "", "\x13" => "", "\x14" => "", "\x15" => "", 
		"\x16" => "", "\x17" => "", "\x18" => "", "\x19" => "", 
		"\x1A" => "", "\x1B" => "", "\x1C" => "", "\x1D" => "", 
		"\x1E" => "", "\x1F" => "", "\x7F" => "",
    ];
	
	public function __construct() {
		echo strtr("abcd", self::REPLACEMENTS_PASS_1);
	}
}

new a();


-- END CODE --
 [2015-10-03 16:38 UTC] laruence@php.net
-Assigned To: +Assigned To: laruence
 [2015-10-03 16:38 UTC] laruence@php.net
okey, great, thanks for the script, I get what's going wrong there, a quick fix could be:

diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c
index 4ed3dd4..949be9e 100644
--- a/ext/opcache/Optimizer/pass1_5.c
+++ b/ext/opcache/Optimizer/pass1_5.c
@@ -314,6 +314,8 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
 							    ZEND_IS_CONSTANT_TYPE(Z_TYPE(t))) {
 								break;
 							}
+						} else if (Z_TYPE_PP(c) == IS_ARRAY) {
+							break;
 						} else {
 							t = **c;
 							zval_copy_ctor(&t);



anyway, I need discuss with Dmitry about this before I commit it..

thanks
 [2015-10-03 16:41 UTC] laruence@php.net
-Status: Assigned +Status: Feedback
 [2015-10-03 16:41 UTC] laruence@php.net
hmm, forget to say: please help verify the fix. :)
 [2015-10-03 17:51 UTC] p at wspnr dot com
-Status: Feedback +Status: Assigned
 [2015-10-03 17:51 UTC] p at wspnr dot com
Applied patch and recompiled -- problem seems to be resolved!
 [2015-10-04 06:17 UTC] laruence@php.net
Automatic comment on behalf of laruence@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=c147d90dbfcc4f9fd494215b7e5740e497d818c1
Log: Fixed bug #70601 (Segfault in gc_remove_from_buffer())
 [2015-10-04 06:17 UTC] laruence@php.net
-Status: Assigned +Status: Closed
 [2015-10-05 12:23 UTC] hajo dot passon at form4 dot de
We encounter the same problem on 5.5.9-1ubuntu4.13. In the backtrace the gdb shows the same problem at Zend/zend_gc.h:189.

Please, could someone backport the solution to 5.5?
 [2015-10-13 10:12 UTC] ab@php.net
Automatic comment on behalf of laruence@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=c147d90dbfcc4f9fd494215b7e5740e497d818c1
Log: Fixed bug #70601 (Segfault in gc_remove_from_buffer())
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Thu Feb 23 02:01:35 2017 UTC