Bug #77533 [Opn->Nab]: Found crash when appending element to pass-by-ref array with []

From: Date: Mon, 28 Jan 2019 08:14:33 +0000
Subject: Bug #77533 [Opn->Nab]: Found crash when appending element to pass-by-ref array with []
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-219240@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=77533&edit=1 ID: 77533 Updated by: nikic@php.net Reported by: timandes@php.net Summary: Found crash when appending element to pass-by-ref array with [] -Status: Open +Status: Not a bug Type: Bug Package: Reproducible crash Operating System: CentOS Linux release 7.6.1810 (C PHP Version: 7.3.1 Block user comment: N Private report: N New Comment: Should be: if (Z_TYPE_P(param) != IS_ARRAY) { zval_ptr_dtor(param); array_init(param); } else { SEPARATE_ARRAY(param); } You are trying to modify a potentially shared array without separating it first. In this case it is the empty array, which lives in read-only memory. Previous Comments: ------------------------------------------------------------------------ [2019-01-28 02:43:12] timandes@php.net Description: ------------ Last week, I found a CI failure[1] of pecl/zookeeper. I thought it would be compatibility problem because I turned on PHP-7.3 in .travis.yml. When I looked into that issue, I found it's weird because the crash point was in the PHP src, and it only crashed when I passed an empty array to the function provided pass-by-ref var. So I wrote a small ext to reproduce that: ```c PHP_FUNCTION(caseone_test1) { zval *param; if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &param) == FAILURE) { return; } if (param) { ZVAL_DEREF(param); } if (Z_TYPE_P(param) != IS_ARRAY) { array_init(param); } add_assoc_long_ex(param, ZEND_STRL("foo"), 0); } ``` ```php $param = []; caseone_test1($param); ``` ```gdb #0 0x000056193020c64e in zend_hash_real_init_mixed_ex (ht=ht@entry=0x5619305fe220 <zend_empty_array>) at /usr/src/debug/php-7.3.1/Zend/zend_hash.c:131 #1 zend_hash_real_init_mixed (ht=ht@entry=0x5619305fe220 <zend_empty_array>) at /usr/src/debug/php-7.3.1/Zend/zend_hash.c:260 #2 0x000056193020db88 in _zend_hash_str_add_or_update_i (flag=1, pData=0x7fffbb8834d0, h=9223372037048267657, len=3, str=0x7ff29e4b7d93 "foo", ht=0x5619305fe220 <zend_empty_array>) at /usr/src/debug/php-7.3.1/Zend/zend_hash.c:746 #3 zend_hash_str_update (ht=ht@entry=0x5619305fe220 <zend_empty_array>, str=str@entry=0x7ff29e4b7d93 "foo", len=len@entry=3, pData=pData@entry=0x7fffbb8834d0) at /usr/src/debug/php-7.3.1/Zend/zend_hash.c:854 #4 0x00005619302021a8 in zend_symtable_str_update (pData=0x7fffbb8834d0, len=3, str=0x7ff29e4b7d93 "foo", ht=0x5619305fe220 <zend_empty_array>) at /usr/src/debug/php-7.3.1/Zend/zend_hash.h:498 #5 add_assoc_long_ex (arg=<optimized out>, key=key@entry=0x7ff29e4b7d93 "foo", key_len=key_len@entry=3, n=n@entry=0) at /usr/src/debug/php-7.3.1/Zend/zend_API.c:1359 #6 0x00007ff29e4b7c7c in zif_caseone_test1 (execute_data=<optimized out>, return_value=<optimized out>) at /root/php-7.3.1/ext/caseone/caseone.c:29 #7 0x000056193028b2f9 in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER () at /usr/src/debug/php-7.3.1/Zend/zend_vm_execute.h:645 #8 execute_ex (ex=0x5619305fe220 <zend_empty_array>) at /usr/src/debug/php-7.3.1/Zend/zend_vm_execute.h:55414 #9 0x000056193028f3a3 in zend_execute (op_array=op_array@entry=0x7ff2a267d2a0, return_value=0x0, return_value@entry=0x7ff2a267d3e0) at /usr/src/debug/php-7.3.1/Zend/zend_vm_execute.h:60834 #10 0x0000561930200622 in zend_execute_scripts (type=type@entry=8, retval=0x7ff2a267d3e0, retval@entry=0x0, file_count=-1570648016, file_count@entry=3) at /usr/src/debug/php-7.3.1/Zend/zend.c:1568 #11 0x00005619301a05d0 in php_execute_script (primary_file=primary_file@entry=0x7fffbb885b80) at /usr/src/debug/php-7.3.1/main/main.c:2630 #12 0x0000561930291892 in do_cli (argc=3, argv=0x561930f3f960) at /usr/src/debug/php-7.3.1/sapi/cli/php_cli.c:997 #13 0x000056193000121b in main (argc=3, argv=0x561930f3f960) at /usr/src/debug/php-7.3.1/sapi/cli/php_cli.c:1389 ``` When I changed the former PHP script to : ```php $param = ''; caseone_test1($param); ``` or ```php $param = [0]; caseone_test1($param); ``` , they worked fine. This issue can only be reproduced under Linux. I'm not sure it's a bug or not, so I turned to you guys for help. System info: ```shell uname -a Linux 93a912e38b29 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux ``` ```shell cat /etc/redhat-release CentOS Linux release 7.6.1810 (Core) ``` [1] https://api.travis-ci.org/v3/job/484167428/log.txt ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=77533&edit=1

« previous php.bugs (#219240) next »