153aa9179Sopenharmony_ciFrom c50196c13d348025a4843305902bb37df64bae36 Mon Sep 17 00:00:00 2001
253aa9179Sopenharmony_ciFrom: David Kilzer <ddkilzer@apple.com>
353aa9179Sopenharmony_ciDate: Sun, 10 Apr 2022 20:02:47 -0700
453aa9179Sopenharmony_ciSubject: [PATCH 289/300] Fix use-after-free bugs when calling
553aa9179Sopenharmony_ci xmlTextReaderClose() before xmlFreeTextReader() on post-validating parser
653aa9179Sopenharmony_ci
753aa9179Sopenharmony_ciWhen creating an xmlTextReaderPtr using xmlReaderForMemory(),
853aa9179Sopenharmony_cithere are two optional API functions that can be used:
953aa9179Sopenharmony_ci- xmlTextReaderClose() may be called prior to calling
1053aa9179Sopenharmony_ci  xmlFreeTextReader() to free parsing resources and close the
1153aa9179Sopenharmony_ci  xmlTextReaderPtr without freeing it.
1253aa9179Sopenharmony_ci- xmlTextReaderCurrentDoc() may be called to return an
1353aa9179Sopenharmony_ci  xmlDocPtr that's owned by the caller, and must be free using
1453aa9179Sopenharmony_ci  xmlFreeDoc() after calling xmlFreeTextReader().
1553aa9179Sopenharmony_ci
1653aa9179Sopenharmony_ciThe use-after-free issues occur when calling
1753aa9179Sopenharmony_cixmlTextReaderClose() before xmlFreeTextReader(), with different
1853aa9179Sopenharmony_ciissues occurring depending on whether xmlTextReaderCurrentDoc()
1953aa9179Sopenharmony_ciis also called.
2053aa9179Sopenharmony_ci
2153aa9179Sopenharmony_ci* xmlreader.c:
2253aa9179Sopenharmony_ci(xmlFreeTextReader):
2353aa9179Sopenharmony_ci- Move code to xmlTextReaderClose(), remove duplicate code, and
2453aa9179Sopenharmony_ci  call xmlTextReaderClose() if it hasn't been called yet.
2553aa9179Sopenharmony_ci(xmlTextReaderClose):
2653aa9179Sopenharmony_ci- Move call to xmlFreeNode(reader->faketext) from
2753aa9179Sopenharmony_ci  xmlFreeTextReader() to fix a use-after-free bug when calling
2853aa9179Sopenharmony_ci  xmlTextReaderClose() before xmlFreeTextReader(), but not when
2953aa9179Sopenharmony_ci  using xmlTextReaderCurrentDoc().  The bug was introduced in
3053aa9179Sopenharmony_ci  2002 by commit beb70bd39.  In 2009 commit f4653dcd8 fixed the
3153aa9179Sopenharmony_ci  use-after-free that occurred every time xmlFreeTextReader()
3253aa9179Sopenharmony_ci  was called, but not the case where xmlTextReaderClose() was
3353aa9179Sopenharmony_ci  called first.
3453aa9179Sopenharmony_ci- Move post-parsing validation code from xmlFreeTextReader() to
3553aa9179Sopenharmony_ci  fix a second use-after-free when calling xmlTextReaderClose()
3653aa9179Sopenharmony_ci  before xmlFreeTextReader().  This regressed in v2.9.10 with
3753aa9179Sopenharmony_ci  commit 57a3af56f.
3853aa9179Sopenharmony_ci
3953aa9179Sopenharmony_ciReference:https://github.com/GNOME/libxml2/commit/c50196c13d348025a4843305902bb37df64bae36
4053aa9179Sopenharmony_ciConflict:NA
4153aa9179Sopenharmony_ci
4253aa9179Sopenharmony_ci---
4353aa9179Sopenharmony_ci xmlreader.c | 40 ++++++++++++++++++----------------------
4453aa9179Sopenharmony_ci 1 file changed, 18 insertions(+), 22 deletions(-)
4553aa9179Sopenharmony_ci
4653aa9179Sopenharmony_cidiff --git a/xmlreader.c b/xmlreader.c
4753aa9179Sopenharmony_ciindex 72e40b0..989b7c1 100644
4853aa9179Sopenharmony_ci--- a/xmlreader.c
4953aa9179Sopenharmony_ci+++ b/xmlreader.c
5053aa9179Sopenharmony_ci@@ -2319,36 +2319,16 @@ xmlFreeTextReader(xmlTextReaderPtr reader) {
5153aa9179Sopenharmony_ci 	xmlFree(reader->patternTab);
5253aa9179Sopenharmony_ci     }
5353aa9179Sopenharmony_ci #endif
5453aa9179Sopenharmony_ci-    if (reader->faketext != NULL) {
5553aa9179Sopenharmony_ci-	xmlFreeNode(reader->faketext);
5653aa9179Sopenharmony_ci-    }
5753aa9179Sopenharmony_ci+    if (reader->mode != XML_TEXTREADER_MODE_CLOSED)
5853aa9179Sopenharmony_ci+        xmlTextReaderClose(reader);
5953aa9179Sopenharmony_ci     if (reader->ctxt != NULL) {
6053aa9179Sopenharmony_ci         if (reader->dict == reader->ctxt->dict)
6153aa9179Sopenharmony_ci 	    reader->dict = NULL;
6253aa9179Sopenharmony_ci-#ifdef LIBXML_VALID_ENABLED
6353aa9179Sopenharmony_ci-	if ((reader->ctxt->vctxt.vstateTab != NULL) &&
6453aa9179Sopenharmony_ci-	    (reader->ctxt->vctxt.vstateMax > 0)){
6553aa9179Sopenharmony_ci-#ifdef LIBXML_REGEXP_ENABLED
6653aa9179Sopenharmony_ci-            while (reader->ctxt->vctxt.vstateNr > 0)
6753aa9179Sopenharmony_ci-                xmlValidatePopElement(&reader->ctxt->vctxt, NULL, NULL, NULL);
6853aa9179Sopenharmony_ci-#endif /* LIBXML_REGEXP_ENABLED */
6953aa9179Sopenharmony_ci-	    xmlFree(reader->ctxt->vctxt.vstateTab);
7053aa9179Sopenharmony_ci-	    reader->ctxt->vctxt.vstateTab = NULL;
7153aa9179Sopenharmony_ci-	    reader->ctxt->vctxt.vstateMax = 0;
7253aa9179Sopenharmony_ci-	}
7353aa9179Sopenharmony_ci-#endif /* LIBXML_VALID_ENABLED */
7453aa9179Sopenharmony_ci-	if (reader->ctxt->myDoc != NULL) {
7553aa9179Sopenharmony_ci-	    if (reader->preserve == 0)
7653aa9179Sopenharmony_ci-		xmlTextReaderFreeDoc(reader, reader->ctxt->myDoc);
7753aa9179Sopenharmony_ci-	    reader->ctxt->myDoc = NULL;
7853aa9179Sopenharmony_ci-	}
7953aa9179Sopenharmony_ci 	if (reader->allocs & XML_TEXTREADER_CTXT)
8053aa9179Sopenharmony_ci 	    xmlFreeParserCtxt(reader->ctxt);
8153aa9179Sopenharmony_ci     }
8253aa9179Sopenharmony_ci     if (reader->sax != NULL)
8353aa9179Sopenharmony_ci 	xmlFree(reader->sax);
8453aa9179Sopenharmony_ci-    if ((reader->input != NULL)  && (reader->allocs & XML_TEXTREADER_INPUT))
8553aa9179Sopenharmony_ci-	xmlFreeParserInputBuffer(reader->input);
8653aa9179Sopenharmony_ci     if (reader->buffer != NULL)
8753aa9179Sopenharmony_ci         xmlBufFree(reader->buffer);
8853aa9179Sopenharmony_ci     if (reader->entTab != NULL)
8953aa9179Sopenharmony_ci@@ -2379,7 +2359,23 @@ xmlTextReaderClose(xmlTextReaderPtr reader) {
9053aa9179Sopenharmony_ci     reader->node = NULL;
9153aa9179Sopenharmony_ci     reader->curnode = NULL;
9253aa9179Sopenharmony_ci     reader->mode = XML_TEXTREADER_MODE_CLOSED;
9353aa9179Sopenharmony_ci+    if (reader->faketext != NULL) {
9453aa9179Sopenharmony_ci+        xmlFreeNode(reader->faketext);
9553aa9179Sopenharmony_ci+        reader->faketext = NULL;
9653aa9179Sopenharmony_ci+    }
9753aa9179Sopenharmony_ci     if (reader->ctxt != NULL) {
9853aa9179Sopenharmony_ci+#ifdef LIBXML_VALID_ENABLED
9953aa9179Sopenharmony_ci+	if ((reader->ctxt->vctxt.vstateTab != NULL) &&
10053aa9179Sopenharmony_ci+	    (reader->ctxt->vctxt.vstateMax > 0)){
10153aa9179Sopenharmony_ci+#ifdef LIBXML_REGEXP_ENABLED
10253aa9179Sopenharmony_ci+            while (reader->ctxt->vctxt.vstateNr > 0)
10353aa9179Sopenharmony_ci+                xmlValidatePopElement(&reader->ctxt->vctxt, NULL, NULL, NULL);
10453aa9179Sopenharmony_ci+#endif /* LIBXML_REGEXP_ENABLED */
10553aa9179Sopenharmony_ci+	    xmlFree(reader->ctxt->vctxt.vstateTab);
10653aa9179Sopenharmony_ci+	    reader->ctxt->vctxt.vstateTab = NULL;
10753aa9179Sopenharmony_ci+	    reader->ctxt->vctxt.vstateMax = 0;
10853aa9179Sopenharmony_ci+	}
10953aa9179Sopenharmony_ci+#endif /* LIBXML_VALID_ENABLED */
11053aa9179Sopenharmony_ci 	xmlStopParser(reader->ctxt);
11153aa9179Sopenharmony_ci 	if (reader->ctxt->myDoc != NULL) {
11253aa9179Sopenharmony_ci 	    if (reader->preserve == 0)
11353aa9179Sopenharmony_ci-- 
11453aa9179Sopenharmony_ci2.27.0
11553aa9179Sopenharmony_ci
116