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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
From d0bc0dbb20e906324e874197fa71d7b4583e59b6 Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <stas@php.net>
Date: Sun, 31 Jan 2021 21:15:23 -0800
Subject: [PATCH 1/2] Fix bug #80672 - Null Dereference in SoapClient
(cherry picked from commit 3c939e3f69955d087e0bb671868f7267dfb2a502)
(cherry picked from commit f1e2cfa008d1596251968d13eb9a8539dba6879f)
---
NEWS | 5 +++++
ext/soap/php_sdl.c | 26 ++++++++++++++------------
ext/soap/php_xml.c | 4 ++--
ext/soap/tests/bug80672.phpt | 15 +++++++++++++++
ext/soap/tests/bug80672.xml | 6 ++++++
5 files changed, 42 insertions(+), 14 deletions(-)
create mode 100644 ext/soap/tests/bug80672.phpt
create mode 100644 ext/soap/tests/bug80672.xml
diff --git a/NEWS b/NEWS
index 43e3b8faf3..8e9bd9648e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,11 @@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+Backported from 7.3.27
+
+- SOAP:
+ . Fixed bug #80672 (Null Dereference in SoapClient). (CVE-2021-21702) (cmb, Stas)
+
Backported from 7.3.26
- Standard:
diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c
index 51aea0021e..49f61374cb 100644
--- a/ext/soap/php_sdl.c
+++ b/ext/soap/php_sdl.c
@@ -318,6 +318,8 @@ void sdl_restore_uri_credentials(sdlCtx *ctx TSRMLS_DC)
ctx->context = NULL;
}
+#define SAFE_STR(a) ((a)?a:"")
+
static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include TSRMLS_DC)
{
sdlPtr tmpsdl = ctx->sdl;
@@ -379,7 +381,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include
if (node_is_equal_ex(trav2, "schema", XSD_NAMESPACE)) {
load_schema(ctx, trav2 TSRMLS_CC);
} else if (is_wsdl_element(trav2) && !node_is_equal(trav2,"documentation")) {
- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name);
+ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav2->name));
}
trav2 = trav2->next;
}
@@ -440,7 +442,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include
soap_error0(E_ERROR, "Parsing WSDL: <service> has no name attribute");
}
} else if (!node_is_equal(trav,"documentation")) {
- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
+ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name));
}
trav = trav->next;
}
@@ -550,7 +552,7 @@ static sdlSoapBindingFunctionHeaderPtr wsdl_soap_binding_header(sdlCtx* ctx, xml
}
smart_str_free(&key);
} else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
+ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name));
}
trav = trav->next;
}
@@ -655,7 +657,7 @@ static void wsdl_soap_binding_body(sdlCtx* ctx, xmlNodePtr node, char* wsdl_soap
}
smart_str_free(&key);
} else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
+ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name));
}
trav = trav->next;
}
@@ -687,14 +689,14 @@ static HashTable* wsdl_message(sdlCtx *ctx, xmlChar* message_name)
sdlParamPtr param;
if (trav->ns != NULL && strcmp((char*)trav->ns->href, WSDL_NAMESPACE) != 0) {
- soap_error1(E_ERROR, "Parsing WSDL: Unexpected extensibility element <%s>", trav->name);
+ soap_error1(E_ERROR, "Parsing WSDL: Unexpected extensibility element <%s>", SAFE_STR(trav->name));
}
if (node_is_equal(trav,"documentation")) {
trav = trav->next;
continue;
}
if (!node_is_equal(trav,"part")) {
- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
+ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name));
}
part = trav;
param = emalloc(sizeof(sdlParam));
@@ -703,7 +705,7 @@ static HashTable* wsdl_message(sdlCtx *ctx, xmlChar* message_name)
name = get_attribute(part->properties, "name");
if (name == NULL) {
- soap_error1(E_ERROR, "Parsing WSDL: No name associated with <part> '%s'", message->name);
+ soap_error1(E_ERROR, "Parsing WSDL: No name associated with <part> '%s'", SAFE_STR(message->name));
}
param->paramName = estrdup((char*)name->children->content);
@@ -773,7 +775,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
continue;
}
if (!node_is_equal(trav,"port")) {
- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
+ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name));
}
port = trav;
@@ -812,7 +814,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
}
}
if (trav2 != address && is_wsdl_element(trav2) && !node_is_equal(trav2,"documentation")) {
- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name);
+ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav2->name));
}
trav2 = trav2->next;
}
@@ -914,7 +916,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
continue;
}
if (!node_is_equal(trav2,"operation")) {
- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name);
+ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav2->name));
}
operation = trav2;
@@ -933,7 +935,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
!node_is_equal(trav3,"output") &&
!node_is_equal(trav3,"fault") &&
!node_is_equal(trav3,"documentation")) {
- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav3->name);
+ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav3->name));
}
trav3 = trav3->next;
}
@@ -1111,7 +1113,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri TSRMLS_DC)
}
}
} else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
+ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name));
}
trav = trav->next;
}
diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c
index f3b49dfd41..4694b4e05d 100644
--- a/ext/soap/php_xml.c
+++ b/ext/soap/php_xml.c
@@ -205,7 +205,7 @@ xmlNsPtr node_find_ns(xmlNodePtr node)
int attr_is_equal_ex(xmlAttrPtr node, char *name, char *ns)
{
- if (name == NULL || strcmp((char*)node->name, name) == 0) {
+ if (name == NULL || ((node->name) && strcmp((char*)node->name, name) == 0)) {
if (ns) {
xmlNsPtr nsPtr = attr_find_ns(node);
if (nsPtr) {
@@ -221,7 +221,7 @@ int attr_is_equal_ex(xmlAttrPtr node, char *name, char *ns)
int node_is_equal_ex(xmlNodePtr node, char *name, char *ns)
{
- if (name == NULL || strcmp((char*)node->name, name) == 0) {
+ if (name == NULL || ((node->name) && strcmp((char*)node->name, name) == 0)) {
if (ns) {
xmlNsPtr nsPtr = node_find_ns(node);
if (nsPtr) {
diff --git a/ext/soap/tests/bug80672.phpt b/ext/soap/tests/bug80672.phpt
new file mode 100644
index 0000000000..71e2b1d841
--- /dev/null
+++ b/ext/soap/tests/bug80672.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Bug #80672 Null Dereference in SoapClient
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+try {
+ $client = new SoapClient(__DIR__ . "/bug80672.xml");
+ $query = $soap->query(array('sXML' => 'something'));
+} catch(SoapFault $e) {
+ print $e->getMessage();
+}
+?>
+--EXPECTF--
+SOAP-ERROR: Parsing WSDL: Unexpected WSDL element <>
\ No newline at end of file
diff --git a/ext/soap/tests/bug80672.xml b/ext/soap/tests/bug80672.xml
new file mode 100644
index 0000000000..0fa185bf1e
--- /dev/null
+++ b/ext/soap/tests/bug80672.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<soap:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:soap="http://schemas.xmlsoap.org/wsdl/">
+<![CDATA[test]]>
+</soap:definitions>
--
2.29.2
From 0373255df92545ded6df1a8b1af58ee63bae1754 Mon Sep 17 00:00:00 2001
From: Nikita Popov <nikita.ppv@gmail.com>
Date: Mon, 1 Feb 2021 09:46:17 +0100
Subject: [PATCH 2/2] Fix build
(cherry picked from commit e5d767d27f94895e09f0321562fd3774d4656164)
(cherry picked from commit 02352d5acc1896756dcb4645f54689ffdcc4ca52)
---
ext/soap/php_sdl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c
index 49f61374cb..4a3a2fab52 100644
--- a/ext/soap/php_sdl.c
+++ b/ext/soap/php_sdl.c
@@ -318,7 +318,7 @@ void sdl_restore_uri_credentials(sdlCtx *ctx TSRMLS_DC)
ctx->context = NULL;
}
-#define SAFE_STR(a) ((a)?a:"")
+#define SAFE_STR(a) ((a)?((const char *)a):"")
static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include TSRMLS_DC)
{
--
2.29.2
|