[raptor] Fixed XML entity expansion that could lead to information disclosure (CVE-2012-0037)

Jaroslav Škarvada jskarvad at fedoraproject.org
Thu Jul 12 09:26:31 UTC 2012


commit 24f2fa708c805f08d3bea9016cae73a0bad87799
Author: Jaroslav Škarvada <jskarvad at redhat.com>
Date:   Thu Jul 12 11:26:16 2012 +0200

    Fixed XML entity expansion that could lead to information disclosure (CVE-2012-0037)
    
      Resolves: rhbz#805941

 raptor-1.4.21-CVE-2012-0037.patch |  383 +++++++++++++++++++++++++++++++++++++
 raptor.spec                       |   10 +-
 2 files changed, 391 insertions(+), 2 deletions(-)
---
diff --git a/raptor-1.4.21-CVE-2012-0037.patch b/raptor-1.4.21-CVE-2012-0037.patch
new file mode 100644
index 0000000..12c4524
--- /dev/null
+++ b/raptor-1.4.21-CVE-2012-0037.patch
@@ -0,0 +1,383 @@
+diff --git a/src/raptor.h b/src/raptor.h
+--- a/src/raptor.h
++++ b/src/raptor.h
+@@ -407,6 +407,7 @@ typedef struct {
+  * @RAPTOR_FEATURE_RSS_TRIPLES: Atom/RSS serializer writes extra RDF triples it finds (none, rdf-xml, atom-triples)
+  * @RAPTOR_FEATURE_ATOM_ENTRY_URI: Atom entry URI.  If given, generate an Atom Entry Document with the item having the given URI, otherwise generate an Atom Feed Document with any items found.
+  * @RAPTOR_FEATURE_PREFIX_ELEMENTS: Integer. If set, generate Atom/RSS1.0 documents with prefixed elements, otherwise unprefixed.
++ * @RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES: When reading XML, load external entities.
+  * @RAPTOR_FEATURE_LAST: Internal
+  *
+  * Raptor parser, serializer or XML writer features.
+@@ -448,7 +449,8 @@ typedef enum {
+   RAPTOR_FEATURE_RSS_TRIPLES,
+   RAPTOR_FEATURE_ATOM_ENTRY_URI,
+   RAPTOR_FEATURE_PREFIX_ELEMENTS,
+-  RAPTOR_FEATURE_LAST = RAPTOR_FEATURE_PREFIX_ELEMENTS
++  RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES,
++  RAPTOR_FEATURE_LAST = RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES
+ } raptor_feature;
+ 
+ 
+diff --git a/src/raptor_feature.c b/src/raptor_feature.c
+--- a/src/raptor_feature.c
++++ b/src/raptor_feature.c
+@@ -93,7 +93,8 @@ static const struct
+   { RAPTOR_FEATURE_JSON_EXTRA_DATA   , 6,  "jsonExtraData", "JSON serializer extra data" },
+   { RAPTOR_FEATURE_RSS_TRIPLES       , 6,  "rssTriples", "Atom/RSS serializer writes extra RDF triples" },
+   { RAPTOR_FEATURE_ATOM_ENTRY_URI    , 6,  "atomEntryUri", "Atom serializer Entry URI" },
+-  { RAPTOR_FEATURE_PREFIX_ELEMENTS   , 2,  "prefixElements", "Atom/RSS serializers write namespace-prefixed elements" }
++  { RAPTOR_FEATURE_PREFIX_ELEMENTS   , 2,  "prefixElements", "Atom/RSS serializers write namespace-prefixed elements" },
++  { RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES, 1, "loadExternalEntities", "Load external XML entities." }
+ };
+ 
+ 
+diff -urN -X /Users/dajobe/dev/dontdiff -x raptor.rdf -x file1.txt -x xmlent1.rdf -x rapper -x rdfdiff raptor-1.4.17.orig/src/raptor_internal.h raptor-1.4.17/src/raptor_internal.h
+--- raptor-1.4.17.orig/src/raptor_internal.h	2008-03-25 23:16:30.000000000 -0700
++++ raptor-1.4.17/src/raptor_internal.h	2012-02-04 15:06:05.000000000 -0800
+@@ -1056,6 +1056,14 @@
+ 
+   /* base URI for resolving relative URIs or xml:base URIs */
+   raptor_uri* base_uri;
++
++  /* call SAX2 handlers if non-0 */
++  int enabled;
++
++  /* FEATURE: 
++   * non 0 if XML entities should be loaded
++   */
++  int feature_load_external_entities;
+ 
+   /* sax2 init failed - do not try to do anything with it */
+   int failed;
+diff -urN -X /Users/dajobe/dev/dontdiff -x raptor.rdf -x file1.txt -x xmlent1.rdf -x rapper -x rdfdiff raptor-1.4.17.orig/src/raptor_libxml.c raptor-1.4.17/src/raptor_libxml.c
+--- raptor-1.4.17.orig/src/raptor_libxml.c	2008-02-24 23:24:28.000000000 -0800
++++ raptor-1.4.17/src/raptor_libxml.c	2012-02-04 15:05:22.000000000 -0800
+@@ -142,18 +142,115 @@
+ 
+ static xmlParserInputPtr
+ raptor_libxml_resolveEntity(void* user_data, 
+-                            const xmlChar *publicId, const xmlChar *systemId) {
+-  raptor_sax2* sax2=(raptor_sax2*)user_data;
+-  return libxml2_resolveEntity(sax2->xc, publicId, systemId);
++                            const xmlChar *publicId, const xmlChar *systemId)
++{
++  raptor_sax2* sax2 = (raptor_sax2*)user_data;
++  xmlParserCtxtPtr ctxt = sax2->xc;
++  const unsigned char *uri_string = NULL;
++  xmlParserInputPtr entity_input;
++  int load_entity = 0;
++
++  if(ctxt->input)
++    uri_string = (const unsigned char *)ctxt->input->filename;
++
++  if(!uri_string)
++    uri_string = (const unsigned char *)ctxt->directory;
++
++  load_entity = sax2->feature_load_external_entities;
++
++  if(load_entity) {
++    entity_input = xmlLoadExternalEntity((const char*)uri_string,
++                                         (const char*)publicId,
++                                         ctxt);
++  } else {
++    RAPTOR_DEBUG4("Not loading entity URI %s by policy for publicId '%s' systemId '%s'\n", uri_string, publicId, systemId);
++  }
++  
++  return entity_input;
+ }
+ 
+ 
+ static xmlEntityPtr
+-raptor_libxml_getEntity(void* user_data, const xmlChar *name) {
+-  raptor_sax2* sax2=(raptor_sax2*)user_data;
+-  return libxml2_getEntity(sax2->xc, name);
+-}
++raptor_libxml_getEntity(void* user_data, const xmlChar *name)
++{
++  raptor_sax2* sax2 = (raptor_sax2*)user_data;
++  xmlParserCtxtPtr xc = sax2->xc;
++  xmlEntityPtr ret = NULL;
++
++  if(!xc)
++    return NULL;
++
++  if(!xc->inSubset) {
++    /* looks for hardcoded set of entity names - lt, gt etc. */
++    ret = xmlGetPredefinedEntity(name);
++    if(ret) {
++      RAPTOR_DEBUG2("Entity '%s' found in predefined set\n", name);
++      return ret;
++    }
++  }
++
++  /* This section uses xmlGetDocEntity which looks for entities in
++   * memory only, never from a file or URI 
++   */
++  if(xc->myDoc && (xc->myDoc->standalone == 1)) {
++    RAPTOR_DEBUG2("Entity '%s' document is standalone\n", name);
++    /* Document is standalone: no entities are required to interpret doc */
++    if(xc->inSubset == 2) {
++      xc->myDoc->standalone = 0;
++      ret = xmlGetDocEntity(xc->myDoc, name);
++      xc->myDoc->standalone = 1;
++    } else {
++      ret = xmlGetDocEntity(xc->myDoc, name);
++      if(!ret) {
++        xc->myDoc->standalone = 0;
++        ret = xmlGetDocEntity(xc->myDoc, name);
++        xc->myDoc->standalone = 1;
++      }
++    }
++  } else {
++    ret = xmlGetDocEntity(xc->myDoc, name);
++  }
+ 
++  if(ret && !ret->children &&
++    (ret->etype == XML_EXTERNAL_GENERAL_PARSED_ENTITY)) {
++    /* Entity is an external general parsed entity. It may be in a
++     * catalog file, user file or user URI
++     */
++    int val = 0;
++    xmlNodePtr children;
++    int load_entity = 0;
++
++    load_entity = sax2->feature_load_external_entities;
++
++    if(!load_entity) {
++      RAPTOR_DEBUG2("Not getting entity URI %s by policy\n", ret->URI);
++      children = xmlNewText((const xmlChar*)"");
++    } else {
++      /* Disable SAX2 handlers so that the SAX2 events do not all get
++       * sent to callbacks during dealing with the entity parsing.
++       */
++      sax2->enabled = 0;
++      val = xmlParseCtxtExternalEntity(xc, ret->URI, ret->ExternalID, &children);
++      sax2->enabled = 1;
++    }
++    
++    if(!val) {
++      xmlAddChildList((xmlNodePtr)ret, children);
++    } else {
++      xc->validate = 0;
++      return NULL;
++    }
++    
++    ret->owner = 1;
++
++    /* Mark this entity as having been checked - never do this again */
++    if(!ret->checked)
++      ret->checked = 1;
++  }
++
++  return ret;
++}
++  
+ 
+ static xmlEntityPtr
+ raptor_libxml_getParameterEntity(void* user_data, const xmlChar *name) {
+diff --git a/src/raptor_parse.c b/src/raptor_parse.c
+--- a/src/raptor_parse.c
++++ b/src/raptor_parse.c
+@@ -1443,6 +1443,7 @@ raptor_set_feature(raptor_parser *parser, raptor_feature feature, int value)
+     case RAPTOR_FEATURE_MICROFORMATS:
+     case RAPTOR_FEATURE_HTML_LINK:
+     case RAPTOR_FEATURE_WWW_TIMEOUT:
++    case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+       parser->features[(int)feature]=value;
+       break;
+ 
+@@ -1564,6 +1565,7 @@ raptor_get_feature(raptor_parser *parser, raptor_feature feature)
+     case RAPTOR_FEATURE_MICROFORMATS:
+     case RAPTOR_FEATURE_HTML_LINK:
+     case RAPTOR_FEATURE_WWW_TIMEOUT:
++    case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+       result = parser->features[(int)feature];
+       break;
+ 
+diff -urN -X /Users/dajobe/dev/dontdiff -x raptor.rdf -x file1.txt -x xmlent1.rdf -x rapper -x rdfdiff raptor-1.4.17.orig/src/raptor_rdfxml.c raptor-1.4.17/src/raptor_rdfxml.c
+--- raptor-1.4.17.orig/src/raptor_rdfxml.c	2008-03-26 00:26:03.000000000 -0700
++++ raptor-1.4.17/src/raptor_rdfxml.c	2012-02-04 15:05:29.000000000 -0800
+@@ -1124,6 +1124,9 @@
+   raptor_sax2_set_feature(rdf_xml_parser->sax2, 
+                           RAPTOR_FEATURE_NO_NET,
+                           rdf_parser->features[RAPTOR_FEATURE_NO_NET]);
++  raptor_sax2_set_feature(rdf_xml_parser->sax2, 
++                          RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES,
++                          rdf_parser->features[RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES]);
+   
+   raptor_sax2_parse_start(rdf_xml_parser->sax2, uri);
+ 
+diff -urN -X /Users/dajobe/dev/dontdiff -x raptor.rdf -x file1.txt -x xmlent1.rdf -x rapper -x rdfdiff raptor-1.4.17.orig/src/raptor_rss.c raptor-1.4.17/src/raptor_rss.c
+--- raptor-1.4.17.orig/src/raptor_rss.c	2008-01-12 11:27:15.000000000 -0800
++++ raptor-1.4.17/src/raptor_rss.c	2012-02-04 15:05:33.000000000 -0800
+@@ -243,6 +243,9 @@
+   raptor_sax2_set_feature(rss_parser->sax2, 
+                           RAPTOR_FEATURE_NO_NET,
+                           rdf_parser->features[RAPTOR_FEATURE_NO_NET]);
++  raptor_sax2_set_feature(rss_parser->sax2, 
++                          RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES,
++                          rdf_parser->features[RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES]);
+   
+   raptor_sax2_parse_start(rss_parser->sax2, uri);
+ 
+diff -urN -X /Users/dajobe/dev/dontdiff -x raptor.rdf -x file1.txt -x xmlent1.rdf -x rapper -x rdfdiff raptor-1.4.17.orig/src/raptor_sax2.c raptor-1.4.17/src/raptor_sax2.c
+--- raptor-1.4.17.orig/src/raptor_sax2.c	2008-03-26 00:26:03.000000000 -0700
++++ raptor-1.4.17/src/raptor_sax2.c	2012-02-04 15:05:38.000000000 -0800
+@@ -96,6 +96,8 @@
+ 
+   sax2->user_data=user_data;
+ 
++  sax2->enabled = 1;
++
+   sax2->locator=error_handlers->locator;
+   
+   sax2->error_handlers=error_handlers;
+@@ -684,6 +686,10 @@
+       sax2->feature_no_net=value;
+       break;
+ 
++    case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
++      sax2->feature_load_external_entities=value;
++      break;
++
+     case RAPTOR_FEATURE_SCANNING:
+     case RAPTOR_FEATURE_ASSUME_IS_RDF:
+     case RAPTOR_FEATURE_ALLOW_NON_NS_ATTRIBUTES:
+@@ -802,7 +802,7 @@ raptor_sax2_start_element(void* user_data, const unsigned char *name,
+   unsigned char *xml_language=NULL;
+   raptor_uri *xml_base=NULL;
+ 
+-  if(sax2->failed)
++  if(!sax2->enabled || sax2->failed)
+     return;
+ 
+ #ifdef RAPTOR_XML_EXPAT
+@@ -1031,7 +1031,7 @@ raptor_sax2_end_element(void* user_data, const unsigned char *name)
+   raptor_sax2* sax2=(raptor_sax2*)user_data;
+   raptor_xml_element* xml_element;
+ 
+-  if(sax2->failed)
++  if(!sax2->enabled || sax2->failed)
+     return;
+ 
+ #ifdef RAPTOR_XML_EXPAT
+@@ -1069,7 +1069,7 @@ void
+ raptor_sax2_characters(void* user_data, const unsigned char *s, int len)
+ {
+   raptor_sax2* sax2=(raptor_sax2*)user_data;
+-  if(!sax2->failed && sax2->characters_handler)
++  if(sax2->enabled && !sax2->failed && sax2->characters_handler)
+     sax2->characters_handler(sax2->user_data, sax2->current_element, s, len);
+ }
+ 
+@@ -1085,7 +1085,7 @@ raptor_sax2_cdata(void* user_data, const unsigned char *s, int len)
+ #endif
+ #endif
+ 
+-  if(!sax2->failed && sax2->cdata_handler)
++  if(sax2->enabled && !sax2->failed && sax2->cdata_handler)
+     sax2->cdata_handler(sax2->user_data, sax2->current_element, s, len);
+ }
+ 
+@@ -1095,7 +1095,7 @@ void
+ raptor_sax2_comment(void* user_data, const unsigned char *s)
+ {
+   raptor_sax2* sax2=(raptor_sax2*)user_data;
+-  if(!sax2->failed && sax2->comment_handler)
++  if(sax2->enabled && !sax2->failed && sax2->comment_handler)
+     sax2->comment_handler(sax2->user_data, sax2->current_element, s);
+ }
+ 
+@@ -1110,7 +1110,7 @@ raptor_sax2_unparsed_entity_decl(void* user_data,
+                                  const unsigned char* notationName)
+ {
+   raptor_sax2* sax2=(raptor_sax2*)user_data;
+-  if(!sax2->failed && sax2->unparsed_entity_decl_handler)
++  if(sax2->enabled && !sax2->failed && sax2->unparsed_entity_decl_handler)
+     sax2->unparsed_entity_decl_handler(sax2->user_data,
+                                        entityName, base, systemId, 
+                                        publicId, notationName);
+@@ -1127,7 +1127,7 @@ raptor_sax2_external_entity_ref(void* user_data,
+ {
+   raptor_sax2* sax2=(raptor_sax2*)user_data;
+ 
+-  if(sax2->failed)
++  if(!sax2->enabled || sax2->failed)
+     return 0;
+ 
+   if(sax2->external_entity_ref_handler)
+
+diff -urN -X /Users/dajobe/dev/dontdiff -x raptor.rdf -x file1.txt -x xmlent1.rdf -x rapper -x rdfdiff raptor-1.4.17.orig/src/raptor_serialize.c raptor-1.4.17/src/raptor_serialize.c
+--- raptor-1.4.17.orig/src/raptor_serialize.c	2008-03-25 23:16:30.000000000 -0700
++++ raptor-1.4.17/src/raptor_serialize.c	2012-02-04 15:05:41.000000000 -0800
+@@ -800,6 +800,7 @@
+ 
+     /* Shared */
+     case RAPTOR_FEATURE_NO_NET:
++    case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+ 
+     /* XML writer features */
+     case RAPTOR_FEATURE_WRITER_AUTO_INDENT:
+@@ -904,6 +905,7 @@
+ 
+     /* Shared */
+     case RAPTOR_FEATURE_NO_NET:
++    case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+ 
+     /* XML writer features */
+     case RAPTOR_FEATURE_WRITER_AUTO_INDENT:
+@@ -1029,6 +1031,7 @@
+ 
+     /* Shared */
+     case RAPTOR_FEATURE_NO_NET:
++    case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+ 
+     /* XML writer features */
+     case RAPTOR_FEATURE_WRITER_AUTO_INDENT:
+@@ -1122,6 +1125,7 @@
+ 
+     /* Shared */
+     case RAPTOR_FEATURE_NO_NET:
++    case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+ 
+     /* XML writer features */
+     case RAPTOR_FEATURE_WRITER_AUTO_INDENT:
+diff -urN -X /Users/dajobe/dev/dontdiff -x raptor.rdf -x file1.txt -x xmlent1.rdf -x rapper -x rdfdiff raptor-1.4.17.orig/src/raptor_turtle_writer.c raptor-1.4.17/src/raptor_turtle_writer.c
+--- raptor-1.4.17.orig/src/raptor_turtle_writer.c	2008-03-25 23:16:30.000000000 -0700
++++ raptor-1.4.17/src/raptor_turtle_writer.c	2012-02-04 15:05:46.000000000 -0800
+@@ -724,6 +724,7 @@
+ 
+     /* Shared */
+     case RAPTOR_FEATURE_NO_NET:
++    case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+ 
+     /* XML writer features */
+     case RAPTOR_FEATURE_RELATIVE_URIS:
+@@ -835,6 +836,7 @@
+ 
+     /* Shared */
+     case RAPTOR_FEATURE_NO_NET:
++    case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+ 
+     /* XML writer features */
+     case RAPTOR_FEATURE_RELATIVE_URIS:
+diff -urN -X /Users/dajobe/dev/dontdiff -x raptor.rdf -x file1.txt -x xmlent1.rdf -x rapper -x rdfdiff raptor-1.4.17.orig/src/raptor_xml_writer.c raptor-1.4.17/src/raptor_xml_writer.c
+--- raptor-1.4.17.orig/src/raptor_xml_writer.c	2008-03-25 23:16:30.000000000 -0700
++++ raptor-1.4.17/src/raptor_xml_writer.c	2012-02-04 15:05:49.000000000 -0800
+@@ -852,6 +852,7 @@
+ 
+     /* Shared */
+     case RAPTOR_FEATURE_NO_NET:
++    case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+ 
+     /* XML writer features */
+     case RAPTOR_FEATURE_RELATIVE_URIS:
+@@ -970,6 +971,7 @@
+ 
+     /* Shared */
+     case RAPTOR_FEATURE_NO_NET:
++    case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+ 
+     /* XML writer features */
+     case RAPTOR_FEATURE_RELATIVE_URIS:
diff --git a/raptor.spec b/raptor.spec
index 1763e4b..e98b081 100644
--- a/raptor.spec
+++ b/raptor.spec
@@ -1,18 +1,19 @@
 
 # include rapper here (or in raptor2 packaging)
-%if 0%{?fedora} < 16 
+%if 0%{?fedora} < 16
 %global rapper 1
 %endif
 
 Summary:       Raptor RDF Parser Toolkit for Redland
 Name:          raptor
 Version:       1.4.21
-Release:       11%{?dist}
+Release:       12%{?dist}
 License:       LGPLv2+ or ASL 2.0
 Group:         System Environment/Libraries
 Source:        http://download.librdf.org/source/raptor-%{version}.tar.gz
 # Make the raptor-config file multilib friendly (RHBZ#477342)
 Patch0:        raptor-config-multilib.patch
+Patch1:        raptor-1.4.21-CVE-2012-0037.patch
 URL:           http://librdf.org/raptor/
 BuildRoot:     %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: libxml2-devel libxslt-devel curl-devel
@@ -39,6 +40,7 @@ RDF/XML or N-Triples.
 %prep
 %setup -q
 %patch0 -p1 -b .multilib
+%patch1 -p1 -b .CVE-2012-0037
 %patch100 -p1 -b .curl
 
 # Fix encoding
@@ -97,6 +99,10 @@ rm -rf $RPM_BUILD_ROOT
 %{_bindir}/raptor-config
 
 %changelog
+* Thu Jul 12 2012 Jaroslav Škarvada <jskarvad at redhat.com> - 1.4.21-12
+- Fixed XML entity expansion that could lead to information disclosure (CVE-2012-0037)
+  Resolves: rhbz#805941
+
 * Sat Jan 14 2012 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 1.4.21-11
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
 


More information about the scm-commits mailing list