Tuesday, September 15, 2009

Libxml2 Denial of Service

Recently, several dangerous vulnerabilities have been discovered in libxml2, the open source of Gnome for parsing xml files (http://xmlsoft.org/). In fact, I’m accidentally interested in these vulnerabilities because I used libxml2 in some my applications. So, I also want to write a demo exploiting.

From patch of Gnome, this error resides in a function of the source parser.c:
xmlParseElementChildrenContenDecl()

Looking at the function’s name, I thought that there was an error in processing DTD ELEMENT declared in the xml file. Let's pay attention to the patch of the fault:

-xmlElementContentPtr
-xmlParseElementChildrenContentDecl (xmlParserCtxtPtr ctxt, int inputchk) {
+static xmlElementContentPtr
+xmlParseElementChildrenContentDeclPriv(xmlParserCtxtPtr ctxt, int inputchk,
+ int depth) {
xmlElementContentPtr ret = NULL, cur = NULL, last = NULL, op = NULL;
const xmlChar *elem;
xmlChar type = 0;
+ if (((depth > 128) && ((ctxt->options & XML_PARSE_HUGE) == 0))
+ (depth > 2048)) {
+ xmlFatalErrMsgInt(ctxt, XML_ERR_ELEMCONTENT_NOT_FINISHED,
+"xmlParseElementChildrenContentDecl : depth %d too deep, use XML_PARSE_HUGE\n",
+ depth);
+ return(NULL);
+ }

The fixed function have one more parameter (depth). So, I guessed this error was due to the fact that ELEMENT declaration was too deep. The result was that the recursive call would consume all the memory and the program could completely crash.

Applications using libxml2 with xml parser functions (xmlReadFile, xmlParseFile…) can lead to denial of service on parsing this file.

Besides, file parser.c also have another error relating notation and enumeration attribute types in a DTD definition.