php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70182 Mem out-of-bounds write (segfault) in ZEND_ASSIGN_DIV_SPEC_CV_UNUSED_HANDLER
Submitted: 2015-08-02 07:52 UTC Modified: 2015-08-02 19:20 UTC
From: hugh at allthethings dot co dot nz Assigned: bwoebi
Status: Closed Package: Reproducible crash
PHP Version: master-Git-2015-08-02 (Git) OS: Linux
Private report: No CVE-ID:
 [2015-08-02 07:52 UTC] hugh at allthethings dot co dot nz
Description:
------------
Found this using afl-fuzz, see http://lcamtuf.coredump.cx/afl/

To reproduce, compile PHP with CFLAGS=-O3, then run ./sapi/cli/php with the test script
<?php $a[]/=$a=a?>
You should get a segfault.

Bisected this crash back to commit 7a01c44ab268820c2365798fde0fe010cf6c5e20 which was the fix for bug #69905 (similar test case).

The test case I found needed to have an array with an "assign-and-??" operator (/=, *=, +=, etc), combined with an assign operator, with a character on the RHS of the assignment. ($a[]/=$a=a).

Traced the bug to the ZEND_ASSIGN_DIV_SPEC_CV_UNUSED_HANDLER assuming that the zend_fetch_dimension_address_RW method returned as INDIRECT type, but the patch for bug #69905 returned a NULL type (see Zend/zend_vm_execute.h line 33752 of commit 9f395b9e761a4d714e22366a63e9640cee461bd4). The assert is probably the reason why I needed -O3 in CFLAGS.

Created a patch that applies cleanly to master, and makes no change in the "make test" run after recompilation.

Test script:
---------------
<?php $a[]/=$a=a?>


Expected result:
----------------
Fatal error: Uncaught Error: [] operator not supported for strings in /root/php-crash-tmin:1
Stack trace:
#0 {main}
  thrown in /root/php-crash-tmin on line 1


Actual result:
--------------
(gdb) bt
#0  zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED (binary_op=<optimized out>) at /root/php-src/Zend/zend_vm_execute.h:33769
#1  ZEND_ASSIGN_DIV_SPEC_CV_UNUSED_HANDLER () at /root/php-src/Zend/zend_vm_execute.h:33860
#2  0x00000000006221fb in execute_ex (ex=<optimized out>) at /root/php-src/Zend/zend_vm_execute.h:406
#3  0x000000000067f4e9 in zend_execute (op_array=0x7ffff70690e0, return_value=0x90, return_value@entry=0x7ffff7014030) at /root/php-src/Zend/zend_vm_execute.h:450
#4  0x00000000005d9ea8 in zend_execute_scripts (type=type@entry=8, retval=0x7ffff7014030, retval@entry=0x0, file_count=file_count@entry=3)
    at /root/php-src/Zend/zend.c:1404
#5  0x00000000005678d0 in php_execute_script (primary_file=primary_file@entry=0x7fffffffd630) at /root/php-src/main/main.c:2475
#6  0x0000000000680c6b in do_cli (argc=2, argv=0xa8d780) at /root/php-src/sapi/cli/php_cli.c:971
#7  0x000000000041ed80 in main (argc=2, argv=0xa8d780) at /root/php-src/sapi/cli/php_cli.c:1338
(gdb) i r
rax            0x4      4
rbx            0x700000009      30064771081
rcx            0x4      4
rdx            0x7ffff7073050   140737337831504
rsi            0x90     144
rdi            0x7ffff7073000   140737337831424
rbp            0x7ffff70140c0   0x7ffff70140c0
rsp            0x7fffffffb160   0x7fffffffb160
r8             0x200    512
r9             0x0      0
r10            0xac6390 11297680
r11            0x7ffff7476870   140737342040176
r12            0x7ffff70140c0   140737337442496
r13            0x0      0
r14            0x7ffff7014030   140737337442352
r15            0x7ffff70720e0   140737337827552
rip            0x670755 0x670755 <ZEND_ASSIGN_DIV_SPEC_CV_UNUSED_HANDLER+133>
eflags         0x10206  [ PF IF RF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x0      0
gs             0x0      0
(gdb) x/i $rip
=> 0x670755 <ZEND_ASSIGN_DIV_SPEC_CV_UNUSED_HANDLER+133>:       movzbl 0x9(%rbx),%ecx


Patches

bug-70182.patch (last revision 2015-08-02 08:12 UTC) by hugh at allthethings dot co dot nz)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-08-02 07:57 UTC] stas@php.net
-Type: Security +Type: Bug
 [2015-08-02 07:58 UTC] stas@php.net
-Assigned To: +Assigned To: dmitry
 [2015-08-02 08:34 UTC] hugh at allthethings dot co dot nz
Just to note, that I used gcc 4.8.0 and 4.8.4, I can't reproduce this on gcc 4.7.2.
 [2015-08-02 08:56 UTC] hugh at allthethings dot co dot nz
Also can't reproduce this using clang
 [2015-08-02 16:58 UTC] bwoebi@php.net
-Assigned To: dmitry +Assigned To: bwoebi
 [2015-08-02 16:58 UTC] bwoebi@php.net
It depends on what was previously in memory before, so with luck you had a segfault here. Like it was the case with GCC -O3.

But it also violates ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); assertion in zend_binary_assign_op_dim_helper. Fixing...
 [2015-08-02 17:08 UTC] bwoebi@php.net
Automatic comment on behalf of bobwei9@hotmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=9e246a73ef465f622050f8a166d35c5431df3bdd
Log: Fixed bug #70182 (Segfault in ZEND_ASSIGN_OP handlers)
 [2015-08-02 17:08 UTC] bwoebi@php.net
-Status: Assigned +Status: Closed
 [2015-08-02 19:20 UTC] hugh at allthethings dot co dot nz
Thanks for the quick fix!
 [2015-08-04 20:54 UTC] ab@php.net
Automatic comment on behalf of bobwei9@hotmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=9e246a73ef465f622050f8a166d35c5431df3bdd
Log: Fixed bug #70182 (Segfault in ZEND_ASSIGN_OP handlers)
 [2016-07-20 11:37 UTC] davey@php.net
Automatic comment on behalf of bobwei9@hotmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=9e246a73ef465f622050f8a166d35c5431df3bdd
Log: Fixed bug #70182 (Segfault in ZEND_ASSIGN_OP handlers)
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Fri Jul 21 08:01:41 2017 UTC