summaryrefslogtreecommitdiffstats
path: root/php-bug79971.patch
blob: 5d750e2dce871d8ed54ad46cb914bbeed8c8d47a (plain)
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
From a9a1eb2383f7b95c4e6a52d40dd99651e0c1c53c Mon Sep 17 00:00:00 2001
From: "Christoph M. Becker" <cmbecker69@gmx.de>
Date: Tue, 1 Sep 2020 10:04:28 +0200
Subject: [PATCH 1/4] Fix #79971: special character is breaking the path in xml
 function

The libxml based XML functions accepting a filename actually accept
URIs with possibly percent-encoded characters.  Percent-encoded NUL
bytes lead to truncation, like non-encoded NUL bytes would.  We catch
those, and let the functions fail with a respective warning.

(cherry picked from commit f15f8fc573eb38c3c73e23e0930063a6f6409ed4)
---
 ext/dom/domimplementation.c         |  5 +++++
 ext/dom/tests/bug79971_2.phpt       | 20 ++++++++++++++++++++
 ext/libxml/libxml.c                 | 10 ++++++++++
 ext/simplexml/tests/bug79971_1.phpt | 27 +++++++++++++++++++++++++++
 ext/simplexml/tests/bug79971_1.xml  |  2 ++
 5 files changed, 64 insertions(+)
 create mode 100644 ext/dom/tests/bug79971_2.phpt
 create mode 100644 ext/simplexml/tests/bug79971_1.phpt
 create mode 100644 ext/simplexml/tests/bug79971_1.xml

diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c
index d79430b660..5f2b4e6776 100644
--- a/ext/dom/domimplementation.c
+++ b/ext/dom/domimplementation.c
@@ -111,6 +111,11 @@ PHP_METHOD(domimplementation, createDocumentType)
 	if (systemid_len > 0)
 		pch2 = systemid;
 
