php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72800 heap-use-after-free in _zend_mm_free_int
Submitted: 2016-08-10 08:57 UTC Modified: 2016-08-16 06:32 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: brian dot carpenter at gmail dot com Assigned: dmitry (profile)
Status: Assigned Package: Reproducible crash
PHP Version: 5.6.24 OS: Debian 8
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: brian dot carpenter at gmail dot com
New email:
PHP Version: OS:

 

 [2016-08-10 08:57 UTC] brian dot carpenter at gmail dot com
Description:
------------
64-bit PHP 5.6.24 w/ ASAN enabled.
Found via American Fuzzy Lop + libdislocator.so

Test script:
---------------
<?ptr0str();for(;;){$v[]=$f.=0;}class t{var$t;var$g;function t(){}}function ptr0str(){for(;$i;){}

Expected result:
----------------
No crash.

Actual result:
--------------
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 16124 bytes) in /home/geeknik/php-tmp/out/2/crashes/test07 on line 1
=================================================================
==103707==ERROR: AddressSanitizer: heap-use-after-free on address 0x7fbe227987f8 at pc 0x0000014c861f bp 0x7ffe4bbb2a20 sp 0x7ffe4bbb2a18
READ of size 8 at 0x7fbe227987f8 thread T0
    #0 0x14c861e in _zend_mm_free_int /home/geeknik/php-5.6.24/Zend/zend_alloc.c:2113:6
    #1 0x14ccb17 in _efree /home/geeknik/php-5.6.24/Zend/zend_alloc.c:2440:2
    #2 0x15a6bc1 in _zval_dtor_func /home/geeknik/php-5.6.24/Zend/zend_variables.c:37:4
    #3 0x155991a in _zval_dtor /home/geeknik/php-5.6.24/Zend/zend_variables.h:35:2
    #4 0x155991a in i_zval_ptr_dtor /home/geeknik/php-5.6.24/Zend/zend_execute.h:79
    #5 0x155991a in _zval_ptr_dtor /home/geeknik/php-5.6.24/Zend/zend_execute_API.c:424
    #6 0x15f5185 in i_zend_hash_bucket_delete /home/geeknik/php-5.6.24/Zend/zend_hash.c:182:3
    #7 0x15f5185 in zend_hash_bucket_delete /home/geeknik/php-5.6.24/Zend/zend_hash.c:192
    #8 0x15f5581 in zend_hash_graceful_reverse_destroy /home/geeknik/php-5.6.24/Zend/zend_hash.c:613:3
    #9 0x155a230 in shutdown_executor /home/geeknik/php-5.6.24/Zend/zend_execute_API.c:244:3
    #10 0x15b0f83 in zend_deactivate /home/geeknik/php-5.6.24/Zend/zend.c:960:2
    #11 0x13b807e in php_request_shutdown /home/geeknik/php-5.6.24/main/main.c:1899:2
    #12 0x1908b17 in do_cli /home/geeknik/php-5.6.24/sapi/cli/php_cli.c:1177:3
    #13 0x190474d in main /home/geeknik/php-5.6.24/sapi/cli/php_cli.c:1378:18
    #14 0x7fbe2f52db44 in __libc_start_main /build/glibc-uPj9cH/glibc-2.19/csu/libc-start.c:287
    #15 0x5095ac in _start (/home/geeknik/php-5.6.24/sapi/cli/php+0x5095ac)

0x7fbe227987f8 is located 4088 bytes inside of 262144-byte region [0x7fbe22797800,0x7fbe227d7800)
freed by thread T0 here:
    #0 0x4ebcab in __interceptor_free (/home/geeknik/php-5.6.24/sapi/cli/php+0x4ebcab)
    #1 0x14d0e7a in zend_mm_mem_malloc_free /home/geeknik/php-5.6.24/Zend/zend_alloc.c:297:2

previously allocated by thread T0 here:
    #0 0x4ebf2b in malloc (/home/geeknik/php-5.6.24/sapi/cli/php+0x4ebf2b)
    #1 0x14d0d9a in zend_mm_mem_malloc_alloc /home/geeknik/php-5.6.24/Zend/zend_alloc.c:287:27

SUMMARY: AddressSanitizer: heap-use-after-free /home/geeknik/php-5.6.24/Zend/zend_alloc.c:2113 _zend_mm_free_int
Shadow bytes around the buggy address:
  0x0ff8444eb0a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0ff8444eb0b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0ff8444eb0c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0ff8444eb0d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0ff8444eb0e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0ff8444eb0f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd[fd]
  0x0ff8444eb100: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0ff8444eb110: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0ff8444eb120: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0ff8444eb130: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0ff8444eb140: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  ASan internal:           fe
