[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [xml] Security flaw affecting all previous libxml2 releases



On Thu, Jan 17, 2008 at 10:34:19AM -0800, Fred Smith wrote:
> Trying to manually apply this patch to 2.4.25. I find that some parts of
> it match up well and others don't.
> 
> There are three places in the file where similar code can be found. I'm
> guessing that the one we're concerned with here is the one beginning
> around line 1282, as that's the block where the "1-byte code" most
> closely resembles the bottom part of this patch.
> 
> But I don't see a close match for the first change in the patch in any
> of those areas. Specifically, there is no line reading "if (c == 0xC0)".
> The place that most looks like the right place is:
> 
> 	c = *cur;
> 	if (c & 0x80) {        <====================
> 	    if (cur[1] == 0)
> 		xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
> 	    if ((cur[1] & 0xc0) != 0x80)
> 		goto encoding_error;
> 	    if ((c & 0xe0) == 0xe0) {
> 
> 		if (cur[2] == 0)
> 		    xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
> 
> see the line marked with arrow, it looks as if the patch wants to insert
> a couple of lines right below there??
> 
> I'd be grateful if Daniel (or anyone else who has patched an ancient
> version) could advise me on the correct changes to make here.

  Sure, i made the patches which were needed for RHEL 2.1/3/4 security fixes,
they went out as part of the source RPM updates for RHEL, attached !

Daniel

-- 
Red Hat Virtualization group http://redhat.com/virtualization/
Daniel Veillard      | virtualization library  http://libvirt.org/
veillard redhat com  | libxml GNOME XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine  http://rpmfind.net/
*** parserInternals.c.orig	2002-03-21 04:35:12.000000000 +0100
--- parserInternals.c	2007-12-17 11:17:03.000000000 +0100
*************** xmlNextChar(xmlParserCtxtPtr ctxt) {
*** 1143,1148 ****
--- 1143,1150 ----
  
  		c = *cur;
  		if (c & 0x80) {
+ 		    if (((c & 0x40) == 0) || (c == 0xC0))
+ 		        goto encoding_error;
  		    if (cur[1] == 0)
  			xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  		    if ((cur[1] & 0xc0) != 0x80)
*************** xmlCurrentChar(xmlParserCtxtPtr ctxt, in
*** 1308,1325 ****
--- 1310,1333 ----
  		    val |= (cur[1] & 0x3f) << 12;
  		    val |= (cur[2] & 0x3f) << 6;
  		    val |= cur[3] & 0x3f;
+ 		    if (val < 0x10000)
+ 			goto encoding_error;
  		} else {
  		  /* 3-byte code */
  		    *len = 3;
  		    val = (cur[0] & 0xf) << 12;
  		    val |= (cur[1] & 0x3f) << 6;
  		    val |= cur[2] & 0x3f;
+ 		    if (val < 0x800)
+ 			goto encoding_error;
  		}
  	    } else {
  	      /* 2-byte code */
  		*len = 2;
  		val = (cur[0] & 0x1f) << 6;
  		val |= cur[1] & 0x3f;
+ 		if (val < 0x80)
+ 		    goto encoding_error;
  	    }
  	    if (!IS_CHAR(val)) {
  		if ((ctxt->sax != NULL) &&
*************** xmlCurrentChar(xmlParserCtxtPtr ctxt, in
*** 1334,1339 ****
--- 1342,1359 ----
  	} else {
  	    /* 1-byte code */
  	    *len = 1;
+ 	    if (*ctxt->input->cur == 0)
+ 		xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+ 	    if ((*ctxt->input->cur == 0) &&
+ 	        (ctxt->input->end > ctxt->input->cur)) {
+ 		if ((ctxt->sax != NULL) &&
+ 		    (ctxt->sax->error != NULL))
+ 		    ctxt->sax->error(ctxt->userData, 
+ 				     "Char 0x0 out of allowed range\n");
+ 		ctxt->errNo = XML_ERR_INVALID_ENCODING;
+ 		ctxt->wellFormed = 0;
+ 		ctxt->disableSAX = 1;
+ 	    }
  	    if (*ctxt->input->cur == 0xD) {
  		if (ctxt->input->cur[1] == 0xA) {
  		    ctxt->nbChars++;
*** parserInternals.c.orig	2003-08-02 18:23:52.000000000 +0200
--- parserInternals.c	2007-12-17 11:30:12.000000000 +0100
*************** xmlCurrentChar(xmlParserCtxtPtr ctxt, in
*** 1316,1333 ****
--- 1316,1339 ----
  		    val |= (cur[1] & 0x3f) << 12;
  		    val |= (cur[2] & 0x3f) << 6;
  		    val |= cur[3] & 0x3f;
+ 		    if (val < 0x10000)
+ 			goto encoding_error;
  		} else {
  		  /* 3-byte code */
  		    *len = 3;
  		    val = (cur[0] & 0xf) << 12;
  		    val |= (cur[1] & 0x3f) << 6;
  		    val |= cur[2] & 0x3f;
+ 		    if (val < 0x800)
+ 			goto encoding_error;
  		}
  	    } else {
  	      /* 2-byte code */
  		*len = 2;
  		val = (cur[0] & 0x1f) << 6;
  		val |= cur[1] & 0x3f;
+ 		if (val < 0x80)
+ 		    goto encoding_error;
  	    }
  	    if (!IS_CHAR(val)) {
  		if ((ctxt->sax != NULL) &&
*************** xmlCurrentChar(xmlParserCtxtPtr ctxt, in
*** 1342,1347 ****
--- 1348,1365 ----
  	} else {
  	    /* 1-byte code */
  	    *len = 1;
+ 	    if (*ctxt->input->cur == 0)
+ 		xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+ 	    if ((*ctxt->input->cur == 0) &&
+ 	        (ctxt->input->end > ctxt->input->cur)) {
+ 		if ((ctxt->sax != NULL) &&
+ 		    (ctxt->sax->error != NULL))
+ 		    ctxt->sax->error(ctxt->userData, 
+ 				     "Char 0x0 out of allowed range\n");
+ 		ctxt->errNo = XML_ERR_INVALID_ENCODING;
+ 		ctxt->wellFormed = 0;
+ 		ctxt->disableSAX = 1;
+ 	    }
  	    if (*ctxt->input->cur == 0xD) {
  		if (ctxt->input->cur[1] == 0xA) {
  		    ctxt->nbChars++;
Index: parserInternals.c
===================================================================
--- parserInternals.c	(revision 3667)
+++ parserInternals.c	(working copy)
@@ -638,14 +638,13 @@
 
 	c = *cur;
 	if (c & 0x80) {
-	    if (c == 0xC0)
+	    if (((c & 0x40) == 0) || (c == 0xC0))
 		goto encoding_error;
 	    if (cur[1] == 0)
 		xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
 	    if ((cur[1] & 0xc0) != 0x80)
 		goto encoding_error;
 	    if ((c & 0xe0) == 0xe0) {
-
 		if (cur[2] == 0)
 		    xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
 		if ((cur[2] & 0xc0) != 0x80)
@@ -662,18 +661,24 @@
 		    val |= (cur[1] & 0x3f) << 12;
 		    val |= (cur[2] & 0x3f) << 6;
 		    val |= cur[3] & 0x3f;
+		    if (val < 0x10000)
+			goto encoding_error;
 		} else {
 		  /* 3-byte code */
 		    *len = 3;
 		    val = (cur[0] & 0xf) << 12;
 		    val |= (cur[1] & 0x3f) << 6;
 		    val |= cur[2] & 0x3f;
+		    if (val < 0x800)
+			goto encoding_error;
 		}
 	    } else {
 	      /* 2-byte code */
 		*len = 2;
 		val = (cur[0] & 0x1f) << 6;
 		val |= cur[1] & 0x3f;
+		if (val < 0x80)
+		    goto encoding_error;
 	    }
 	    if (!IS_CHAR(val)) {
 	        xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
@@ -683,6 +688,13 @@
 	} else {
 	    /* 1-byte code */
 	    *len = 1;
+	    if (*ctxt->input->cur == 0)
+		xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+	    if ((*ctxt->input->cur == 0) &&
+	        (ctxt->input->end > ctxt->input->cur)) {
+	        xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
+				  "Char 0x%X out of allowed range\n", val);
+	    }
 	    if (*ctxt->input->cur == 0xD) {
 		if (ctxt->input->cur[1] == 0xA) {
 		    ctxt->nbChars++;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]