+	if (strstr(name, "%00")) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "URI must not contain percent-encoded NUL bytes");
+		RETURN_FALSE;
+	}
+
 	uri = xmlParseURI(name);
 	if (uri != NULL && uri->opaque != NULL) {
 		localname = xmlStrdup(uri->opaque);
diff --git a/ext/dom/tests/bug79971_2.phpt b/ext/dom/tests/bug79971_2.phpt
new file mode 100644
index 0000000000..c4e6b1e4e0
--- /dev/null
+++ b/ext/dom/tests/bug79971_2.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Bug #79971 (special character is breaking the path in xml function)
+--SKIPIF--
+<?php
+if (!extension_loaded('dom')) die('skip dom extension not available');
+?>
+--FILE--
+<?php
+$imp = new DOMImplementation;
+if (PHP_OS_FAMILY === 'Windows') {
+    $path = '/' . str_replace('\\', '/', __DIR__);
+} else {
+    $path = __DIR__;
+}
+$uri = "file://$path/bug79971_2.xml";
+var_dump($imp->createDocumentType("$uri%00foo"));
+?>
+--EXPECTF--
+Warning: DOMImplementation::createDocumentType(): URI must not contain percent-encoded NUL bytes in %s on line %d
+bool(false)
diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c
index b252cb6d81..d4a47ff702 100644
--- a/ext/libxml/libxml.c
+++ b/ext/libxml/libxml.c
@@ -301,6 +301,11 @@ static void *php_libxml_streams_IO_open_wrapper(const char *filename, const char
 
 	TSRMLS_FETCH();
 
+	if (strstr(filename, "%00")) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "URI must not contain percent-encoded NUL bytes");
+		return NULL;
+	}
+
 	uri = xmlParseURI(filename);
 	if (uri && (uri->scheme == NULL ||
 			(xmlStrncmp(BAD_CAST uri->scheme, BAD_CAST "file", 4) == 0))) {
@@ -431,6 +436,11 @@ php_libxml_output_buffer_create_filename(const char *URI,
 	if (URI == NULL)
 		return(NULL);
 
+	if (strstr(URI, "%00")) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "URI must not contain percent-encoded NUL bytes");
+		return NULL;
+	}
+
 	puri = xmlParseURI(URI);
 	if (puri != NULL) {
 		if (puri->scheme != NULL)
diff --git a/ext/simplexml/tests/bug79971_1.phpt b/ext/simplexml/tests/bug79971_1.phpt
new file mode 100644
index 0000000000..197776d82d
--- /dev/null
+++ b/ext/simplexml/tests/bug79971_1.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Bug #79971 (special character is breaking the path in xml function)
+--SKIPIF--
+<?php
+if (!extension_loaded('simplexml')) die('skip simplexml extension not available');
+?>
+--FILE--
+<?php
+if (PHP_OS_FAMILY === 'Windows') {
+    $path = '/' . str_replace('\\', '/', __DIR__);
+} else {
+    $path = __DIR__;
+}
+$uri = "file://$path/bug79971_1.xml";
+var_dump(simplexml_load_file("$uri%00foo"));
+
+$sxe = simplexml_load_file($uri);
+var_dump($sxe->asXML("$uri.out%00foo"));
+?>
+--EXPECTF--
+Warning: simplexml_load_file(): URI must not contain percent-encoded NUL bytes in %s on line %d
+
+Warning: simplexml_load_file(): I/O warning : failed to load external entity "%s/bug79971_1.xml%00foo" in %s on line %d
+bool(false)
+
+Warning: SimpleXMLElement::asXML(): URI must not contain percent-encoded NUL bytes in %s on line %d
+bool(false)
diff --git a/ext/simplexml/tests/bug79971_1.xml b/ext/simplexml/tests/bug79971_1.xml
new file mode 100644
index 0000000000..912bb76d9d
--- /dev/null
+++ b/ext/simplexml/tests/bug79971_1.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<root></root>
-- 
2.31.1

From 85cc53b8d23724e71545b501f817727721117e71 Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Mon, 15 Nov 2021 09:57:10 +0100
Subject: [PATCH 2/4] fix new tests

(cherry picked from commit b21524ff3db15da5a7779cba73e3774eb5404d40)
(cherry picked from commit 271e8b9203ba752de436cb090e3fe8f27c792de4)
---
 ext/dom/tests/bug79971_2.phpt       | 2 +-
 ext/simplexml/tests/bug79971_1.phpt | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/ext/dom/tests/bug79971_2.phpt b/ext/dom/tests/bug79971_2.phpt
index c4e6b1e4e0..01cd123541 100644
--- a/ext/dom/tests/bug79971_2.phpt
+++ b/ext/dom/tests/bug79971_2.phpt
@@ -7,7 +7,7 @@ if (!extension_loaded('dom')) die('skip dom extension not available');
 --FILE--
 <?php
 $imp = new DOMImplementation;
-if (PHP_OS_FAMILY === 'Windows') {
+if (DIRECTORY_SEPARATOR !== '/') {
     $path = '/' . str_replace('\\', '/', __DIR__);
 } else {
     $path = __DIR__;
diff --git a/ext/simplexml/tests/bug79971_1.phpt b/ext/simplexml/tests/bug79971_1.phpt
index 197776d82d..464112c99e 100644
--- a/ext/simplexml/tests/bug79971_1.phpt
+++ b/ext/simplexml/tests/bug79971_1.phpt
@@ -6,7 +6,7 @@ if (!extension_loaded('simplexml')) die('skip simplexml extension not available'
 ?>
 --FILE--
 <?php
-if (PHP_OS_FAMILY === 'Windows') {
+if (DIRECTORY_SEPARATOR !== '/') {
     $path = '/' . str_replace('\\', '/', __DIR__);
 } else {
     $path = __DIR__;
-- 
2.31.1

From 0a37872d5393c56ff60df108aabd003b9d9378f2 Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Mon, 15 Nov 2021 09:05:33 +0100
Subject: [PATCH 3/4] NEWS

(cherry picked from commit c032381da0bfb6457aa9cfa7a430790f6eab8178)
---
 NEWS | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index eece23f672..63ecbcc38e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,13 @@
 PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 
-Backported from 7.4.25
+Backported from 7.3.33
+
+- XML:
+  . Fix #79971: special character is breaking the path in xml function.
+    (CVE-2021-21707) (cmb)
+
+Backported from 7.3.32
 
 - FPM:
   . Fixed bug #81026 (PHP-FPM oob R/W in root process leading to privilege
-- 
2.31.1

From cfad01ddc65a32fbde3110a84c61d2ac55173a9c Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Mon, 15 Nov 2021 11:28:17 +0100
Subject: [PATCH 4/4] fix ZTS

---
 ext/libxml/libxml.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c
index d4a47ff702..02453ffb36 100644
--- a/ext/libxml/libxml.c
+++ b/ext/libxml/libxml.c
@@ -433,6 +433,8 @@ php_libxml_output_buffer_create_filename(const char *URI,
 	void *context = NULL;
 	char *unescaped = NULL;
 
+	TSRMLS_FETCH();
+
 	if (URI == NULL)
 		return(NULL);
 
-- 
2.31.1