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 (profile)
Status: Closed Package: Reproducible crash
PHP Version: master-Git-2015-08-02 (Git) OS: Linux
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: hugh at allthethings dot co dot nz
New email:
PHP Version: OS:

 

 [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)

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 12:01:29 2024 UTC