php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73188 Use after free in user_wrapper_opener()
Submitted: 2016-09-27 19:15 UTC Modified: 2016-10-12 06:23 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:2 (100.0%)
From: admin at fullspace dot ru Assigned: pollita (profile)
Status: Closed Package: Streams related
PHP Version: 5.6.26 OS: Gentoo
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: admin at fullspace dot ru
New email:
PHP Version: OS:

 

 [2016-09-27 19:15 UTC] admin at fullspace dot ru
Description:
------------
There is use after free bug in streams.

This is production site and I can't reproduce bug in short script, but it appears all the time.

Core was generated by `/usr/sbin/apache2 -D PHP5.6 -D MACRO -D RPAF -d /usr/lib64/apache2 -f /etc/apac'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007f5c23af639e in ?? () from /lib64/libc.so.6
(gdb) bt
#0  0x00007f5c23af639e in ?? () from /lib64/libc.so.6
#1  0x00007f5c1f214f8f in user_wrapper_opener (wrapper=0x2133828, 
    filename=0x2cce9b8 "udata://custom/getMyDelivCity/%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0/.json", mode=0x7f5c1f8019c3 "rb", options=0, opened_path=0x0, 
    context=0x257df30, __php_stream_call_depth=1, 
    __zend_filename=0x7f5c1f82a198 "/var/tmp/portage/dev-lang/php-5.6.26/work/sapis-build/apache2/main/streams/streams.c", __zend_lineno=2061, 
    __zend_orig_filename=0x7f5c1f801288 "/var/tmp/portage/dev-lang/php-5.6.26/work/sapis-build/apache2/ext/standard/file.c", __zend_orig_lineno=550)
    at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/main/streams/userspace.c:347
#2  0x00007f5c1f20c892 in _php_stream_open_wrapper_ex (path=0x2cce9b8 "udata://custom/getMyDelivCity/%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0/.json", 
    mode=0x7f5c1f8019c3 "rb", options=8, opened_path=0x0, context=0x257df30, __php_stream_call_depth=0, 
    __zend_filename=0x7f5c1f801288 "/var/tmp/portage/dev-lang/php-5.6.26/work/sapis-build/apache2/ext/standard/file.c", __zend_lineno=550, 
    __zend_orig_filename=0x0, __zend_orig_lineno=0) at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/main/streams/streams.c:2059
#3  0x00007f5c1f0b61f6 in zif_file_get_contents (ht=1, return_value=0x2cd1658, return_value_ptr=0x7f5c25bb01b8, this_ptr=0x0, return_value_used=1)
    at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/ext/standard/file.c:548
#4  0x00007f5c1ef77327 in phar_file_get_contents (ht=1, return_value=0x2cd1658, return_value_ptr=0x7f5c25bb01b8, this_ptr=0x0, return_value_used=1)
    at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/ext/phar/func_interceptors.c:225
#5  0x00007f5c1f2d1910 in zend_do_fcall_common_helper_SPEC (execute_data=0x7f5c25bb0210)
    at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/Zend/zend_vm_execute.h:558
#6  0x00007f5c1f2d7422 in ZEND_DO_FCALL_SPEC_CONST_HANDLER (execute_data=0x7f5c25bb0210)
    at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/Zend/zend_vm_execute.h:2602
#7  0x00007f5c1f2d0f79 in execute_ex (execute_data=0x7f5c25bb0210) at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/Zend/zend_vm_execute.h:363
#8  0x00007f5c1f2d1002 in zend_execute (op_array=0x7f5c25be5bb0) at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/Zend/zend_vm_execute.h:388
#9  0x00007f5c1f289010 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/Zend/zend.c:1341
#10 0x00007f5c1f1eb211 in php_execute_script (primary_file=0x7ffc4d68bcf0) at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/main/main.c:2613
#11 0x00007f5c1f345fb3 in php_handler (r=0x2018de0) at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/sapi/apache2handler/sapi_apache2.c:667
#12 0x0000000000438df0 in ap_run_handler ()
#13 0x00000000004391b9 in ap_invoke_handler ()
#14 0x00000000004454ec in ap_internal_redirect ()
#15 0x00007f5c207f2462 in ?? () from /usr/lib64/apache2/modules/mod_rewrite.so
#16 0x0000000000438df0 in ap_run_handler ()
#17 0x00000000004391b9 in ap_invoke_handler ()
#18 0x0000000000445d90 in ap_process_request ()
#19 0x0000000000442f30 in ?? ()
#20 0x000000000043f1e0 in ap_run_process_connection ()
#21 0x000000000044a3af in ?? ()
#22 0x000000000044a7d4 in ?? ()
#23 0x000000000044b6e4 in ap_mpm_run ()
#24 0x0000000000424c21 in main ()


Segfault is in strcmp() here:

(gdb) up
#1  0x00007f5c1f214f8f in user_wrapper_opener (wrapper=0x2133828, 
    filename=0x2cce9b8 "udata://custom/getMyDelivCity/%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0/.json", mode=0x7f5c1f8019c3 "rb", options=0, opened_path=0x0, 
    context=0x257df30, __php_stream_call_depth=1, 
    __zend_filename=0x7f5c1f82a198 "/var/tmp/portage/dev-lang/php-5.6.26/work/sapis-build/apache2/main/streams/streams.c", __zend_lineno=2061, 
    __zend_orig_filename=0x7f5c1f801288 "/var/tmp/portage/dev-lang/php-5.6.26/work/sapis-build/apache2/ext/standard/file.c", __zend_orig_lineno=550)
    at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/main/streams/userspace.c:347
347		if (FG(user_stream_current_filename) != NULL && strcmp(filename, FG(user_stream_current_filename)) == 0) {
(gdb) print file_globals.user_stream_current_filename
$1 = 0x7f5c15714ab0 <error: Cannot access memory at address 0x7f5c15714ab0>




Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-09-27 19:22 UTC] admin at fullspace dot ru
There is use after free bug in streams.

apache 2.2.31 (prefork) + mod_php (5.6.26)

This is production site and I can't reproduce bug in short script, but it appears all the time.

Core was generated by `/usr/sbin/apache2 -D PHP5.6 -D MACRO -D RPAF -d /usr/lib64/apache2 -f /etc/apac'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007f5c23af639e in ?? () from /lib64/libc.so.6
(gdb) bt
#0  0x00007f5c23af639e in ?? () from /lib64/libc.so.6
#1  0x00007f5c1f214f8f in user_wrapper_opener (wrapper=0x2133828, 
    filename=0x2cce9b8 "udata://custom/getMyDelivCity/%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0/.json", mode=0x7f5c1f8019c3 "rb", options=0, opened_path=0x0, 
    context=0x257df30, __php_stream_call_depth=1, 
    __zend_filename=0x7f5c1f82a198 "/var/tmp/portage/dev-lang/php-5.6.26/work/sapis-build/apache2/main/streams/streams.c", __zend_lineno=2061, 
    __zend_orig_filename=0x7f5c1f801288 "/var/tmp/portage/dev-lang/php-5.6.26/work/sapis-build/apache2/ext/standard/file.c", __zend_orig_lineno=550)
    at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/main/streams/userspace.c:347
