php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73906 multi part response leads to segfault in Soapserver
Submitted: 2017-01-10 13:34 UTC Modified: -
Votes:8
Avg. Score:4.5 ± 0.5
Reproduced:8 of 8 (100.0%)
Same Version:2 (25.0%)
Same OS:6 (75.0%)
From: mib at nic dot at Assigned:
Status: Open Package: SOAP related
PHP Version: 7.0.14 OS: Linux
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: mib at nic dot at
New email:
PHP Version: OS:

 

 [2017-01-10 13:34 UTC] mib at nic dot at
Description:
------------
The Soapserver segfaults when generating a multi part response:

To reproduce the bug:

relevant WSDL parts:

<message name="read">
     <part name="label" type="xsd:string"/>
</message>
<message name="readResponse">
      <part name="readResult" type="xsd:string"/>
      <part name="label" type="xsd:string"/>
      <part name="value1" type="xsd:string"/>
</message>

<portType name="SOAPCrash">
       <operation name="read">
             <input message="s0:read"/>
             <output message="s0:readResponse"/>
        </operation>
</portType>


?>


The code runs fine in PHP 5.5/5.6 but crashes 7.0.14/7.1 



Test script:
---------------
<?php
 ini_set("soap.wsdl_cache_enabled", "0"); // disabling WSDL cache
 $server = new SoapServer("../crash.wsdl");
 $server->addFunction("read");

 $server->handle();

 function read ($label) {
 $return = array (new SoapParam("OK: $domain","readResult"),
                  new SoapParam("$label","label"),
                  new SoapParam("Value 1", "value1"));
 return $return;
}
?>

Actual result:
--------------
(gdb) bt
#0  strlen () at ../sysdeps/x86_64/strlen.S:106
#1  0x00007f372d4f64e3 in get_param (function=0x18, function@entry=0x7f37306af080, 
    param_name=0x18 <error: Cannot access memory at address 0x18>, index=0, response=24, response@entry=1)
    at /build/php7.0-VhrlDZ/php7.0-7.0.14/ext/soap/soap.c:4496
#2  0x00007f372d4f6d2f in serialize_response_call2 (body=body@entry=0x7f373d2e4730, function=function@entry=0x7f37306af080, 
    function_name=function_name@entry=0x7f37306b1450 "pollResponse", 
    uri=uri@entry=0x7f373065d120 "http://XXXXXXXXXX/XXXXXX", ret=ret@entry=0x7ffc1a0e3f10, version=version@entry=1, 
    main=main@entry=1, node=node@entry=0x0) at /build/php7.0-VhrlDZ/php7.0-7.0.14/ext/soap/soap.c:3829
#3  0x00007f372d4f734a in serialize_response_call (function=function@entry=0x7f37306af080, 
    function_name=function_name@entry=0x7f37306b1450 "pollResponse", uri=0x7f373065d120 "http://www.ipcom.at/RcodeZero/SecondaryDNS", 
    ret=ret@entry=0x7ffc1a0e3f10, headers=<optimized out>, version=version@entry=1)
    at /build/php7.0-VhrlDZ/php7.0-7.0.14/ext/soap/soap.c:4189
#4  0x00007f372d50261b in zim_SoapServer_handle (execute_data=<optimized out>, return_value=<optimized out>)
    at /build/php7.0-VhrlDZ/php7.0-7.0.14/ext/soap/soap.c:1915
#5  0x00007f37371ca44b in ?? () from /usr/lib/apache2/modules/libphp7.0.so
#6  0x00007f373718c59b in execute_ex () from /usr/lib/apache2/modules/libphp7.0.so
#7  0x00007f37371d5e0f in zend_execute () from /usr/lib/apache2/modules/libphp7.0.so
#8  0x00007f373714ffc4 in zend_execute_scripts () from /usr/lib/apache2/modules/libphp7.0.so
#9  0x00007f37370f2fd8 in php_execute_script () from /usr/lib/apache2/modules/libphp7.0.so
#10 0x00007f37371d7752 in ?? () from /usr/lib/apache2/modules/libphp7.0.so
#11 0x00007f373b5353f0 in ap_run_handler ()
#12 0x00007f373b535939 in ap_invoke_handler ()
#13 0x00007f373b54cd4a in ap_process_async_request ()
#14 0x00007f373b54d024 in ap_process_request ()
#15 0x00007f373b549005 in ?? ()
#16 0x00007f373b53f230 in ap_run_process_connection ()
#17 0x00007f373772aa20 in ?? () from /usr/lib/apache2/modules/mod_mpm_prefork.so
#18 0x00007f373772acb2 in ?? () from /usr/lib/apache2/modules/mod_mpm_prefork.so
#19 0x00007f373772ad1f in ?? () from /usr/lib/apache2/modules/mod_mpm_prefork.so
#20 0x00007f373772bbff in ?? () from /usr/lib/apache2/modules/mod_mpm_prefork.so
#21 0x00007f373b517f7e in ap_run_mpm ()
#22 0x00007f373b510ac8 in main ()


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-11-24 12:53 UTC] jonas at sitedirect dot se
Have the same issue but in 7.1.
Using Ondřej Surý Ubuntu PPA.
 [2018-07-03 07:24 UTC] bart at hexon dot cx
The problem is that ext/soap assumes that the PHP function that implements the SOAP operation returns an associative array.

In serialize_response_call2() (ext/soap/soap.c), near the end, the following code is used to loop through the value that should be returned:

} else if (param_count > 1 && Z_TYPE_P(ret) == IS_ARRAY) {
    zval *data;
    int i = 0;
    zend_string *param_name;
    zend_ulong param_index = i;

    ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(ret), param_index, param_name, data) {
        parameter = get_param(function, ZSTR_VAL(param_name), param_index, TRUE);

param_name contains the string key when ret is associative, but contains an invalid pointer if ret is numerical. It is passed to get_param, which calls strlen() on it, which segfaults.

Obviously this should not segfault, but the following change in the PHP code fixes the initial problem:

$return = array ("readResult" => new SoapParam("OK: $domain","readResult"),
                 "label" => new SoapParam("$label","label"),
                 "value1" => new SoapParam("Value 1", "value1"));
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Wed Oct 20 03:03:32 2021 UTC