php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71936 Segmentation fault destroying HTTP_RAW_POST_DATA
Submitted: 2016-04-01 00:33 UTC Modified: 2016-06-20 16:49 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: mike dot laspina at gmail dot com Assigned: remi
Status: Closed Package: Reproducible crash
PHP Version: 5.6.20 OS:
Private report: No CVE-ID:
 [2016-04-01 00:33 UTC] mike dot laspina at gmail dot com
Description:
------------
With --enable-debug, shutdown_executor segfaults trying to destroy the HTTP_RAW_POST_DATA global if the POST body length is zero. The cause is the use of php_stream_copy_to_mem in php_default_post_reader (php_content_types.c:64), which sets the buf parameter to NULL when no data is read. This results in a zval string where Z_STRVAL == NULL. When Zend debugging is disabled, this is harmless, only resulting in a call to _efree(NULL). When Zend debugging is enabled, the string value is dereferenced by a call to CHECK_ZVAL_STRING_REL.

This bug was introduced by https://github.com/php/php-src/commit/3641507fc1a854ec56135740f528d5d428920833

Test script:
---------------
env REDIRECT_STATUS=200 REQUEST_METHOD=POST CONTENT_LENGTH= GATEWAY_INTERFACE=CGI/1.1 SCRIPT_NAME=/some_script.php SCRIPT_FILENAME=/some_script.php php-cgi

Actual result:
--------------
Process 45704 stopped
* thread #1: tid = 0xffcfb9, 0x00000001007e0393 php-cgi`_zval_dtor_func(zvalue=0x0000000104b447a0, __zend_filename="Zend/zend_execute.h", __zend_lineno=79) + 83 at zend_variables.c:36, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
    frame #0: 0x00000001007e0393 php-cgi`_zval_dtor_func(zvalue=0x0000000104b447a0, __zend_filename="Zend/zend_execute.h", __zend_lineno=79) + 83 at zend_variables.c:36
   33  		switch (Z_TYPE_P(zvalue) & IS_CONSTANT_TYPE_MASK) {
   34  			case IS_STRING:
   35  			case IS_CONSTANT:
-> 36  				CHECK_ZVAL_STRING_REL(zvalue);
   37  				str_efree_rel(zvalue->value.str.val);
   38  				break;
   39  			case IS_ARRAY: {
(lldb) bt
* thread #1: tid = 0xffcfb9, 0x00000001007e0393 php-cgi`_zval_dtor_func(zvalue=0x0000000104b447a0, __zend_filename="Zend/zend_execute.h", __zend_lineno=79) + 83 at zend_variables.c:36, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x00000001007e0393 php-cgi`_zval_dtor_func(zvalue=0x0000000104b447a0, __zend_filename="Zend/zend_execute.h", __zend_lineno=79) + 83 at zend_variables.c:36
    frame #1: 0x00000001007cd06c php-cgi`_zval_dtor(zvalue=0x0000000104b447a0, __zend_filename="Zend/zend_execute.h", __zend_lineno=79) + 60 at zend_variables.h:35
    frame #2: 0x00000001007c979f php-cgi`i_zval_ptr_dtor(zval_ptr=0x0000000104b447a0, __zend_filename="/opt/nr/src/php-5.6.16/Zend/zend_variables.c", __zend_lineno=188) + 175 at zend_execute.h:79
    frame #3: 0x00000001007c92a6 php-cgi`_zval_ptr_dtor(zval_ptr=0x0000000104b44f78, __zend_filename="/opt/nr/src/php-5.6.16/Zend/zend_variables.c", __zend_lineno=188) + 38 at zend_execute_API.c:424
    frame #4: 0x00000001007e0901 php-cgi`_zval_ptr_dtor_wrapper(zval_ptr=0x0000000104b44f78) + 33 at zend_variables.c:188
    frame #5: 0x00000001007fa451 php-cgi`i_zend_hash_bucket_delete(ht=0x0000000100ec0df8, p=0x0000000104b44f60) + 369 at zend_hash.c:182
    frame #6: 0x00000001007fa93d php-cgi`zend_hash_bucket_delete(ht=0x0000000100ec0df8, p=0x0000000104b44f60) + 29 at zend_hash.c:192
    frame #7: 0x00000001007fa994 php-cgi`zend_hash_graceful_reverse_destroy(ht=0x0000000100ec0df8) + 68 at zend_hash.c:613
    frame #8: 0x00000001007c8cfc php-cgi`shutdown_executor + 124 at zend_execute_API.c:244
    frame #9: 0x00000001007e4506 php-cgi`zend_deactivate + 134 at zend.c:960
    frame #10: 0x0000000100730621 php-cgi`php_request_shutdown(dummy=0x0000000000000000) + 961 at main.c:1883
    frame #11: 0x00000001008b093b php-cgi`main(argc=1, argv=0x00007fff5fbff9a0) + 9707 at cgi_main.c:2517
    frame #12: 0x00007fff99a815ad libdyld.dylib`start + 1
(lldb) p *zvalue
(zval) $0 = {
  value = {
    lval = 0
    dval = 0
    str = (val = <no value available>, len = 0)
    ht = 0x0000000000000000
    obj = {
      handle = 0
      handlers = 0x0000000000000000
    }
    ast = 0x0000000000000000
  }
  refcount__gc = 0
  type = '\x06'
  is_ref__gc = '\0'
}


Patches

http_raw_post_data_fix.patch (last revision 2016-04-01 00:34 UTC) by mike dot laspina at gmail dot com)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-06-20 16:43 UTC] remi@php.net
Automatic comment on behalf of remi
Revision: http://git.php.net/?p=php-src.git;a=commit;h=1b4570b79fa9810b171d3fb074c405f2f429ecad
Log: Fix bug #71936 (Segmentation fault destroying HTTP_RAW_POST_DATA)
 [2016-06-20 16:43 UTC] remi@php.net
-Status: Open +Status: Closed
 [2016-06-20 16:44 UTC] remi@php.net
Automatic comment on behalf of remi
Revision: http://git.php.net/?p=php-src.git;a=commit;h=1b4570b79fa9810b171d3fb074c405f2f429ecad
Log: Fix bug #71936 (Segmentation fault destroying HTTP_RAW_POST_DATA)
 [2016-06-20 16:45 UTC] remi@php.net
Automatic comment on behalf of remi
Revision: http://git.php.net/?p=php-src.git;a=commit;h=1b4570b79fa9810b171d3fb074c405f2f429ecad
Log: Fix bug #71936 (Segmentation fault destroying HTTP_RAW_POST_DATA)
 [2016-06-20 16:49 UTC] remi@php.net
-Assigned To: +Assigned To: remi
 [2016-06-20 16:49 UTC] remi@php.net
@mike, thanks for your help.

A slightly different patch was applied, test welcome.
 [2016-06-22 05:58 UTC] krakjoe@php.net
Automatic comment on behalf of remi
Revision: http://git.php.net/?p=php-src.git;a=commit;h=1b4570b79fa9810b171d3fb074c405f2f429ecad
Log: Fix bug #71936 (Segmentation fault destroying HTTP_RAW_POST_DATA)
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Aug 29 15:01:52 2017 UTC