1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
From 1b7410a57f8a5fd1dd43854bcf7b9200517c9fd2 Mon Sep 17 00:00:00 2001
From: Ahmed Lekssays <lekssaysahmed@gmail.com>
Date: Tue, 3 Jun 2025 09:00:55 +0000
Subject: [PATCH 1/4] Fix GHSA-453j-q27h-5p8x
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 <7771979+nielsdos@users.noreply.github.com>
(cherry picked from commit 9cb3d8d200f0c822b17bda35a2a67a97b039d3e1)
---
ext/soap/soap.c | 6 ++--
ext/soap/tests/soap_qname_crash.phpt | 48 ++++++++++++++++++++++++++++
2 files changed, 52 insertions(+), 2 deletions(-)
create mode 100644 ext/soap/tests/soap_qname_crash.phpt
diff --git a/ext/soap/soap.c b/ext/soap/soap.c
index a8df136d665..08d6f285d28 100644
--- a/ext/soap/soap.c
+++ b/ext/soap/soap.c
@@ -4143,8 +4143,10 @@ static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName,
}
xmlParam = master_to_xml(enc, val, style, parent);
zval_ptr_dtor(&defval);
- if (!strcmp((char*)xmlParam->name, "BOGUS")) {
- xmlNodeSetName(xmlParam, BAD_CAST(paramName));
+ if (xmlParam != NULL) {
+ if (xmlParam->name == NULL || strcmp((char*)xmlParam->name, "BOGUS") == 0) {
+ xmlNodeSetName(xmlParam, BAD_CAST(paramName));
+ }
}
return xmlParam;
}
diff --git a/ext/soap/tests/soap_qname_crash.phpt b/ext/soap/tests/soap_qname_crash.phpt
new file mode 100644
index 00000000000..52177577788
--- /dev/null
+++ b/ext/soap/tests/soap_qname_crash.phpt
@@ -0,0 +1,48 @@
+--TEST--
+Test SoapClient with excessively large QName prefix in SoapVar
+--EXTENSIONS--
+soap
+--SKIPIF--
+<?php
+if (PHP_INT_SIZE != 8) die("skip: 64-bit only");
+?>
+--INI--
+memory_limit=8G
+--FILE--
+<?php
+
+class TestSoapClient extends SoapClient {
+ public function __doRequest(
+ $request,
+ $location,
+ $action,
+ $version,
+ $one_way = false,
+ ): ?string {
+ die($request);
+ }
+}
+
+$prefix = str_repeat("A", 2 * 1024 * 1024 * 1024);
+$qname = "{$prefix}:tag";
+
+echo "Attempting to create SoapVar with very large QName\n";
+
+$var = new SoapVar("value", XSD_QNAME, null, null, $qname);
+
+echo "Attempting encoding\n";
+
+$options = [
+ 'location' => 'http://127.0.0.1/',
+ 'uri' => 'urn:dummy',
+ 'trace' => 1,
+ 'exceptions' => true,
+];
+$client = new TestSoapClient(null, $options);
+$client->__soapCall("DummyFunction", [$var]);
+?>
+--EXPECT--
+Attempting to create SoapVar with very large QName
+Attempting encoding
+<?xml version="1.0" encoding="UTF-8"?>
+<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>
--
2.50.0
|