php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71300 Segfault in zend_fetch_string_offset
Submitted: 2016-01-07 06:47 UTC Modified: 2016-01-07 15:00 UTC
From: stas@php.net Assigned: laruence (profile)
Status: Closed Package: Reproducible crash
PHP Version: 7.0.2RC1 OS: Darwin
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: stas@php.net
New email:
PHP Version: OS:

 

 [2016-01-07 06:47 UTC] stas@php.net
Description:
------------
The following code segaults on 7.x, doesn't on 5.x. Original report by Brian Carpenter.

Test script:
---------------
<?php
for($s=STR;26>$x-=!$c=$s[$$x];)
	echo $$s = $s[$$x++] = ++$c;


Expected result:
----------------
(a lot of garbage, no segfault)

Actual result:
--------------
TUS1VT1WU1XV1YW1ZX1AY1BZ1CA1DB1EC1FD1GE1HF1IG1JH1KI1LJ1MK1NL1OM1PN1QO1RP1SQ1TR1US1VT1WU1XV1YW1ZX1AY1BZ1CA1DB1EC1FD1GE1HF1IG1JH1KI1LJ1MK1NL1OM1PN1QO1RP1SQ1TR1US1VT1WU1XV1YW1ZX1AY1BZ1CA1DB1EC1FD1GE1HF1IG1JH1KI1LJ1MK1NL1OM1PN1QO1RP1SQ1TR1US1VT1WU1XV1YW1ZX1AY1BZ1CA1DB1EC1FD1GE1HF1IG1JH1KI1LJ1MK1NL1OM1PN1QO1RP1SQ1TR1US1VT1WU1XV1YW1ZX1AY1BZ1CA1DB1EC1FD1GE1HF1IG1JH1KI1LJ1MK1NL1OM1PN1QO1R-
Program received signal SIGSEGV, Segmentation fault.


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-01-07 06:48 UTC] stas@php.net
-Assigned To: +Assigned To: laruence
 [2016-01-07 06:48 UTC] stas@php.net
Backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x0000000100713591 in zend_mm_alloc_small (heap=<optimized out>, size=386504, bin_num=<optimized out>, heap=<optimized out>, size=386504, bin_num=<optimized out>)
    at /Users/smalyshev/php-7.0/Zend/zend_alloc.c:1291
1291			heap->free_slot[bin_num] = p->next_free_slot;
(gdb) bt
#0  0x0000000100713591 in zend_mm_alloc_small (heap=<optimized out>, size=386504, bin_num=<optimized out>, heap=<optimized out>, size=386504, bin_num=<optimized out>)
    at /Users/smalyshev/php-7.0/Zend/zend_alloc.c:1291
#1  zend_mm_alloc_heap (heap=<optimized out>, size=<optimized out>, heap=<optimized out>, size=<optimized out>) at /Users/smalyshev/php-7.0/Zend/zend_alloc.c:1358
#2  _emalloc (size=32) at /Users/smalyshev/php-7.0/Zend/zend_alloc.c:2442
#3  0x00000001007609cc in zend_string_alloc (len=3, persistent=0) at /Users/smalyshev/php-7.0/Zend/zend_string.h:121
#4  zend_string_init (str=0x103478eb8 "1R-", len=3, persistent=0) at /Users/smalyshev/php-7.0/Zend/zend_string.h:157
#5  zend_string_dup (s=0x103478ea0, persistent=0) at /Users/smalyshev/php-7.0/Zend/zend_string.h:177
#6  _zval_copy_ctor_func (zvalue=0x103415090) at /Users/smalyshev/php-7.0/Zend/zend_variables.c:226
#7  0x00000001008f5234 in zend_fetch_string_offset (container=<optimized out>, dim=<optimized out>, type=<optimized out>, container=<optimized out>, 
    dim=<optimized out>, type=<optimized out>) at /Users/smalyshev/php-7.0/Zend/zend_execute.c:1688
#8  ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_HANDLER (execute_data=0x103415030) at /Users/smalyshev/php-7.0/Zend/zend_vm_execute.h:39361
#9  0x000000010080c4a4 in execute_ex (ex=0x103415030) at /Users/smalyshev/php-7.0/Zend/zend_vm_execute.h:417
#10 0x000000010080cf88 in zend_execute (op_array=0x1034742a0, return_value=0x0) at /Users/smalyshev/php-7.0/Zend/zend_vm_execute.h:458
#11 0x0000000100765667 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /Users/smalyshev/php-7.0/Zend/zend.c:1428
#12 0x000000010068a33f in php_execute_script (primary_file=0x7fff5fbfed40) at /Users/smalyshev/php-7.0/main/main.c:2471
#13 0x000000010094083b in do_cli (argc=2, argv=0x103300cb0) at /Users/smalyshev/php-7.0/sapi/cli/php_cli.c:974
#14 0x000000010093f3a3 in main (argc=2, argv=0x103300cb0) at /Users/smalyshev/php-7.0/sapi/cli/php_cli.c:1345
(gdb)
 [2016-01-07 09:13 UTC] laruence@php.net
An simple fix would be:
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 44ae08d..bd34074 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2535,8 +2535,8 @@ void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
        switch (var_ast->kind) {
                case ZEND_AST_VAR:
                case ZEND_AST_STATIC_PROP:
-                   zend_compile_var(&var_node, var_ast, BP_VAR_W);
                        zend_compile_expr(&expr_node, expr_ast);
+                 zend_compile_var(&var_node, var_ast, BP_VAR_W);
                        zend_emit_op(result, ZEND_ASSIGN, &var_node, &expr_node);
                        return;
                case ZEND_AST_DIM:


but this will break the evaluate order of assign operator (from right-to-left to left-to-rgith).

so I am not sure, need think another way maybe :<
 [2016-01-07 10:17 UTC] nikic@php.net
@laruence: This is what delayed_compile_var is for (not sure if it support delayed simple fetches yet): To keep order of evaluation of dependent expressions, but do the actual FETCH_Ws last.
 [2016-01-07 14:38 UTC] laruence@php.net
yeah, that is what I was trying, but I find another problem with +=.

digging that togther
 [2016-01-07 15:00 UTC] laruence@php.net
okey, that one became more complicated, I submit a new entry in #71303, will fix this one soon
 [2016-01-07 15:05 UTC] laruence@php.net
Automatic comment on behalf of laruence@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=16a2b47394a3f8c3d7c2b8eaba59da0e4beca171
Log: Fixed bug #71300 (Segfault in zend_fetch_string_offset)
 [2016-01-07 15:05 UTC] laruence@php.net
-Status: Assigned +Status: Closed
 [2016-07-20 11:34 UTC] davey@php.net
Automatic comment on behalf of laruence@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=16a2b47394a3f8c3d7c2b8eaba59da0e4beca171
Log: Fixed bug #71300 (Segfault in zend_fetch_string_offset)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 03:01:28 2024 UTC