aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArmin Kuster <akuster@mvista.com>2016-07-09 15:03:43 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-07-27 08:29:39 +0100
commit990b5427fd3bf5c00ac7c5820d5f455378776b62 (patch)
tree69bf43d5bfdc582f73e2181a5644b4570db2a5b4
parentd008b7023cb703a787c8fcac5cd87628b38a9ecd (diff)
downloadopenembedded-core-contrib-990b5427fd3bf5c00ac7c5820d5f455378776b62.tar.gz
libxml2: Security fix for CVE-2016-1833
Affects libxml2 < 2.9.4 Signed-off-by: Armin Kuster <akuster@mvista.com>
-rw-r--r--meta/recipes-core/libxml/libxml2/CVE-2016-1833.patch368
-rw-r--r--meta/recipes-core/libxml/libxml2_2.9.2.bb1
2 files changed, 369 insertions, 0 deletions
diff --git a/meta/recipes-core/libxml/libxml2/CVE-2016-1833.patch b/meta/recipes-core/libxml/libxml2/CVE-2016-1833.patch
new file mode 100644
index 0000000000..26a19b86e7
--- /dev/null
+++ b/meta/recipes-core/libxml/libxml2/CVE-2016-1833.patch
@@ -0,0 +1,368 @@
+From 0bcd05c5cd83dec3406c8f68b769b1d610c72f76 Mon Sep 17 00:00:00 2001
+From: Pranjal Jumde <pjumde@apple.com>
+Date: Tue, 1 Mar 2016 15:18:04 -0800
+Subject: [PATCH] Heap-based buffer overread in htmlCurrentChar
+
+For https://bugzilla.gnome.org/show_bug.cgi?id=758606
+
+* parserInternals.c:
+(xmlNextChar): Add an test to catch other issues on ctxt->input
+corruption proactively.
+For non-UTF-8 charsets, xmlNextChar() failed to check for the end
+of the input buffer and would continuing reading. Fix this by
+pulling out the check for the end of the input buffer into common
+code, and return if we reach the end of the input buffer
+prematurely.
+* result/HTML/758606.html: Added.
+* result/HTML/758606.html.err: Added.
+* result/HTML/758606.html.sax: Added.
+* result/HTML/758606_2.html: Added.
+* result/HTML/758606_2.html.err: Added.
+* result/HTML/758606_2.html.sax: Added.
+* test/HTML/758606.html: Added test case.
+* test/HTML/758606_2.html: Added test case.
+
+Upstream-Status: Backport
+CVE: CVE-2016-1833
+Signed-off-by: Armin Kuster <akuster@mvista.com>
+
+---
+ parserInternals.c | 172 ++++++++++++++++++++++--------------------
+ result/HTML/758606.html | 2 +
+ result/HTML/758606.html.err | 16 ++++
+ result/HTML/758606.html.sax | 10 +++
+ result/HTML/758606_2.html | 2 +
+ result/HTML/758606_2.html.err | 16 ++++
+ result/HTML/758606_2.html.sax | 17 +++++
+ test/HTML/758606.html | 1 +
+ test/HTML/758606_2.html | 1 +
+ 9 files changed, 154 insertions(+), 83 deletions(-)
+ create mode 100644 result/HTML/758606.html
+ create mode 100644 result/HTML/758606.html.err
+ create mode 100644 result/HTML/758606.html.sax
+ create mode 100644 result/HTML/758606_2.html
+ create mode 100644 result/HTML/758606_2.html.err
+ create mode 100644 result/HTML/758606_2.html.sax
+ create mode 100644 test/HTML/758606.html
+ create mode 100644 test/HTML/758606_2.html
+
+diff --git a/parserInternals.c b/parserInternals.c
+index 8c79678..bfc778a 100644
+--- a/parserInternals.c
++++ b/parserInternals.c
+@@ -55,6 +55,10 @@
+ #include <libxml/globals.h>
+ #include <libxml/chvalid.h>
+
++#define CUR(ctxt) ctxt->input->cur
++#define END(ctxt) ctxt->input->end
++#define VALID_CTXT(ctxt) (CUR(ctxt) <= END(ctxt))
++
+ #include "buf.h"
+ #include "enc.h"
+
+@@ -422,103 +426,105 @@ xmlNextChar(xmlParserCtxtPtr ctxt)
+ (ctxt->input == NULL))
+ return;
+
+- if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
+- if ((*ctxt->input->cur == 0) &&
+- (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0) &&
+- (ctxt->instate != XML_PARSER_COMMENT)) {
+- /*
+- * If we are at the end of the current entity and
+- * the context allows it, we pop consumed entities
+- * automatically.
+- * the auto closing should be blocked in other cases
+- */
++ if (!(VALID_CTXT(ctxt))) {
++ xmlErrInternal(ctxt, "Parser input data memory error\n", NULL);
++ ctxt->errNo = XML_ERR_INTERNAL_ERROR;
++ xmlStopParser(ctxt);
++ return;
++ }
++
++ if ((*ctxt->input->cur == 0) &&
++ (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) {
++ if ((ctxt->instate != XML_PARSER_COMMENT))
+ xmlPopInput(ctxt);
+- } else {
+- const unsigned char *cur;
+- unsigned char c;
++ return;
++ }
+
+- /*
+- * 2.11 End-of-Line Handling
+- * the literal two-character sequence "#xD#xA" or a standalone
+- * literal #xD, an XML processor must pass to the application
+- * the single character #xA.
+- */
+- if (*(ctxt->input->cur) == '\n') {
+- ctxt->input->line++; ctxt->input->col = 1;
+- } else
+- ctxt->input->col++;
++ if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
++ const unsigned char *cur;
++ unsigned char c;
+
+- /*
+- * We are supposed to handle UTF8, check it's valid
+- * From rfc2044: encoding of the Unicode values on UTF-8:
+- *
+- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
+- * 0000 0000-0000 007F 0xxxxxxx
+- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
+- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
+- *
+- * Check for the 0x110000 limit too
+- */
+- cur = ctxt->input->cur;
++ /*
++ * 2.11 End-of-Line Handling
++ * the literal two-character sequence "#xD#xA" or a standalone
++ * literal #xD, an XML processor must pass to the application
++ * the single character #xA.
++ */
++ if (*(ctxt->input->cur) == '\n') {
++ ctxt->input->line++; ctxt->input->col = 1;
++ } else
++ ctxt->input->col++;
+
+- c = *cur;
+- if (c & 0x80) {
+- if (c == 0xC0)
+- goto encoding_error;
+- if (cur[1] == 0) {
++ /*
++ * We are supposed to handle UTF8, check it's valid
++ * From rfc2044: encoding of the Unicode values on UTF-8:
++ *
++ * UCS-4 range (hex.) UTF-8 octet sequence (binary)
++ * 0000 0000-0000 007F 0xxxxxxx
++ * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
++ * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
++ *
++ * Check for the 0x110000 limit too
++ */
++ cur = ctxt->input->cur;
++
++ c = *cur;
++ if (c & 0x80) {
++ if (c == 0xC0)
++ goto encoding_error;
++ if (cur[1] == 0) {
++ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
++ cur = ctxt->input->cur;
++ }
++ if ((cur[1] & 0xc0) != 0x80)
++ goto encoding_error;
++ if ((c & 0xe0) == 0xe0) {
++ unsigned int val;
++
++ if (cur[2] == 0) {
+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+ cur = ctxt->input->cur;
+ }
+- if ((cur[1] & 0xc0) != 0x80)
++ if ((cur[2] & 0xc0) != 0x80)
+ goto encoding_error;
+- if ((c & 0xe0) == 0xe0) {
+- unsigned int val;
+-
+- if (cur[2] == 0) {
++ if ((c & 0xf0) == 0xf0) {
++ if (cur[3] == 0) {
+ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+ cur = ctxt->input->cur;
+ }
+- if ((cur[2] & 0xc0) != 0x80)
++ if (((c & 0xf8) != 0xf0) ||
++ ((cur[3] & 0xc0) != 0x80))
+ goto encoding_error;
+- if ((c & 0xf0) == 0xf0) {
+- if (cur[3] == 0) {
+- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+- cur = ctxt->input->cur;
+- }
+- if (((c & 0xf8) != 0xf0) ||
+- ((cur[3] & 0xc0) != 0x80))
+- goto encoding_error;
+- /* 4-byte code */
+- ctxt->input->cur += 4;
+- val = (cur[0] & 0x7) << 18;
+- val |= (cur[1] & 0x3f) << 12;
+- val |= (cur[2] & 0x3f) << 6;
+- val |= cur[3] & 0x3f;
+- } else {
+- /* 3-byte code */
+- ctxt->input->cur += 3;
+- val = (cur[0] & 0xf) << 12;
+- val |= (cur[1] & 0x3f) << 6;
+- val |= cur[2] & 0x3f;
+- }
+- if (((val > 0xd7ff) && (val < 0xe000)) ||
+- ((val > 0xfffd) && (val < 0x10000)) ||
+- (val >= 0x110000)) {
+- xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
+- "Char 0x%X out of allowed range\n",
+- val);
+- }
+- } else
+- /* 2-byte code */
+- ctxt->input->cur += 2;
++ /* 4-byte code */
++ ctxt->input->cur += 4;
++ val = (cur[0] & 0x7) << 18;
++ val |= (cur[1] & 0x3f) << 12;
++ val |= (cur[2] & 0x3f) << 6;
++ val |= cur[3] & 0x3f;
++ } else {
++ /* 3-byte code */
++ ctxt->input->cur += 3;
++ val = (cur[0] & 0xf) << 12;
++ val |= (cur[1] & 0x3f) << 6;
++ val |= cur[2] & 0x3f;
++ }
++ if (((val > 0xd7ff) && (val < 0xe000)) ||
++ ((val > 0xfffd) && (val < 0x10000)) ||
++ (val >= 0x110000)) {
++ xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
++ "Char 0x%X out of allowed range\n",
++ val);
++ }
+ } else
+- /* 1-byte code */
+- ctxt->input->cur++;
++ /* 2-byte code */
++ ctxt->input->cur += 2;
++ } else
++ /* 1-byte code */
++ ctxt->input->cur++;
+
+- ctxt->nbChars++;
+- if (*ctxt->input->cur == 0)
+- xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+- }
++ ctxt->nbChars++;
++ if (*ctxt->input->cur == 0)
++ xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
+ } else {
+ /*
+ * Assume it's a fixed length encoding (1) with
+diff --git a/result/HTML/758606.html b/result/HTML/758606.html
+new file mode 100644
+index 0000000..4f21f62
+--- /dev/null
++++ b/result/HTML/758606.html
+@@ -0,0 +1,2 @@
++<!DOCTYPE >
++
+diff --git a/result/HTML/758606.html.err b/result/HTML/758606.html.err
+new file mode 100644
+index 0000000..060433a
+--- /dev/null
++++ b/result/HTML/758606.html.err
+@@ -0,0 +1,16 @@
++./test/HTML/758606.html:1: HTML parser error : Comment not terminated
++<!--
++<!-- <!doctype
++ ^
++./test/HTML/758606.html:1: HTML parser error : Invalid char in CDATA 0xC
++<!-- <!doctype
++ ^
++./test/HTML/758606.html:1: HTML parser error : Misplaced DOCTYPE declaration
++<!-- <!doctype
++ ^
++./test/HTML/758606.html:2: HTML parser error : htmlParseDocTypeDecl : no DOCTYPE name !
++
++^
++./test/HTML/758606.html:2: HTML parser error : DOCTYPE improperly terminated
++
++^
+diff --git a/result/HTML/758606.html.sax b/result/HTML/758606.html.sax
+new file mode 100644
+index 0000000..d44a5cf
+--- /dev/null
++++ b/result/HTML/758606.html.sax
+@@ -0,0 +1,10 @@
++SAX.setDocumentLocator()
++SAX.startDocument()
++SAX.error: Comment not terminated
++<!--
++SAX.error: Invalid char in CDATA 0xC
++SAX.error: Misplaced DOCTYPE declaration
++SAX.error: htmlParseDocTypeDecl : no DOCTYPE name !
++SAX.error: DOCTYPE improperly terminated
++SAX.internalSubset((null), , )
++SAX.endDocument()
+diff --git a/result/HTML/758606_2.html b/result/HTML/758606_2.html
+new file mode 100644
+index 0000000..273816a
+--- /dev/null
++++ b/result/HTML/758606_2.html
+@@ -0,0 +1,2 @@
++<!DOCTYPE >
++<html><body><p>&#145;</p></body></html>
+diff --git a/result/HTML/758606_2.html.err b/result/HTML/758606_2.html.err
+new file mode 100644
+index 0000000..4be039f
+--- /dev/null
++++ b/result/HTML/758606_2.html.err
+@@ -0,0 +1,16 @@
++./test/HTML/758606_2.html:1: HTML parser error : Comment not terminated
++<!--
++<!-- ‘<!dOctYPE
++ ^
++./test/HTML/758606_2.html:1: HTML parser error : Invalid char in CDATA 0xC
++<!-- ‘<!dOctYPE
++ ^
++./test/HTML/758606_2.html:1: HTML parser error : Misplaced DOCTYPE declaration
++‘<!dOctYPE
++ ^
++./test/HTML/758606_2.html:2: HTML parser error : htmlParseDocTypeDecl : no DOCTYPE name !
++
++^
++./test/HTML/758606_2.html:2: HTML parser error : DOCTYPE improperly terminated
++
++^
+diff --git a/result/HTML/758606_2.html.sax b/result/HTML/758606_2.html.sax
+new file mode 100644
+index 0000000..80ff3d7
+--- /dev/null
++++ b/result/HTML/758606_2.html.sax
+@@ -0,0 +1,17 @@
++SAX.setDocumentLocator()
++SAX.startDocument()
++SAX.error: Comment not terminated
++<!--
++SAX.error: Invalid char in CDATA 0xC
++SAX.startElement(html)
++SAX.startElement(body)
++SAX.startElement(p)
++SAX.characters(&#145;, 2)
++SAX.error: Misplaced DOCTYPE declaration
++SAX.error: htmlParseDocTypeDecl : no DOCTYPE name !
++SAX.error: DOCTYPE improperly terminated
++SAX.internalSubset((null), , )
++SAX.endElement(p)
++SAX.endElement(body)
++SAX.endElement(html)
++SAX.endDocument()
+diff --git a/test/HTML/758606.html b/test/HTML/758606.html
+new file mode 100644
+index 0000000..01a013c
+--- /dev/null
++++ b/test/HTML/758606.html
+@@ -0,0 +1 @@
++<!-- <!doctype
+diff --git a/test/HTML/758606_2.html b/test/HTML/758606_2.html
+new file mode 100644
+index 0000000..daa185b
+--- /dev/null
++++ b/test/HTML/758606_2.html
+@@ -0,0 +1 @@
++<!-- ‘<!dOctYPE
+--
+2.3.5
+
diff --git a/meta/recipes-core/libxml/libxml2_2.9.2.bb b/meta/recipes-core/libxml/libxml2_2.9.2.bb
index 2bbdb0961d..76efa9ffca 100644
--- a/meta/recipes-core/libxml/libxml2_2.9.2.bb
+++ b/meta/recipes-core/libxml/libxml2_2.9.2.bb
@@ -15,6 +15,7 @@ SRC_URI += "file://CVE-2016-1762.patch \
file://CVE-2016-4449.patch \
file://CVE-2016-1837.patch \
file://CVE-2016-1835.patch \
+ file://CVE-2016-1833.patch \
"
SRC_URI[libtar.md5sum] = "9e6a9aca9d155737868b3dc5fd82f788"