xzyang / rpms / libxml2

Forked from rpms/libxml2 3 years ago
Clone

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

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