Commit: 552e8b2b4c5708cb90faf148bd99e3f67fa926b5
Author: Dmitry Stogov <dmi...@zend.com> Tue, 10 Dec 2013 17:57:05
+0400
Parents: a46f644b3ac4abe7577165de4e4850e5c2c88227
Branches: PHP-5.5 PHP-5.6 master
Link:
http://git.php.net/?p=php-src.git;a=commitdiff;h=552e8b2b4c5708cb90faf148bd99e3f67fa926b5
Log:
Fixed bug #66112 (Use after free condition in SOAP extension). (martin dot
koegler at brz dot gv dot at)
Bugs:
https://bugs.php.net/66112
Changed paths:
M NEWS
M ext/soap/soap.c
A ext/soap/tests/bugs/bug66112.phpt
A ext/soap/tests/bugs/bug66112.wsdl
diff --git a/NEWS b/NEWS
index 0d6edf2..1e7ce53 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,10 @@ PHP
NEWS
- Filter:
. Fixed bug #66229 (128.0.0.0/16 isn't reserved any longer). (Adam)
+- SOAP
+ . Fixed bug #66112 (Use after free condition in SOAP extension).
+ (martin dot koegler at brz dot gv dot at)
+
- Sockets:
. Fixed bug #65923 (ext/socket assumes AI_V4MAPPED is defined). (Felipe)
diff --git a/ext/soap/soap.c b/ext/soap/soap.c
index 0404096..3448df4 100644
--- a/ext/soap/soap.c
+++ b/ext/soap/soap.c
@@ -2694,124 +2694,133 @@ static void do_soap_call(zval* this_ptr,
SOAP_GLOBAL(features) = 0;
}
- if (sdl != NULL) {
- fn = get_function(sdl, function);
- if (fn != NULL) {
- sdlBindingPtr binding = fn->binding;
- int one_way = 0;
-
- if (fn->responseName == NULL &&
- fn->responseParameters == NULL &&
- soap_headers == NULL) {
- one_way = 1;
- }
+ zend_try {
+ if (sdl != NULL) {
+ fn = get_function(sdl, function);
+ if (fn != NULL) {
+ sdlBindingPtr binding = fn->binding;
+ int one_way = 0;
+
+ if (fn->responseName == NULL &&
+ fn->responseParameters == NULL &&
+ soap_headers == NULL) {
+ one_way = 1;
+ }
- if (location == NULL) {
- location = binding->location;
- }
- if (binding->bindingType == BINDING_SOAP) {
- sdlSoapBindingFunctionPtr fnb =
(sdlSoapBindingFunctionPtr)fn->bindingAttributes;
- request = serialize_function_call(this_ptr, fn,
NULL, fnb->input.ns, real_args, arg_count, soap_version, soap_headers
TSRMLS_CC);
- ret = do_request(this_ptr, request, location,
fnb->soapAction, soap_version, one_way, &response TSRMLS_CC);
- } else {
- request = serialize_function_call(this_ptr, fn,
NULL, sdl->target_ns, real_args, arg_count, soap_version, soap_headers
TSRMLS_CC);
- ret = do_request(this_ptr, request, location,
NULL, soap_version, one_way, &response TSRMLS_CC);
- }
-
- xmlFreeDoc(request);
-
- if (ret && Z_TYPE(response) == IS_STRING) {
- encode_reset_ns();
- ret = parse_packet_soap(this_ptr,
Z_STRVAL(response), Z_STRLEN(response), fn, NULL, return_value, output_headers
TSRMLS_CC);
- encode_finish();
- }
+ if (location == NULL) {
+ location = binding->location;
+ }
+ if (binding->bindingType == BINDING_SOAP) {
+ sdlSoapBindingFunctionPtr fnb =
(sdlSoapBindingFunctionPtr)fn->bindingAttributes;
+ request =
serialize_function_call(this_ptr, fn, NULL, fnb->input.ns, real_args,
arg_count, soap_version, soap_headers TSRMLS_CC);
+ ret = do_request(this_ptr, request,
location, fnb->soapAction, soap_version, one_way, &response TSRMLS_CC);
+ } else {
+ request =
serialize_function_call(this_ptr, fn, NULL, sdl->target_ns, real_args,
arg_count, soap_version, soap_headers TSRMLS_CC);
+ ret = do_request(this_ptr, request,
location, NULL, soap_version, one_way, &response TSRMLS_CC);
+ }
+
+ xmlFreeDoc(request);
+
+ if (ret && Z_TYPE(response) == IS_STRING) {
+ encode_reset_ns();
+ ret = parse_packet_soap(this_ptr,
Z_STRVAL(response), Z_STRLEN(response), fn, NULL, return_value, output_headers
TSRMLS_CC);
+ encode_finish();
+ }
- zval_dtor(&response);
+ zval_dtor(&response);
- } else {
- smart_str error = {0};
- smart_str_appends(&error,"Function (\"");
- smart_str_appends(&error,function);
- smart_str_appends(&error,"\") is not a valid method for
this service");
- smart_str_0(&error);
- add_soap_fault(this_ptr, "Client", error.c, NULL, NULL
TSRMLS_CC);
- smart_str_free(&error);
- }
- } else {
- zval **uri;
- smart_str action = {0};
-
- if (zend_hash_find(Z_OBJPROP_P(this_ptr), "uri", sizeof("uri"),
(void *)&uri) == FAILURE) {
- add_soap_fault(this_ptr, "Client", "Error finding
\"uri\" property", NULL, NULL TSRMLS_CC);
- } else if (location == NULL) {
- add_soap_fault(this_ptr, "Client", "Error could not
find \"location\" property", NULL, NULL TSRMLS_CC);
- } else {
- if (call_uri == NULL) {
- call_uri = Z_STRVAL_PP(uri);
+ } else {
+ smart_str error = {0};
+ smart_str_appends(&error,"Function (\"");
+ smart_str_appends(&error,function);
+ smart_str_appends(&error,"\") is not a valid
method for this service");
+ smart_str_0(&error);
+ add_soap_fault(this_ptr, "Client", error.c,
NULL, NULL TSRMLS_CC);
+ smart_str_free(&error);
}
- request = serialize_function_call(this_ptr, NULL,
function, call_uri, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
+ } else {
+ zval **uri;
+ smart_str action = {0};
- if (soap_action == NULL) {
- smart_str_appends(&action, call_uri);
- smart_str_appendc(&action, '#');
- smart_str_appends(&action, function);
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "uri",
sizeof("uri"), (void *)&uri) == FAILURE) {
+ add_soap_fault(this_ptr, "Client", "Error
finding \"uri\" property", NULL, NULL TSRMLS_CC);
+ } else if (location == NULL) {
+ add_soap_fault(this_ptr, "Client", "Error could
not find \"location\" property", NULL, NULL TSRMLS_CC);
} else {
- smart_str_appends(&action, soap_action);
- }
- smart_str_0(&action);
+ if (call_uri == NULL) {
+ call_uri = Z_STRVAL_PP(uri);
+ }
+ request = serialize_function_call(this_ptr,
NULL, function, call_uri, real_args, arg_count, soap_version, soap_headers
TSRMLS_CC);
- ret = do_request(this_ptr, request, location, action.c,
soap_version, 0, &response TSRMLS_CC);
+ if (soap_action == NULL) {
+ smart_str_appends(&action, call_uri);
+ smart_str_appendc(&action, '#');
+ smart_str_appends(&action, function);
+ } else {
+ smart_str_appends(&action, soap_action);
+ }
+ smart_str_0(&action);
- smart_str_free(&action);
- xmlFreeDoc(request);
+ ret = do_request(this_ptr, request, location,
action.c, soap_version, 0, &response TSRMLS_CC);
- if (ret && Z_TYPE(response) == IS_STRING) {
- encode_reset_ns();
- ret = parse_packet_soap(this_ptr,
Z_STRVAL(response), Z_STRLEN(response), NULL, function, return_value,
output_headers TSRMLS_CC);
- encode_finish();
- }
+ smart_str_free(&action);
+ xmlFreeDoc(request);
- zval_dtor(&response);
- }
- }
+ if (ret && Z_TYPE(response) == IS_STRING) {
+ encode_reset_ns();
+ ret = parse_packet_soap(this_ptr,
Z_STRVAL(response), Z_STRLEN(response), NULL, function, return_value,
output_headers TSRMLS_CC);
+ encode_finish();
+ }
- if (!ret) {
- zval** fault;
- if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault",
sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
- *return_value = **fault;
- zval_copy_ctor(return_value);
+ zval_dtor(&response);
+ }
+ }
+
+ if (!ret) {
+ zval** fault;
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr),
"__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
+ *return_value = **fault;
+ zval_copy_ctor(return_value);
+ } else {
+ *return_value = *add_soap_fault(this_ptr,
"Client", "Unknown Error", NULL, NULL TSRMLS_CC);
+ zval_copy_ctor(return_value);
+ }
} else {
- *return_value = *add_soap_fault(this_ptr, "Client",
"Unknown Error", NULL, NULL TSRMLS_CC);
- zval_copy_ctor(return_value);
- }
- } else {
- zval** fault;
- if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault",
sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
- *return_value = **fault;
- zval_copy_ctor(return_value);
+ zval** fault;
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr),
"__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
+ *return_value = **fault;
+ zval_copy_ctor(return_value);
+ }
}
- }
- if (!EG(exception) &&
- Z_TYPE_P(return_value) == IS_OBJECT &&
- instanceof_function(Z_OBJCE_P(return_value), soap_fault_class_entry
TSRMLS_CC) &&
- (zend_hash_find(Z_OBJPROP_P(this_ptr), "_exceptions",
sizeof("_exceptions"), (void **) &tmp) != SUCCESS ||
- Z_TYPE_PP(tmp) != IS_BOOL || Z_LVAL_PP(tmp) != 0)) {
- zval *exception;
+ if (!EG(exception) &&
+ Z_TYPE_P(return_value) == IS_OBJECT &&
+ instanceof_function(Z_OBJCE_P(return_value),
soap_fault_class_entry TSRMLS_CC) &&
+ (zend_hash_find(Z_OBJPROP_P(this_ptr), "_exceptions",
sizeof("_exceptions"), (void **) &tmp) != SUCCESS ||
+ Z_TYPE_PP(tmp) != IS_BOOL || Z_LVAL_PP(tmp) != 0)) {
+ zval *exception;
- MAKE_STD_ZVAL(exception);
- MAKE_COPY_ZVAL(&return_value, exception);
- zend_throw_exception_object(exception TSRMLS_CC);
- }
+ MAKE_STD_ZVAL(exception);
+ MAKE_COPY_ZVAL(&return_value, exception);
+ zend_throw_exception_object(exception TSRMLS_CC);
+ }
+ } zend_catch {
+ _bailout = 1;
+ } zend_end_try();
+
if (SOAP_GLOBAL(encoding) != NULL) {
xmlCharEncCloseFunc(SOAP_GLOBAL(encoding));
}
+
SOAP_GLOBAL(features) = old_features;
SOAP_GLOBAL(typemap) = old_typemap;
SOAP_GLOBAL(class_map) = old_class_map;
SOAP_GLOBAL(encoding) = old_encoding;
SOAP_GLOBAL(sdl) = old_sdl;
+ if (_bailout) {
+ zend_bailout();
+ }
SOAP_CLIENT_END_CODE();
}
diff --git a/ext/soap/tests/bugs/bug66112.phpt
b/ext/soap/tests/bugs/bug66112.phpt
new file mode 100644
index 0000000..6df3a4e
--- /dev/null
+++ b/ext/soap/tests/bugs/bug66112.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Bug #66112 (Use after free condition in SOAP extension)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--INI--
+soap.wsdl_cache_enabled=0
+--FILE--
+<?php
+define('WSDL', dirname(__FILE__)."/bug66112.wsdl");
+function Mist($p) {
+ $client=new soapclient(WSDL,
array('typemap'=>array(array("type_ns"=>"uri:mist", "type_name"=>"A"))));
+ try{
+ $client->Mist(array("XX"=>"xx"));
+ }catch(SoapFault $x){
+ }
+ return array("A"=>"ABC","B"=>"sss");
+}
+$s = new SoapServer(WSDL, array('typemap'=>array(array("type_ns"=>"uri:mist",
"type_name"=>"A"))));
+$s->addFunction("Mist");
+$_SERVER["REQUEST_METHOD"] = "POST";
+$HTTP_RAW_POST_DATA=<<<EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:uri="uri:mist">
+ <soapenv:Header/>
+ <soapenv:Body>
+ <uri:Request><uri:A>XXX</uri:A><uri:B>yyy</uri:B></uri:Request>
+ </soapenv:Body>
+</soapenv:Envelope>
+EOF;
+echo "OK\n";
+$s->handle($HTTP_RAW_POST_DATA);
+echo "BUG\n";
+?>
+--EXPECT--
+OK
diff --git a/ext/soap/tests/bugs/bug66112.wsdl
b/ext/soap/tests/bugs/bug66112.wsdl
new file mode 100644
index 0000000..8589a46
--- /dev/null
+++ b/ext/soap/tests/bugs/bug66112.wsdl
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:tns="uri:mist"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="test"
targetNamespace="uri:mist">
+ <wsdl:types>
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="uri:mist">
+ <xs:complexType name="T1">
+ <xs:sequence>
+ <xs:element name="A" type="xsd:string"/><xs:element name="B"
type="xsd:string"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:element name="Request" type="tns:T1"/><xs:element name="Response"
type="tns:T1"/>
+ </xs:schema>
+ </wsdl:types>
+ <wsdl:message name="Request">
+ <wsdl:part name="Request" element="tns:Request"/>
+ </wsdl:message>
+ <wsdl:message name="Response">
+ <wsdl:part name="Response" element="tns:Response"/>
+ </wsdl:message>
+ <wsdl:portType name="test">
+ <wsdl:operation name="Mist">
+ <wsdl:input message="tns:Request"/>
+ <wsdl:output message="tns:Response"/>
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="test" type="tns:test">
+ <soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
+ <wsdl:operation name="Mist">
+ <soap:operation soapAction="Mist"/>
+ <wsdl:input>
+ <soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="test">
+ <wsdl:port name="test" binding="tns:test">
+ <soap:address location="http://127.0.0.1:81/mist.php"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php