==103707==ABORTING


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-08-10 17:07 UTC] stas@php.net
-Type: Security +Type: Bug -Assigned To: +Assigned To: dmitry
 [2016-08-13 07:43 UTC] brian dot carpenter at gmail dot com
This smaller script triggers an oh so slightly different version of this heap-use-after-free flaw: <?for(;;$i++){0/$p0r=$i.=$p0r;}

Result:
Warning: Division by zero in /home/geeknik/php-tmp/out/2/crashes/test10 on line 1
...repeated 20 more times and then we crash...
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 56623105 bytes) in /home/geeknik/php-tmp/out/2/crashes/test10 on line 1
=================================================================
==47594==ERROR: AddressSanitizer: heap-use-after-free on address 0x7ffb4a9ad810 at pc 0x0000014c859e bp 0x7ffe4191b740 sp 0x7ffe4191b738
READ of size 8 at 0x7ffb4a9ad810 thread T0
    #0 0x14c859d in _zend_mm_free_int /home/geeknik/php-5.6.24/Zend/zend_alloc.c:2075:2
    #1 0x14ccb17 in _efree /home/geeknik/php-5.6.24/Zend/zend_alloc.c:2440:2
    #2 0x15a6bc1 in _zval_dtor_func /home/geeknik/php-5.6.24/Zend/zend_variables.c:37:4
    #3 0x155991a in _zval_dtor /home/geeknik/php-5.6.24/Zend/zend_variables.h:35:2
    #4 0x155991a in i_zval_ptr_dtor /home/geeknik/php-5.6.24/Zend/zend_execute.h:79
    #5 0x155991a in _zval_ptr_dtor /home/geeknik/php-5.6.24/Zend/zend_execute_API.c:424
    #6 0x15f5185 in i_zend_hash_bucket_delete /home/geeknik/php-5.6.24/Zend/zend_hash.c:182:3
    #7 0x15f5185 in zend_hash_bucket_delete /home/geeknik/php-5.6.24/Zend/zend_hash.c:192
    #8 0x15f5581 in zend_hash_graceful_reverse_destroy /home/geeknik/php-5.6.24/Zend/zend_hash.c:613:3
    #9 0x155a230 in shutdown_executor /home/geeknik/php-5.6.24/Zend/zend_execute_API.c:244:3
    #10 0x15b0f83 in zend_deactivate /home/geeknik/php-5.6.24/Zend/zend.c:960:2
    #11 0x13b807e in php_request_shutdown /home/geeknik/php-5.6.24/main/main.c:1899:2
    #12 0x1908b17 in do_cli /home/geeknik/php-5.6.24/sapi/cli/php_cli.c:1177:3
    #13 0x190474d in main /home/geeknik/php-5.6.24/sapi/cli/php_cli.c:1378:18
    #14 0x7ffb5d701b44 in __libc_start_main /build/glibc-uPj9cH/glibc-2.19/csu/libc-start.c:287
    #15 0x5095ac in _start (/home/geeknik/php-5.6.24/sapi/cli/php+0x5095ac)

0x7ffb4a9ad810 is located 16 bytes inside of 56885248-byte region [0x7ffb4a9ad800,0x7ffb4dfed800)
freed by thread T0 here:
    #0 0x4ebcab in __interceptor_free (/home/geeknik/php-5.6.24/sapi/cli/php+0x4ebcab)
    #1 0x14d0e7a in zend_mm_mem_malloc_free /home/geeknik/php-5.6.24/Zend/zend_alloc.c:297:2

previously allocated by thread T0 here:
    #0 0x4ec21e in realloc (/home/geeknik/php-5.6.24/sapi/cli/php+0x4ec21e)
    #1 0x14d0e0e in zend_mm_mem_malloc_realloc /home/geeknik/php-5.6.24/Zend/zend_alloc.c:292:27

SUMMARY: AddressSanitizer: heap-use-after-free /home/geeknik/php-5.6.24/Zend/zend_alloc.c:2075 _zend_mm_free_int
Shadow bytes around the buggy address:
  0x0fffe952dab0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0fffe952dac0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0fffe952dad0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0fffe952dae0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0fffe952daf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0fffe952db00: fd fd[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fffe952db10: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fffe952db20: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fffe952db30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fffe952db40: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0fffe952db50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  ASan internal:           fe
==47594==ABORTING
 [2016-08-16 06:32 UTC] laruence@php.net
the problem is oom while doing copy_ctor, then it will leave a two zval reference on a same char *.... then double free.

I am not sure how to fix this easily. maybe we should not try to dtor zval(symbol table) if php is terminated by OOM error.
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC