summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/libxml/libxml2/CVE-2022-23308.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/libxml/libxml2/CVE-2022-23308.patch')
-rw-r--r--meta/recipes-core/libxml/libxml2/CVE-2022-23308.patch204
1 files changed, 204 insertions, 0 deletions
diff --git a/meta/recipes-core/libxml/libxml2/CVE-2022-23308.patch b/meta/recipes-core/libxml/libxml2/CVE-2022-23308.patch
new file mode 100644
index 0000000000..bf5604e81a
--- /dev/null
+++ b/meta/recipes-core/libxml/libxml2/CVE-2022-23308.patch
@@ -0,0 +1,204 @@
1From 8b66850de350f0fcd786ae776a65ba15a5999e50 Mon Sep 17 00:00:00 2001
2From: Nick Wellnhofer <wellnhofer@aevum.de>
3Date: Tue, 8 Feb 2022 03:29:24 +0100
4Subject: [PATCH] Use-after-free of ID and IDREF attributes
5
6If a document is parsed with XML_PARSE_DTDVALID and without
7XML_PARSE_NOENT, the value of ID attributes has to be normalized after
8potentially expanding entities in xmlRemoveID. Otherwise, later calls
9to xmlGetID can return a pointer to previously freed memory.
10
11ID attributes which are empty or contain only whitespace after
12entity expansion are affected in a similar way. This is fixed by
13not storing such attributes in the ID table.
14
15The test to detect streaming mode when validating against a DTD was
16broken. In connection with the defects above, this could result in a
17use-after-free when using the xmlReader interface with validation.
18Fix detection of streaming mode to avoid similar issues. (This changes
19the expected result of a test case. But as far as I can tell, using the
20XML reader with XIncludes referencing the root document never worked
21properly, anyway.)
22
23All of these issues can result in denial of service. Using xmlReader
24with validation could result in disclosure of memory via the error
25channel, typically stderr. The security impact of xmlGetID returning
26a pointer to freed memory depends on the application. The typical use
27case of calling xmlGetID on an unmodified document is not affected.
28
29Upstream-Status: Backport
30[https://gitlab.gnome.org/GNOME/libxml2/-/commit/652dd12a858989b14eed4e84e453059cd3ba340e]
31
32The upstream patch 652dd12a858989b14eed4e84e453059cd3ba340e has been modified
33to skip the patch to the testsuite result (result/XInclude/ns1.xml.rdr), as
34this particular test does not exist in v2.9.10 (it was added later).
35
36CVE: CVE-2022-23308
37Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org>
38
39---
40 valid.c | 88 +++++++++++++++++++++++++++++++++++----------------------
41 1 file changed, 55 insertions(+), 33 deletions(-)
42
43diff --git a/valid.c b/valid.c
44index 07963e7..ee75311 100644
45--- a/valid.c
46+++ b/valid.c
47@@ -479,6 +479,35 @@ nodeVPop(xmlValidCtxtPtr ctxt)
48 return (ret);
49 }
50
51+/**
52+ * xmlValidNormalizeString:
53+ * @str: a string
54+ *
55+ * Normalize a string in-place.
56+ */
57+static void
58+xmlValidNormalizeString(xmlChar *str) {
59+ xmlChar *dst;
60+ const xmlChar *src;
61+
62+ if (str == NULL)
63+ return;
64+ src = str;
65+ dst = str;
66+
67+ while (*src == 0x20) src++;
68+ while (*src != 0) {
69+ if (*src == 0x20) {
70+ while (*src == 0x20) src++;
71+ if (*src != 0)
72+ *dst++ = 0x20;
73+ } else {
74+ *dst++ = *src++;
75+ }
76+ }
77+ *dst = 0;
78+}
79+
80 #ifdef DEBUG_VALID_ALGO
81 static void
82 xmlValidPrintNode(xmlNodePtr cur) {
83@@ -2607,6 +2636,24 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
84 (xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
85 xmlFree((char *)(str));
86
87+static int
88+xmlIsStreaming(xmlValidCtxtPtr ctxt) {
89+ xmlParserCtxtPtr pctxt;
90+
91+ if (ctxt == NULL)
92+ return(0);
93+ /*
94+ * These magic values are also abused to detect whether we're validating
95+ * while parsing a document. In this case, userData points to the parser
96+ * context.
97+ */
98+ if ((ctxt->finishDtd != XML_CTXT_FINISH_DTD_0) &&
99+ (ctxt->finishDtd != XML_CTXT_FINISH_DTD_1))
100+ return(0);
101+ pctxt = ctxt->userData;
102+ return(pctxt->parseMode == XML_PARSE_READER);
103+}
104+
105 /**
106 * xmlFreeID:
107 * @not: A id
108@@ -2650,7 +2697,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
109 if (doc == NULL) {
110 return(NULL);
111 }
112- if (value == NULL) {
113+ if ((value == NULL) || (value[0] == 0)) {
114 return(NULL);
115 }
116 if (attr == NULL) {
117@@ -2681,7 +2728,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
118 */
119 ret->value = xmlStrdup(value);
120 ret->doc = doc;
121- if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
122+ if (xmlIsStreaming(ctxt)) {
123 /*
124 * Operating in streaming mode, attr is gonna disappear
125 */
126@@ -2820,6 +2867,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
127 ID = xmlNodeListGetString(doc, attr->children, 1);
128 if (ID == NULL)
129 return(-1);
130+ xmlValidNormalizeString(ID);
131
132 id = xmlHashLookup(table, ID);
133 if (id == NULL || id->attr != attr) {
134@@ -3009,7 +3057,7 @@ xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
135 * fill the structure.
136 */
137 ret->value = xmlStrdup(value);
138- if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
139+ if (xmlIsStreaming(ctxt)) {
140 /*
141 * Operating in streaming mode, attr is gonna disappear
142 */
143@@ -4028,8 +4076,7 @@ xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
144 xmlChar *
145 xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
146 xmlNodePtr elem, const xmlChar *name, const xmlChar *value) {
147- xmlChar *ret, *dst;
148- const xmlChar *src;
149+ xmlChar *ret;
150 xmlAttributePtr attrDecl = NULL;
151 int extsubset = 0;
152
153@@ -4070,19 +4117,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
154 ret = xmlStrdup(value);
155 if (ret == NULL)
156 return(NULL);
157- src = value;
158- dst = ret;
159- while (*src == 0x20) src++;
160- while (*src != 0) {
161- if (*src == 0x20) {
162- while (*src == 0x20) src++;
163- if (*src != 0)
164- *dst++ = 0x20;
165- } else {
166- *dst++ = *src++;
167- }
168- }
169- *dst = 0;
170+ xmlValidNormalizeString(ret);
171 if ((doc->standalone) && (extsubset == 1) && (!xmlStrEqual(value, ret))) {
172 xmlErrValidNode(ctxt, elem, XML_DTD_NOT_STANDALONE,
173 "standalone: %s on %s value had to be normalized based on external subset declaration\n",
174@@ -4114,8 +4149,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
175 xmlChar *
176 xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
177 const xmlChar *name, const xmlChar *value) {
178- xmlChar *ret, *dst;
179- const xmlChar *src;
180+ xmlChar *ret;
181 xmlAttributePtr attrDecl = NULL;
182
183 if (doc == NULL) return(NULL);
184@@ -4145,19 +4179,7 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
185 ret = xmlStrdup(value);
186 if (ret == NULL)
187 return(NULL);
188- src = value;
189- dst = ret;
190- while (*src == 0x20) src++;
191- while (*src != 0) {
192- if (*src == 0x20) {
193- while (*src == 0x20) src++;
194- if (*src != 0)
195- *dst++ = 0x20;
196- } else {
197- *dst++ = *src++;
198- }
199- }
200- *dst = 0;
201+ xmlValidNormalizeString(ret);
202 return(ret);
203 }
204