[php-src] Issue #9720: segfault in php-soap, type conflict with zend_string and char
| From: | istoph | Date: | Tue, 11 Oct 2022 10:18:39 +0000 |
| Subject: | [php-src] Issue #9720: segfault in php-soap, type conflict with zend_string and char | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-242576@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/9720
Author: istoph
### Description
The following code:
```php
<?php
class soapService
{
function __construct() {
}
function openSession($user) {
return ["OK", "200"]; //<-- The array leads into the area that leads to
the error.
}
}
$sc = new SoapServer(__dir__ .'/service.wsdl');
$sc->setClass("soapService");
$sc->handle();
```
with this
service.wsdl file:
```xml
<?xml version="1.0" encoding="utf-8"?>
<definitions name="soapService" targetNamespace="urn:soapService"
xmlns:typens="urn:soapService" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<message name="openSession">
<part name="user" type="xsd:string" />
</message>
<message name="openSessionResponse">
<part name="status" type="xsd:string" />
<part name="error_code" type="xsd:string" />
</message>
<portType name="soapServicePortType">
<operation name="openSession">
<documentation>Service Call: openSession</documentation>
<input message="typens:openSession" />
<output message="typens:openSessionResponse" />
</operation>
</portType>
<binding name="soapServiceBinding" type="typens:soapServicePortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"
/>
<operation name="openSession">
<soap:operation soapAction="urn:openSession" />
<input>
<soap:body namespace="urn:soapService" use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
/>
</input>
<output>
<soap:body namespace="urn:soapService" use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
/>
</output>
</operation>
</binding>
<service name="soapServiceService">
<port name="soapServicePort" binding="typens:soapServiceBinding">
<soap:address location="###PHP_SELF###" />
</port>
</service>
</definitions>
```
Resulted in this a segfault with gdb output:
```gdb
Program received signal SIGSEGV, Segmentation fault.
0x00007f60ce1f1c75 in __strlen_avx2 () from /lib64/libc.so.6
(gdb) bt
#0 0x00007f60ce1f1c75 in __strlen_avx2 () from /lib64/libc.so.6
#1 0x00007f60c1cdeb6d in get_param (function=function@entry=0x7f60cc2720c0,
param_name=param_name@entry=0x18 <error: Cannot access memory at address 0x18>,
index=<optimized out>, response=response@entry=1)
at /usr/src/debug/php82-php-8.2.0~rc3-16.el8.remi.x86_64/ext/soap/soap.c:3978
#2 0x00007f60c1cdfe54 in serialize_response_call2 (body=body@entry=0x557c1ae411d0,
function=function@entry=0x7f60cc2720c0,
function_name=function_name@entry=0x7f60cc256078 "openSessionResponse",
uri=uri@entry=0x7f60cc2660c0 "urn:soapService",
ret=ret@entry=0x7ffcc3881630, version=version@entry=1, main=1, node=0x0)
at /usr/src/debug/php82-php-8.2.0~rc3-16.el8.remi.x86_64/ext/soap/soap.c:3292
#3 0x00007f60c1ce509b in serialize_response_call (function=0x7f60cc2720c0,
function_name=0x7f60cc256078 "openSessionResponse",
uri=0x7f60cc2660c0 "urn:soapService", ret=0x7ffcc3881630, headers=0x0, version=1)
at /usr/src/debug/php82-php-8.2.0~rc3-16.el8.remi.x86_64/ext/soap/soap.c:3660
#4 0x00007f60c1ced386 in zim_SoapServer_handle (execute_data=0x7f60cc213090,
return_value=<optimized out>)
at /usr/src/debug/php82-php-8.2.0~rc3-16.el8.remi.x86_64/ext/soap/soap.c:1484
#5 0x00007f60cbcbe4f5 in xdebug_execute_internal () from
/opt/remi/php82/root/usr/lib64/php/modules/xdebug.so
#6 0x0000557c196a02c8 in ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HANDLER ()
at /usr/src/debug/php82-php-8.2.0~rc3-16.el8.remi.x86_64/Zend/zend_vm_execute.h:1844
#7 execute_ex (ex=0x18) at
/usr/src/debug/php82-php-8.2.0~rc3-16.el8.remi.x86_64/Zend/zend_vm_execute.h:56047
#8 0x00007f60cbcbda4c in xdebug_execute_ex () from
/opt/remi/php82/root/usr/lib64/php/modules/xdebug.so
#9 0x0000557c196a1932 in zend_execute (op_array=0x7f60cc280000, return_value=0x0)
at /usr/src/debug/php82-php-8.2.0~rc3-16.el8.remi.x86_64/Zend/zend_vm_execute.h:60379
#10 0x0000557c1962ed15 in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0,
file_count=file_count@entry=3)
at /usr/src/debug/php82-php-8.2.0~rc3-16.el8.remi.x86_64/Zend/zend.c:1780
#11 0x0000557c195c849a in php_execute_script (primary_file=<optimized out>) at
/usr/src/debug/php82-php-8.2.0~rc3-16.el8.remi.x86_64/main/main.c:2537
#12 0x0000557c1946e662 in main (argc=<optimized out>, argv=<optimized out>)
at /usr/src/debug/php82-php-8.2.0~rc3-16.el8.remi.x86_64/sapi/fpm/fpm/fpm_main.c:1891
(gdb) frame 2
#2 0x00007f60c1cdfe54 in serialize_response_call2 (body=body@entry=0x557c1ae411d0,
function=function@entry=0x7f60cc2720c0,
function_name=function_name@entry=0x7f60cc256078 "openSessionResponse",
uri=uri@entry=0x7f60cc2660c0 "urn:soapService",
ret=ret@entry=0x7ffcc3881630, version=version@entry=1, main=1, node=0x0)
at /usr/src/debug/php82-php-8.2.0~rc3-16.el8.remi.x86_64/ext/soap/soap.c:3292
3292 parameter = get_param(function, ZSTR_VAL(param_name), param_index, TRUE);
(gdb) info locals
_z = 0x557c1b8bf740
__ht = 0x557c1b8bf700
__key = 0x0
_idx = 1
_count = 2
__h = <optimized out>
_size = <optimized out>
__z = 0x557c1b8bf750
data = 0x557c1b8bf740
i = 0
param_name = 0x0
param_index = <optimized out>
method = <optimized out>
param = <optimized out>
parameter = <optimized out>
param_count = <optimized out>
style = <optimized out>
use = <optimized out>
ns = <optimized out>
(gdb) frame 1
#1 0x00007f60c1cdeb6d in get_param (function=function@entry=0x7f60cc2720c0,
param_name=param_name@entry=0x18 <error: Cannot access memory at address 0x18>,
index=<optimized out>, response=response@entry=1)
at /usr/src/debug/php82-php-8.2.0~rc3-16.el8.remi.x86_64/ext/soap/soap.c:3978
3978 if ((tmp = zend_hash_str_find_ptr(ht, param_name, strlen(param_name))) != NULL) {
(gdb) info locals
tmp = <optimized out>
ht = 0x7f60cc260428
```
In frame 2 the var param_name is from type zend_string but in frame 1 a
char* is expected. The type conflict leads to 0x18 not being recognized as
null in the if statement before.
But I expected this output instead:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="urn:soapService" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:openSessionResponse><status
xsi:type="xsd:string">OK</status><error_code
xsi:type="xsd:string">200</error_code></ns1:openSessionResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
```
After we call it with:
```bash
curl -L --request POST --data '<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="urn:soapService" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/s
<SOAP-ENV:Body><ns1:openSession><user
xsi:type="xsd:string">istoph</user></ns1:openSession></SOAP-ENV:Body></SOAP-ENV:Envelope>'
http://localhost:8080/soap/ -H "Content-Type:
text/xml; charset=UTF-8"
```
In version PHP 5.6.32 this example still works. Between PHP 7.0 and 8.2 we could see the failure.
### PHP Version
PHP 8.2.0
### Operating System
Rhel 8