Blame SOURCES/libxml2-Heap-use-after-free-in-htmlParsePubidLiteral-and-htmlParseSystemiteral.patch

6dedca
From 7012970b0d005f440e8326e37844a834f67a8c64 Mon Sep 17 00:00:00 2001
6dedca
From: Pranjal Jumde <pjumde@apple.com>
6dedca
Date: Wed, 2 Mar 2016 15:52:24 -0800
6dedca
Subject: [PATCH] Heap use-after-free in htmlParsePubidLiteral and
6dedca
 htmlParseSystemiteral
6dedca
To: libvir-list@redhat.com
6dedca
6dedca
For https://bugzilla.gnome.org/show_bug.cgi?id=760263
6dedca
6dedca
* HTMLparser.c: Add BASE_PTR convenience macro.
6dedca
(htmlParseSystemLiteral): Store length and start position instead
6dedca
of a pointer while iterating through the public identifier since
6dedca
the underlying buffer may change, resulting in a stale pointer
6dedca
being used.
6dedca
(htmlParsePubidLiteral): Ditto.
6dedca
6dedca
Signed-off-by: Daniel Veillard <veillard@redhat.com>
6dedca
---
6dedca
 HTMLparser.c | 58 +++++++++++++++++++++++++++++++++++++++++++---------------
6dedca
 1 file changed, 43 insertions(+), 15 deletions(-)
6dedca
6dedca
diff --git a/HTMLparser.c b/HTMLparser.c
6dedca
index a897cb0..e7d802d 100644
6dedca
--- a/HTMLparser.c
6dedca
+++ b/HTMLparser.c
6dedca
@@ -303,6 +303,7 @@ htmlNodeInfoPop(htmlParserCtxtPtr ctxt)
6dedca
 #define UPP(val) (toupper(ctxt->input->cur[(val)]))
6dedca
 
6dedca
 #define CUR_PTR ctxt->input->cur
6dedca
+#define BASE_PTR ctxt->input->base
6dedca
 
6dedca
 #define SHRINK if ((ctxt->input->cur - ctxt->input->base > 2 * INPUT_CHUNK) && \
6dedca
 		   (ctxt->input->end - ctxt->input->cur < 2 * INPUT_CHUNK)) \
6dedca
@@ -2773,31 +2774,43 @@ htmlParseAttValue(htmlParserCtxtPtr ctxt) {
6dedca
 
6dedca
 static xmlChar *
6dedca
 htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) {
6dedca
-    const xmlChar *q;
6dedca
+    size_t len = 0, startPosition = 0;
6dedca
     xmlChar *ret = NULL;
6dedca
 
6dedca
     if (CUR == '"') {
6dedca
         NEXT;
6dedca
-	q = CUR_PTR;
6dedca
-	while ((IS_CHAR_CH(CUR)) && (CUR != '"'))
6dedca
+
6dedca
+        if (CUR_PTR < BASE_PTR)
6dedca
+            return(ret);
6dedca
+        startPosition = CUR_PTR - BASE_PTR;
6dedca
+
6dedca
+	while ((IS_CHAR_CH(CUR)) && (CUR != '"')) {
6dedca
 	    NEXT;
6dedca
+	    len++;
6dedca
+	}
6dedca
 	if (!IS_CHAR_CH(CUR)) {
6dedca
 	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
6dedca
 			 "Unfinished SystemLiteral\n", NULL, NULL);
6dedca
 	} else {
6dedca
-	    ret = xmlStrndup(q, CUR_PTR - q);
6dedca
+	    ret = xmlStrndup((BASE_PTR+startPosition), len);
6dedca
 	    NEXT;
6dedca
         }
6dedca
     } else if (CUR == '\'') {
6dedca
         NEXT;
6dedca
-	q = CUR_PTR;
6dedca
-	while ((IS_CHAR_CH(CUR)) && (CUR != '\''))
6dedca
+
6dedca
+        if (CUR_PTR < BASE_PTR)
6dedca
+            return(ret);
6dedca
+        startPosition = CUR_PTR - BASE_PTR;
6dedca
+
6dedca
+	while ((IS_CHAR_CH(CUR)) && (CUR != '\'')) {
6dedca
 	    NEXT;
6dedca
+	    len++;
6dedca
+	}
6dedca
 	if (!IS_CHAR_CH(CUR)) {
6dedca
 	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
6dedca
 			 "Unfinished SystemLiteral\n", NULL, NULL);
6dedca
 	} else {
6dedca
-	    ret = xmlStrndup(q, CUR_PTR - q);
6dedca
+	    ret = xmlStrndup((BASE_PTR+startPosition), len);
6dedca
 	    NEXT;
6dedca
         }
6dedca
     } else {
6dedca
@@ -2821,32 +2834,47 @@ htmlParseSystemLiteral(htmlParserCtxtPtr ctxt) {
6dedca
 
6dedca
 static xmlChar *
6dedca
 htmlParsePubidLiteral(htmlParserCtxtPtr ctxt) {
6dedca
-    const xmlChar *q;
6dedca
+    size_t len = 0, startPosition = 0;
6dedca
     xmlChar *ret = NULL;
6dedca
     /*
6dedca
      * Name ::= (Letter | '_') (NameChar)*
6dedca
      */
6dedca
     if (CUR == '"') {
6dedca
         NEXT;
6dedca
-	q = CUR_PTR;
6dedca
-	while (IS_PUBIDCHAR_CH(CUR)) NEXT;
6dedca
+
6dedca
+        if (CUR_PTR < BASE_PTR)
6dedca
+            return(ret);
6dedca
+        startPosition = CUR_PTR - BASE_PTR;
6dedca
+
6dedca
+        while (IS_PUBIDCHAR_CH(CUR)) {
6dedca
+            len++;
6dedca
+            NEXT;
6dedca
+        }
6dedca
+
6dedca
 	if (CUR != '"') {
6dedca
 	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
6dedca
 	                 "Unfinished PubidLiteral\n", NULL, NULL);
6dedca
 	} else {
6dedca
-	    ret = xmlStrndup(q, CUR_PTR - q);
6dedca
+	    ret = xmlStrndup((BASE_PTR + startPosition), len);
6dedca
 	    NEXT;
6dedca
 	}
6dedca
     } else if (CUR == '\'') {
6dedca
         NEXT;
6dedca
-	q = CUR_PTR;
6dedca
-	while ((IS_PUBIDCHAR_CH(CUR)) && (CUR != '\''))
6dedca
-	    NEXT;
6dedca
+
6dedca
+        if (CUR_PTR < BASE_PTR)
6dedca
+            return(ret);
6dedca
+        startPosition = CUR_PTR - BASE_PTR;
6dedca
+
6dedca
+        while ((IS_PUBIDCHAR_CH(CUR)) && (CUR != '\'')){
6dedca
+            len++;
6dedca
+            NEXT;
6dedca
+        }
6dedca
+
6dedca
 	if (CUR != '\'') {
6dedca
 	    htmlParseErr(ctxt, XML_ERR_LITERAL_NOT_FINISHED,
6dedca
 	                 "Unfinished PubidLiteral\n", NULL, NULL);
6dedca
 	} else {
6dedca
-	    ret = xmlStrndup(q, CUR_PTR - q);
6dedca
+	    ret = xmlStrndup((BASE_PTR + startPosition), len);
6dedca
 	    NEXT;
6dedca
 	}
6dedca
     } else {
6dedca
-- 
6dedca
2.5.5
6dedca