#2  0x00007f5c1f20c892 in _php_stream_open_wrapper_ex (path=0x2cce9b8 "udata://custom/getMyDelivCity/%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0/.json", 
    mode=0x7f5c1f8019c3 "rb", options=8, opened_path=0x0, context=0x257df30, __php_stream_call_depth=0, 
    __zend_filename=0x7f5c1f801288 "/var/tmp/portage/dev-lang/php-5.6.26/work/sapis-build/apache2/ext/standard/file.c", __zend_lineno=550, 
    __zend_orig_filename=0x0, __zend_orig_lineno=0) at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/main/streams/streams.c:2059
#3  0x00007f5c1f0b61f6 in zif_file_get_contents (ht=1, return_value=0x2cd1658, return_value_ptr=0x7f5c25bb01b8, this_ptr=0x0, return_value_used=1)
    at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/ext/standard/file.c:548
#4  0x00007f5c1ef77327 in phar_file_get_contents (ht=1, return_value=0x2cd1658, return_value_ptr=0x7f5c25bb01b8, this_ptr=0x0, return_value_used=1)
    at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/ext/phar/func_interceptors.c:225
#5  0x00007f5c1f2d1910 in zend_do_fcall_common_helper_SPEC (execute_data=0x7f5c25bb0210)
    at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/Zend/zend_vm_execute.h:558
