Skip to content

Commit dd06065

Browse files
Lekssaysnielsdos
authored andcommitted
Libxml versions prior to 2.13 cannot correctly handle a call to xmlNodeSetName() with a name longer than 2G. It will leave the node object in an invalid state with a NULL name. This later causes a NULL pointer dereference when using the name during message serialization. To solve this, implement a workaround that resets the name to the sentinel name if this situation arises. Versions of libxml of 2.13 and higher are not affected. This can be exploited if a SoapVar is created with a fully qualified name that is longer than 2G. This would be possible if some application code uses a namespace prefix from an untrusted source like from a remote SOAP service. Co-authored-by: Niels Dossche <[email protected]>
1 parent 545d153 commit dd06065

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

ext/soap/soap.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3980,8 +3980,10 @@ static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName,
39803980
}
39813981
xmlParam = master_to_xml(enc, val, style, parent);
39823982
zval_ptr_dtor(&defval);
3983-
if (!strcmp((char*)xmlParam->name, "BOGUS")) {
3984-
xmlNodeSetName(xmlParam, BAD_CAST(paramName));
3983+
if (xmlParam != NULL) {
3984+
if (xmlParam->name == NULL || strcmp((char*)xmlParam->name, "BOGUS") == 0) {
3985+
xmlNodeSetName(xmlParam, BAD_CAST(paramName));
3986+
}
39853987
}
39863988
return xmlParam;
39873989
}

ext/soap/tests/soap_qname_crash.phpt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
--TEST--
2+
Test SoapClient with excessively large QName prefix in SoapVar
3+
--EXTENSIONS--
4+
soap
5+
--SKIPIF--
6+
<?php
7+
if (PHP_INT_SIZE != 8) die("skip: 64-bit only");
8+
?>
9+
--INI--
10+
memory_limit=6144M
11+
--FILE--
12+
<?php
13+
14+
class TestSoapClient extends SoapClient {
15+
public function __doRequest(
16+
$request,
17+
$location,
18+
$action,
19+
$version,
20+
$one_way = false,
21+
): ?string {
22+
die($request);
23+
}
24+
}
25+
26+
$prefix = str_repeat("A", 2 * 1024 * 1024 * 1024);
27+
$qname = "{$prefix}:tag";
28+
29+
echo "Attempting to create SoapVar with very large QName\n";
30+
31+
$var = new SoapVar("value", XSD_QNAME, null, null, $qname);
32+
33+
echo "Attempting encoding\n";
34+
35+
$options = [
36+
'location' => 'http://127.0.0.1/',
37+
'uri' => 'urn:dummy',
38+
'trace' => 1,
39+
'exceptions' => true,
40+
];
41+
$client = new TestSoapClient(null, $options);
42+
$client->__soapCall("DummyFunction", [$var]);
43+
?>
44+
--EXPECT--
45+
Attempting to create SoapVar with very large QName
46+
Attempting encoding
47+
<?xml version="1.0" encoding="UTF-8"?>
48+
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:dummy" 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:DummyFunction><param0 xsi:type="xsd:QName">value</param0></ns1:DummyFunction></SOAP-ENV:Body></SOAP-ENV:Envelope>

0 commit comments

Comments
 (0)