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: 2021-06-20 04:22 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: cmb (profile)
Status: No Feedback Package: Reproducible crash
PHP Version: 5.6.24 OS: Debian 8
Private report: No CVE-ID: None
 [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

Pull Requests

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.
 [2021-06-09 14:46 UTC] cmb@php.net
-Status: Assigned +Status: Feedback -Assigned To: dmitry +Assigned To: cmb
 [2021-06-09 14:46 UTC] cmb@php.net
Is this still an issue with any of the actively supported PHP
versions[1]?

[1] <https://www.php.net/supported-versions.php>
 [2021-06-20 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Dec 30 14:01:28 2024 UTC