#6  0x00007f5c1f2d7422 in ZEND_DO_FCALL_SPEC_CONST_HANDLER (execute_data=0x7f5c25bb0210)
    at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/Zend/zend_vm_execute.h:2602
#7  0x00007f5c1f2d0f79 in execute_ex (execute_data=0x7f5c25bb0210) at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/Zend/zend_vm_execute.h:363
#8  0x00007f5c1f2d1002 in zend_execute (op_array=0x7f5c25be5bb0) at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/Zend/zend_vm_execute.h:388
#9  0x00007f5c1f289010 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/Zend/zend.c:1341
#10 0x00007f5c1f1eb211 in php_execute_script (primary_file=0x7ffc4d68bcf0) at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/main/main.c:2613
#11 0x00007f5c1f345fb3 in php_handler (r=0x2018de0) at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/sapi/apache2handler/sapi_apache2.c:667
#12 0x0000000000438df0 in ap_run_handler ()
#13 0x00000000004391b9 in ap_invoke_handler ()
#14 0x00000000004454ec in ap_internal_redirect ()
#15 0x00007f5c207f2462 in ?? () from /usr/lib64/apache2/modules/mod_rewrite.so
#16 0x0000000000438df0 in ap_run_handler ()
#17 0x00000000004391b9 in ap_invoke_handler ()
#18 0x0000000000445d90 in ap_process_request ()
#19 0x0000000000442f30 in ?? ()
#20 0x000000000043f1e0 in ap_run_process_connection ()
#21 0x000000000044a3af in ?? ()
#22 0x000000000044a7d4 in ?? ()
#23 0x000000000044b6e4 in ap_mpm_run ()
#24 0x0000000000424c21 in main ()


Segfault is in strcmp() here:

(gdb) up
#1  0x00007f5c1f214f8f in user_wrapper_opener (wrapper=0x2133828, 
    filename=0x2cce9b8 "udata://custom/getMyDelivCity/%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B0/.json", mode=0x7f5c1f8019c3 "rb", options=0, opened_path=0x0, 
    context=0x257df30, __php_stream_call_depth=1, 
    __zend_filename=0x7f5c1f82a198 "/var/tmp/portage/dev-lang/php-5.6.26/work/sapis-build/apache2/main/streams/streams.c", __zend_lineno=2061, 
    __zend_orig_filename=0x7f5c1f801288 "/var/tmp/portage/dev-lang/php-5.6.26/work/sapis-build/apache2/ext/standard/file.c", __zend_orig_lineno=550)
    at /usr/src/debug/dev-lang/php-5.6.26/sapis-build/apache2/main/streams/userspace.c:347
347		if (FG(user_stream_current_filename) != NULL && strcmp(filename, FG(user_stream_current_filename)) == 0) {
(gdb) print file_globals.user_stream_current_filename
$1 = 0x7f5c15714ab0 <error: Cannot access memory at address 0x7f5c15714ab0>
 [2016-10-12 04:16 UTC] pollita@php.net
-Assigned To: +Assigned To: pollita
 [2016-10-12 05:00 UTC] pollita@php.net
-Status: Assigned +Status: Closed
 [2016-10-12 05:00 UTC] pollita@php.net
That was a fun one to track down.

Looks like the opener method is valid enough IF you assume that it'll always reach a return statement.

Because of the way PHP handles fatal errors (and die/exit for that matter), if the stream_open() method fataled/died/exited, the recursion protection variable wouldn't get reset, and its (now invalid) pointer would carry over into the next request.

Next request tried to compare to invalid memory == boom.

https://github.com/php/php-src/commit/9f86cdaf7fc44c0d97a35bc4d04622e3d3d53f4d

This fix (which has been applied to 5.6 and later) should take care of the problem.
 [2016-10-12 06:23 UTC] admin at fullspace dot ru
Many thanks, Sara!
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Nov 23 09:01:28 2024 UTC