[raptor/el5] Fixed XML entity expansion that could lead to information disclosure (CVE-2012-0037)
Jaroslav Škarvada
jskarvad at fedoraproject.org
Thu Jul 12 13:29:05 UTC 2012
commit 341900e4f7da5b0b52ae85faa82ea5f2232d48b5
Author: Jaroslav Škarvada <jskarvad at redhat.com>
Date: Thu Jul 12 15:29:00 2012 +0200
Fixed XML entity expansion that could lead to information disclosure (CVE-2012-0037)
Resolves: rhbz#805938
raptor-1.4.16-CVE-2012-0037.patch | 390 +++++++++++++++++++++++++++++++++++++
raptor.spec | 8 +-
2 files changed, 397 insertions(+), 1 deletions(-)
---
diff --git a/raptor-1.4.16-CVE-2012-0037.patch b/raptor-1.4.16-CVE-2012-0037.patch
new file mode 100644
index 0000000..2e09b1a
--- /dev/null
+++ b/raptor-1.4.16-CVE-2012-0037.patch
@@ -0,0 +1,390 @@
+diff --git a/src/raptor.h b/src/raptor.h
+--- a/src/raptor.h
++++ b/src/raptor.h
+@@ -365,6 +365,7 @@ typedef struct {
+ * for GRDDL parser.
+ * @RAPTOR_FEATURE_WWW_TIMEOUT: Set timeout for internal WWW URI requests
+ * for GRDDL parser.
++ * @RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES: When reading XML, load external entities.
+ * @RAPTOR_FEATURE_LAST: Internal
+ *
+ * Raptor parser, serializer or XML writer features.
+@@ -398,7 +399,8 @@ typedef enum {
+ RAPTOR_FEATURE_MICROFORMATS,
+ RAPTOR_FEATURE_HTML_LINK,
+ RAPTOR_FEATURE_WWW_TIMEOUT,
+- RAPTOR_FEATURE_LAST=RAPTOR_FEATURE_WWW_TIMEOUT
++ 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
+@@ -82,7 +82,8 @@ static struct
+ { RAPTOR_FEATURE_HTML_TAG_SOUP , 1, "htmlTagSoup", "HTML parsing uses a lax HTML parser" },
+ { RAPTOR_FEATURE_MICROFORMATS , 1, "microformats", "GRDDL parsing looks for microformats" },
+ { RAPTOR_FEATURE_HTML_LINK , 1, "htmlLink", "GRDDL parsing looks for <link type=\"application/rdf+xml\">" },
+- { RAPTOR_FEATURE_WWW_TIMEOUT , 1, "wwwTimeout", "Set internal WWW URI retrieval timeout" }
++ { RAPTOR_FEATURE_WWW_TIMEOUT , 1, "wwwTimeout", "Set internal WWW URI retrieval timeout" },
++ { RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES, 1, "loadExternalEntities", "Load external XML entities." }
+ };
+
+
+diff --git a/src/raptor_internal.h b/src/raptor_internal.h
+--- a/src/raptor_internal.h
++++ b/src/raptor_internal.h
+@@ -969,6 +969,14 @@ struct raptor_sax2_s {
+
+ /* 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;
+ };
+
+ void raptor_sax2_init(void);
+diff --git a/src/raptor_libxml.c b/src/raptor_libxml.c
+--- a/src/raptor_libxml.c
++++ b/src/raptor_libxml.c
+@@ -142,18 +142,111 @@ raptor_libxml_hasExternalSubset (void* user_data)
+
+ 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;
++ }
++
++ 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
+@@ -1331,6 +1331,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;
+
+@@ -1420,6 +1421,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] != 0);
+ break;
+
+diff --git a/src/raptor_rdfxml.c b/src/raptor_rdfxml.c
+--- a/src/raptor_rdfxml.c
++++ b/src/raptor_rdfxml.c
+@@ -1129,6 +1129,9 @@ raptor_rdfxml_parse_start(raptor_parser* rdf_parser)
+ 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 --git a/src/raptor_rss.c b/src/raptor_rss.c
+--- a/src/raptor_rss.c
++++ b/src/raptor_rss.c
+@@ -243,6 +243,9 @@ raptor_rss_parse_start(raptor_parser *rdf_parser)
+ 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 --git a/src/raptor_sax2.c b/src/raptor_sax2.c
+--- a/src/raptor_sax2.c
++++ b/src/raptor_sax2.c
+@@ -86,6 +86,8 @@ raptor_new_sax2(void* user_data, raptor_error_handlers* error_handlers)
+
+ sax2->user_data=user_data;
+
++ sax2->enabled = 1;
++
+ sax2->locator=error_handlers->locator;
+
+ sax2->error_handlers=error_handlers;
+@@ -593,6 +595,10 @@ raptor_sax2_set_feature(raptor_sax2 *sax2, raptor_feature feature, int value)
+ 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:
+@@ -660,6 +666,9 @@ raptor_sax2_start_element(void* user_data, const unsigned char *name,
+ unsigned char *xml_language=NULL;
+ raptor_uri *xml_base=NULL;
+
++ if(!sax2->enabled)
++ return;
++
+ #ifdef RAPTOR_XML_EXPAT
+ #ifdef EXPAT_UTF8_BOM_CRASH
+ sax2->tokens_count++;
+@@ -873,6 +882,9 @@ 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->enabled)
++ return;
++
+ #ifdef RAPTOR_XML_EXPAT
+ #ifdef EXPAT_UTF8_BOM_CRASH
+ sax2->tokens_count++;
+@@ -908,6 +920,10 @@ void
+ raptor_sax2_characters(void* user_data, const unsigned char *s, int len)
+ {
+ raptor_sax2* sax2=(raptor_sax2*)user_data;
++
++ if(!sax2->enabled)
++ return;
++
+ if(sax2->characters_handler)
+ sax2->characters_handler(sax2->user_data, sax2->current_element, s, len);
+ }
+@@ -918,6 +934,10 @@ void
+ raptor_sax2_cdata(void* user_data, const unsigned char *s, int len)
+ {
+ raptor_sax2* sax2=(raptor_sax2*)user_data;
++
++ if(!sax2->enabled)
++ return;
++
+ #ifdef RAPTOR_XML_EXPAT
+ #ifdef EXPAT_UTF8_BOM_CRASH
+ sax2->tokens_count++;
+@@ -934,6 +954,10 @@ void
+ raptor_sax2_comment(void* user_data, const unsigned char *s)
+ {
+ raptor_sax2* sax2=(raptor_sax2*)user_data;
++
++ if(!sax2->enabled)
++ return;
++
+ if(sax2->comment_handler)
+ sax2->comment_handler(sax2->user_data, sax2->current_element, s);
+ }
+@@ -949,6 +973,10 @@ raptor_sax2_unparsed_entity_decl(void* user_data,
+ const unsigned char* notationName)
+ {
+ raptor_sax2* sax2=(raptor_sax2*)user_data;
++
++ if(!sax2->enabled)
++ return;
++
+ if(sax2->unparsed_entity_decl_handler)
+ sax2->unparsed_entity_decl_handler(sax2->user_data,
+ entityName, base, systemId,
+@@ -965,6 +993,10 @@ raptor_sax2_external_entity_ref(void* user_data,
+ const unsigned char* publicId)
+ {
+ raptor_sax2* sax2=(raptor_sax2*)user_data;
++
++ if(!sax2->enabled)
++ return 0;
++
+ if(sax2->external_entity_ref_handler)
+ return sax2->external_entity_ref_handler(sax2->user_data,
+ context, base, systemId, publicId);
+diff --git a/src/raptor_serialize.c b/src/raptor_serialize.c
+--- a/src/raptor_serialize.c
++++ b/src/raptor_serialize.c
+@@ -756,6 +756,7 @@ raptor_serializer_set_feature(raptor_serializer *serializer,
+
+ /* Shared */
+ case RAPTOR_FEATURE_NO_NET:
++ case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+
+ /* XML writer features */
+ case RAPTOR_FEATURE_WRITER_AUTO_INDENT:
+@@ -853,6 +854,7 @@ raptor_serializer_set_feature_string(raptor_serializer *serializer,
+
+ /* Shared */
+ case RAPTOR_FEATURE_NO_NET:
++ case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+
+ /* XML writer features */
+ case RAPTOR_FEATURE_WRITER_AUTO_INDENT:
+@@ -957,6 +959,7 @@ raptor_serializer_get_feature(raptor_serializer *serializer,
+
+ /* Shared */
+ case RAPTOR_FEATURE_NO_NET:
++ case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+
+ /* XML writer features */
+ case RAPTOR_FEATURE_WRITER_AUTO_INDENT:
+@@ -1039,6 +1042,7 @@ raptor_serializer_get_feature_string(raptor_serializer *serializer,
+
+ /* Shared */
+ case RAPTOR_FEATURE_NO_NET:
++ case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+
+ /* XML writer features */
+ case RAPTOR_FEATURE_WRITER_AUTO_INDENT:
+diff --git a/src/raptor_turtle_writer.c b/src/raptor_turtle_writer.c
+--- a/src/raptor_turtle_writer.c
++++ b/src/raptor_turtle_writer.c
+@@ -737,6 +737,7 @@ raptor_turtle_writer_set_feature(raptor_turtle_writer *turtle_writer,
+
+ /* Shared */
+ case RAPTOR_FEATURE_NO_NET:
++ case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+
+ /* XML writer features */
+ case RAPTOR_FEATURE_RELATIVE_URIS:
+@@ -837,6 +838,7 @@ raptor_turtle_writer_get_feature(raptor_turtle_writer *turtle_writer,
+
+ /* Shared */
+ case RAPTOR_FEATURE_NO_NET:
++ case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+
+ /* XML writer features */
+ case RAPTOR_FEATURE_RELATIVE_URIS:
+diff --git a/src/raptor_xml_writer.c b/src/raptor_xml_writer.c
+--- a/src/raptor_xml_writer.c
++++ b/src/raptor_xml_writer.c
+@@ -854,6 +854,7 @@ raptor_xml_writer_set_feature(raptor_xml_writer *xml_writer,
+
+ /* Shared */
+ case RAPTOR_FEATURE_NO_NET:
++ case RAPTOR_FEATURE_LOAD_EXTERNAL_ENTITIES:
+
+ /* XML writer features */
+ case RAPTOR_FEATURE_RELATIVE_URIS:
+@@ -961,6 +962,7 @@ raptor_xml_writer_get_feature(raptor_xml_writer *xml_writer,
+
+ /* 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 279c6bb..3a3b5a4 100644
--- a/raptor.spec
+++ b/raptor.spec
@@ -1,11 +1,12 @@
Summary: Raptor RDF Parser Toolkit for Redland
Name: raptor
Version: 1.4.16
-Release: 2%{?dist}
+Release: 3%{?dist}
License: LGPLv2+ or ASL 2.0
Group: System Environment/Libraries
Source: http://download.librdf.org/source/raptor-%{version}.tar.gz
URL: http://librdf.org/raptor/
+Patch0: raptor-1.4.16-CVE-2012-0037.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: libxml2-devel libxslt-devel curl-devel
@@ -27,6 +28,7 @@ RDF/XML or N-Triples.
%prep
%setup -q
+%patch0 -p1 -b .CVE-2012-0037
%build
%configure --disable-static
@@ -66,6 +68,10 @@ rm -rf $RPM_BUILD_ROOT
%{_bindir}/raptor-config
%changelog
+* Thu Jul 12 2012 Jaroslav Škarvada <jskarvad at redhat.com> - 1.4.16-3
+- Fixed XML entity expansion that could lead to information disclosure (CVE-2012-0037)
+ Resolves: rhbz#805938
+
* Sat Feb 9 2008 Kevin Kofler <Kevin at tigcc.ticalc.org> 1.4.16-2
- Rebuild for GCC 4.3.
More information about the scm-commits
mailing list