summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrej Valek <andrej.valek@siemens.com>2017-06-14 14:58:47 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2017-06-23 11:44:13 +0100
commit371ba8c74332b6ab2d9062edadc93c688751e4ab (patch)
treea4cac38d29cf01a6c85890f05a7984e7a35a5f81
parent1a4f1ccdcc51b7d97ab66214675357b6c2c075f8 (diff)
downloadpoky-371ba8c74332b6ab2d9062edadc93c688751e4ab.tar.gz
libxml2: Fix CVE-2017-9049 and CVE-2017-9050
Fix handling of parameter-entity references There were two bugs where parameter-entity references could lead to an unexpected change of the input buffer in xmlParseNameComplex and xmlDictLookup being called with an invalid pointer. Fixes bug 781205 and bug 781361 CVE: CVE-2017-9049 CVE-2017-9050 (From OE-Core rev: 2300762fef8fc8e3e56fb07fd4076c1deeba0a9b) Signed-off-by: Andrej Valek <andrej.valek@siemens.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-core/libxml/libxml2/libxml2-CVE-2017-9049_CVE-2017-9050.patch291
-rw-r--r--meta/recipes-core/libxml/libxml2_2.9.4.bb1
2 files changed, 292 insertions, 0 deletions
diff --git a/meta/recipes-core/libxml/libxml2/libxml2-CVE-2017-9049_CVE-2017-9050.patch b/meta/recipes-core/libxml/libxml2/libxml2-CVE-2017-9049_CVE-2017-9050.patch
new file mode 100644
index 0000000000..591075de3c
--- /dev/null
+++ b/meta/recipes-core/libxml/libxml2/libxml2-CVE-2017-9049_CVE-2017-9050.patch
@@ -0,0 +1,291 @@
1libxml2-2.9.4: Fix CVE-2017-9049 and CVE-2017-9050
2
3[No upstream tracking] -- https://bugzilla.gnome.org/show_bug.cgi?id=781205
4 -- https://bugzilla.gnome.org/show_bug.cgi?id=781361
5
6parser: Fix handling of parameter-entity references
7
8There were two bugs where parameter-entity references could lead to an
9unexpected change of the input buffer in xmlParseNameComplex and
10xmlDictLookup being called with an invalid pointer.
11
12Percent sign in DTD Names
13=========================
14
15The NEXTL macro used to call xmlParserHandlePEReference. When parsing
16"complex" names inside the DTD, this could result in entity expansion
17which created a new input buffer. The fix is to simply remove the call
18to xmlParserHandlePEReference from the NEXTL macro. This is safe because
19no users of the macro require expansion of parameter entities.
20
21- xmlParseNameComplex
22- xmlParseNCNameComplex
23- xmlParseNmtoken
24
25The percent sign is not allowed in names, which are grammatical tokens.
26
27- xmlParseEntityValue
28
29Parameter-entity references in entity values are expanded but this
30happens in a separate step in this function.
31
32- xmlParseSystemLiteral
33
34Parameter-entity references are ignored in the system literal.
35
36- xmlParseAttValueComplex
37- xmlParseCharDataComplex
38- xmlParseCommentComplex
39- xmlParsePI
40- xmlParseCDSect
41
42Parameter-entity references are ignored outside the DTD.
43
44- xmlLoadEntityContent
45
46This function is only called from xmlStringLenDecodeEntities and
47entities are replaced in a separate step immediately after the function
48call.
49
50This bug could also be triggered with an internal subset and double
51entity expansion.
52
53This fixes bug 766956 initially reported by Wei Lei and independently by
54Chromium's ClusterFuzz, Hanno Böck, and Marco Grassi. Thanks to everyone
55involved.
56
57xmlParseNameComplex with XML_PARSE_OLD10
58========================================
59
60When parsing Names inside an expanded parameter entity with the
61XML_PARSE_OLD10 option, xmlParseNameComplex would call xmlGROW via the
62GROW macro if the input buffer was exhausted. At the end of the
63parameter entity's replacement text, this function would then call
64xmlPopInput which invalidated the input buffer.
65
66There should be no need to invoke GROW in this situation because the
67buffer is grown periodically every XML_PARSER_CHUNK_SIZE characters and,
68at least for UTF-8, in xmlCurrentChar. This also matches the code path
69executed when XML_PARSE_OLD10 is not set.
70
71This fixes bugs 781205 (CVE-2017-9049) and 781361 (CVE-2017-9050).
72Thanks to Marcel Böhme and Thuan Pham for the report.
73
74Additional hardening
75====================
76
77A separate check was added in xmlParseNameComplex to validate the
78buffer size.
79
80Fixes bug 781205 and bug 781361
81
82Upstream-Status: Backport [https://git.gnome.org/browse/libxml2/commit/?id=932cc9896ab41475d4aa429c27d9afd175959d74]
83CVE: CVE-2017-9049 CVE-2017-9050
84Signed-off-by: Andrej Valek <andrej.valek@siemens.com>
85
86diff --git a/Makefile.am b/Makefile.am
87index 9f988b0..dab15a4 100644
88--- a/Makefile.am
89+++ b/Makefile.am
90@@ -422,6 +422,24 @@ Errtests : xmllint$(EXEEXT)
91 if [ -n "$$log" ] ; then echo $$name result ; echo $$log ; fi ; \
92 rm result.$$name error.$$name ; \
93 fi ; fi ; done)
94+ @echo "## Error cases regression tests (old 1.0)"
95+ -@(for i in $(srcdir)/test/errors10/*.xml ; do \
96+ name=`basename $$i`; \
97+ if [ ! -d $$i ] ; then \
98+ if [ ! -f $(srcdir)/result/errors10/$$name ] ; then \
99+ echo New test file $$name ; \
100+ $(CHECKER) $(top_builddir)/xmllint --oldxml10 $$i \
101+ 2> $(srcdir)/result/errors10/$$name.err \
102+ > $(srcdir)/result/errors10/$$name ; \
103+ grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0"; \
104+ else \
105+ log=`$(CHECKER) $(top_builddir)/xmllint --oldxml10 $$i 2> error.$$name > result.$$name ; \
106+ grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0"; \
107+ diff $(srcdir)/result/errors10/$$name result.$$name ; \
108+ diff $(srcdir)/result/errors10/$$name.err error.$$name` ; \
109+ if [ -n "$$log" ] ; then echo $$name result ; echo "$$log" ; fi ; \
110+ rm result.$$name error.$$name ; \
111+ fi ; fi ; done)
112 @echo "## Error cases stream regression tests"
113 -@(for i in $(srcdir)/test/errors/*.xml ; do \
114 name=`basename $$i`; \
115diff --git a/parser.c b/parser.c
116index 609a270..8e11c12 100644
117--- a/parser.c
118+++ b/parser.c
119@@ -2115,7 +2115,6 @@ static void xmlGROW (xmlParserCtxtPtr ctxt) {
120 ctxt->input->line++; ctxt->input->col = 1; \
121 } else ctxt->input->col++; \
122 ctxt->input->cur += l; \
123- if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt); \
124 } while (0)
125
126 #define CUR_CHAR(l) xmlCurrentChar(ctxt, &l)
127@@ -3406,13 +3405,6 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
128 len += l;
129 NEXTL(l);
130 c = CUR_CHAR(l);
131- if (c == 0) {
132- count = 0;
133- GROW;
134- if (ctxt->instate == XML_PARSER_EOF)
135- return(NULL);
136- c = CUR_CHAR(l);
137- }
138 }
139 }
140 if ((len > XML_MAX_NAME_LENGTH) &&
141@@ -3420,6 +3412,16 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
142 xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
143 return(NULL);
144 }
145+ if (ctxt->input->cur - ctxt->input->base < len) {
146+ /*
147+ * There were a couple of bugs where PERefs lead to to a change
148+ * of the buffer. Check the buffer size to avoid passing an invalid
149+ * pointer to xmlDictLookup.
150+ */
151+ xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
152+ "unexpected change of input buffer");
153+ return (NULL);
154+ }
155 if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
156 return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
157 return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
158diff --git a/result/errors10/781205.xml b/result/errors10/781205.xml
159new file mode 100644
160index 0000000..e69de29
161diff --git a/result/errors10/781205.xml.err b/result/errors10/781205.xml.err
162new file mode 100644
163index 0000000..da15c3f
164--- /dev/null
165+++ b/result/errors10/781205.xml.err
166@@ -0,0 +1,21 @@
167+Entity: line 1: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
168+
169+ %a;
170+ ^
171+Entity: line 1:
172+<:0000
173+^
174+Entity: line 1: parser error : DOCTYPE improperly terminated
175+ %a;
176+ ^
177+Entity: line 1:
178+<:0000
179+^
180+namespace error : Failed to parse QName ':0000'
181+ %a;
182+ ^
183+<:0000
184+ ^
185+./test/errors10/781205.xml:4: parser error : Couldn't find end of Start Tag :0000 line 1
186+
187+^
188diff --git a/result/errors10/781361.xml b/result/errors10/781361.xml
189new file mode 100644
190index 0000000..e69de29
191diff --git a/result/errors10/781361.xml.err b/result/errors10/781361.xml.err
192new file mode 100644
193index 0000000..655f41a
194--- /dev/null
195+++ b/result/errors10/781361.xml.err
196@@ -0,0 +1,13 @@
197+./test/errors10/781361.xml:4: parser error : xmlParseElementDecl: 'EMPTY', 'ANY' or '(' expected
198+
199+^
200+./test/errors10/781361.xml:4: parser error : internal error: xmlParseInternalSubset: error detected in Markup declaration
201+
202+
203+^
204+./test/errors10/781361.xml:4: parser error : DOCTYPE improperly terminated
205+
206+^
207+./test/errors10/781361.xml:4: parser error : Start tag expected, '<' not found
208+
209+^
210diff --git a/result/valid/766956.xml b/result/valid/766956.xml
211new file mode 100644
212index 0000000..e69de29
213diff --git a/result/valid/766956.xml.err b/result/valid/766956.xml.err
214new file mode 100644
215index 0000000..34b1dae
216--- /dev/null
217+++ b/result/valid/766956.xml.err
218@@ -0,0 +1,9 @@
219+test/valid/dtds/766956.dtd:2: parser error : PEReference: expecting ';'
220+%ä%ent;
221+ ^
222+Entity: line 1: parser error : Content error in the external subset
223+ %ent;
224+ ^
225+Entity: line 1:
226+value
227+^
228diff --git a/result/valid/766956.xml.err.rdr b/result/valid/766956.xml.err.rdr
229new file mode 100644
230index 0000000..7760346
231--- /dev/null
232+++ b/result/valid/766956.xml.err.rdr
233@@ -0,0 +1,10 @@
234+test/valid/dtds/766956.dtd:2: parser error : PEReference: expecting ';'
235+%ä%ent;
236+ ^
237+Entity: line 1: parser error : Content error in the external subset
238+ %ent;
239+ ^
240+Entity: line 1:
241+value
242+^
243+./test/valid/766956.xml : failed to parse
244diff --git a/runtest.c b/runtest.c
245index bb74d2a..63e8c20 100644
246--- a/runtest.c
247+++ b/runtest.c
248@@ -4202,6 +4202,9 @@ testDesc testDescriptions[] = {
249 { "Error cases regression tests",
250 errParseTest, "./test/errors/*.xml", "result/errors/", "", ".err",
251 0 },
252+ { "Error cases regression tests (old 1.0)",
253+ errParseTest, "./test/errors10/*.xml", "result/errors10/", "", ".err",
254+ XML_PARSE_OLD10 },
255 #ifdef LIBXML_READER_ENABLED
256 { "Error cases stream regression tests",
257 streamParseTest, "./test/errors/*.xml", "result/errors/", NULL, ".str",
258diff --git a/test/errors10/781205.xml b/test/errors10/781205.xml
259new file mode 100644
260index 0000000..d9e9e83
261--- /dev/null
262+++ b/test/errors10/781205.xml
263@@ -0,0 +1,3 @@
264+<!DOCTYPE D [
265+ <!ENTITY % a "<:0000">
266+ %a;
267diff --git a/test/errors10/781361.xml b/test/errors10/781361.xml
268new file mode 100644
269index 0000000..67476bc
270--- /dev/null
271+++ b/test/errors10/781361.xml
272@@ -0,0 +1,3 @@
273+<!DOCTYPE doc [
274+ <!ENTITY % elem "<!ELEMENT e0000000000">
275+ %elem;
276diff --git a/test/valid/766956.xml b/test/valid/766956.xml
277new file mode 100644
278index 0000000..19a95a0
279--- /dev/null
280+++ b/test/valid/766956.xml
281@@ -0,0 +1,2 @@
282+<!DOCTYPE test SYSTEM "dtds/766956.dtd">
283+<test/>
284diff --git a/test/valid/dtds/766956.dtd b/test/valid/dtds/766956.dtd
285new file mode 100644
286index 0000000..dddde68
287--- /dev/null
288+++ b/test/valid/dtds/766956.dtd
289@@ -0,0 +1,2 @@
290+<!ENTITY % ent "value">
291+%ä%ent;
diff --git a/meta/recipes-core/libxml/libxml2_2.9.4.bb b/meta/recipes-core/libxml/libxml2_2.9.4.bb
index dd2e034e2a..3f78c2de63 100644
--- a/meta/recipes-core/libxml/libxml2_2.9.4.bb
+++ b/meta/recipes-core/libxml/libxml2_2.9.4.bb
@@ -25,6 +25,7 @@ SRC_URI = "ftp://xmlsoft.org/libxml2/libxml2-${PV}.tar.gz;name=libtar \
25 file://libxml2-fix_NULL_pointer_derefs.patch \ 25 file://libxml2-fix_NULL_pointer_derefs.patch \
26 file://libxml2-fix_and_simplify_xmlParseStartTag2.patch \ 26 file://libxml2-fix_and_simplify_xmlParseStartTag2.patch \
27 file://libxml2-CVE-2017-9047_CVE-2017-9048.patch \ 27 file://libxml2-CVE-2017-9047_CVE-2017-9048.patch \
28 file://libxml2-CVE-2017-9049_CVE-2017-9050.patch \
28 file://CVE-2016-9318.patch \ 29 file://CVE-2016-9318.patch \
29 file://0001-Make-ptest-run-the-python-tests-if-python-is-enabled.patch \ 30 file://0001-Make-ptest-run-the-python-tests-if-python-is-enabled.patch \
30 " 31 "