File perl-XML-LibXML-CVE-2017-10672.patch of Package perl-XML-LibXML.6154
Index: XML-LibXML-2.0019/LibXML.xs
===================================================================
--- XML-LibXML-2.0019.orig/LibXML.xs
+++ XML-LibXML-2.0019/LibXML.xs
@@ -1008,6 +1008,40 @@ LibXML_test_node_name( xmlChar * name )
return(1);
}
+/* Assumes that the node has a proxy. */
+static void
+LibXML_reparent_removed_node(xmlNodePtr node) {
+ /*
+ * Attribute nodes can't be added to document fragments. Adding
+ * DTD nodes would cause a memory leak. So document and owner are
+ * set to NULL.
+ */
+ if (node->type != XML_ATTRIBUTE_NODE
+ && node->type != XML_DTD_NODE) {
+ ProxyNodePtr docfrag = PmmNewFragment(node->doc);
+ xmlAddChild(PmmNODE(docfrag), node);
+ PmmFixOwner(PmmPROXYNODE(node), docfrag);
+ }
+}
+
+static void
+LibXML_set_int_subset(xmlDocPtr doc, xmlNodePtr dtd) {
+ xmlNodePtr old_dtd = (xmlNodePtr)doc->intSubset;
+ if (old_dtd == dtd) {
+ return;
+ }
+
+ if (old_dtd != NULL) {
+ xmlUnlinkNode(old_dtd);
+
+ if (PmmPROXYNODE(old_dtd) == NULL) {
+ xmlFreeDtd((xmlDtdPtr)old_dtd);
+ }
+ }
+
+ doc->intSubset = (xmlDtdPtr)dtd;
+}
+
/* ****************************************************************
* XPathContext helper functions
* **************************************************************** */
@@ -4689,42 +4723,47 @@ replaceChild( self, nNode, oNode )
xmlNodePtr oNode
PREINIT:
xmlNodePtr ret = NULL;
- ProxyNodePtr docfrag = NULL;
CODE:
- if ( self->type == XML_DOCUMENT_NODE ) {
- switch ( nNode->type ) {
- case XML_ELEMENT_NODE:
- warn("replaceChild with an element on a document node not supported yet!");
- XSRETURN_UNDEF;
- break;
- case XML_DOCUMENT_FRAG_NODE:
- warn("replaceChild with a document fragment node on a document node not supported yet!");
- XSRETURN_UNDEF;
- break;
- case XML_TEXT_NODE:
- case XML_CDATA_SECTION_NODE:
- warn("replaceChild with a text node not supported on a document node!");
- XSRETURN_UNDEF;
- break;
- default:
- break;
+ // if newNode == oldNode or self == newNode then do nothing, just return nNode.
+ if(nNode == oNode || self == nNode ){
+ ret = nNode;
+ RETVAL = PmmNodeToSv(ret, PmmOWNERPO(PmmPROXYNODE(ret)));
+ }
+ else{
+ if ( self->type == XML_DOCUMENT_NODE ) {
+ switch ( nNode->type ) {
+ case XML_ELEMENT_NODE:
+ warn("replaceChild with an element on a document node not supported yet!");
+ XSRETURN_UNDEF;
+ break;
+ case XML_DOCUMENT_FRAG_NODE:
+ warn("replaceChild with a document fragment node on a document node not supported yet!");
+ XSRETURN_UNDEF;
+ break;
+ case XML_TEXT_NODE:
+ case XML_CDATA_SECTION_NODE:
+ warn("replaceChild with a text node not supported on a document node!");
+ XSRETURN_UNDEF;
+ break;
+ default:
+ break;
+ }
+ }
+ ret = domReplaceChild( self, nNode, oNode );
+ if (ret == NULL) {
+ XSRETURN_UNDEF;
+ }
+ else {
+ LibXML_reparent_removed_node(ret);
+ RETVAL = PmmNodeToSv(ret, PmmOWNERPO(PmmPROXYNODE(ret)));
+ if (nNode->type == XML_DTD_NODE) {
+ LibXML_set_int_subset(nNode->doc, nNode);
}
- }
- ret = domReplaceChild( self, nNode, oNode );
- if (ret == NULL) {
- XSRETURN_UNDEF;
- }
- else {
- docfrag = PmmNewFragment( self->doc );
- /* create document fragment */
- xmlAddChild( PmmNODE(docfrag), ret );
- RETVAL = PmmNodeToSv(ret, docfrag);
-
if ( nNode->_private != NULL ) {
PmmFixOwner( PmmPROXYNODE(nNode),
PmmOWNERPO(PmmPROXYNODE(self)) );
}
- PmmFixOwner( SvPROXYNODE(RETVAL), docfrag );
+ }
}
OUTPUT:
RETVAL
Index: XML-LibXML-2.0019/dom.c
===================================================================
--- XML-LibXML-2.0019.orig/dom.c
+++ XML-LibXML-2.0019/dom.c
@@ -794,7 +794,7 @@ domReplaceChild( xmlNodePtr self, xmlNod
return NULL;
if ( new == old )
- return new;
+ return NULL;
if ( new == NULL ) {
/* level2 sais nothing about this case :( */
Index: XML-LibXML-2.0019/t/ufa.t
===================================================================
--- /dev/null
+++ XML-LibXML-2.0019/t/ufa.t
@@ -0,0 +1,12 @@
+use Test::More;
+use XML::LibXML;
+
+#test bug use after free in function replaceChild
+BEGIN { $| = 1 }
+my $data='<mipu94><pwn4fun><ufanode>-------------------------------------------------------tadinhsung-at-gmail-dot-com-----------------------------------------------------</ufanode></pwn4fun></mipu94>';
+my $parser = XML::LibXML->new();
+my $info = $parser->load_xml(string=>$data) or die;
+my $root = $info->findnodes("mipu94")->[0];
+my $ufanode = $root->findnodes("pwn4fun/ufanode")->[0];
+ok($root->replaceChild($ufanode,$ufanode),"Test UFA in replaceChild");
+done_testing();