[xmlsec] Fix valgrind's invalid read with chained XPath transforms (based on patch from Frank Gross)



commit 8ee4fbabcd651f01c6ec1b6aef70853f27db65a8
Author: Aleksey Sanin <aleksey aleksey com>
Date:   Wed Jan 13 13:03:25 2010 -0800

    Fix valgrind's invalid read with chained XPath transforms (based on patch from Frank Gross)

 ChangeLog     |    4 ++++
 src/nodeset.c |   25 ++++++++++++++++++-------
 2 files changed, 22 insertions(+), 7 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b63503c..2baaef2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2010-01-13  Aleksey Sanin  <aleksey aleksey com>
+	* Fix valgrind's invalid read with chained XPath transforms (based
+	on patch from Frank Gross).
+
 2009-09-05  Aleksey Sanin  <aleksey aleksey com>
 	* preparation for 1.2.14 release
 
diff --git a/src/nodeset.c b/src/nodeset.c
index 74c2d5b..a5c0a36 100644
--- a/src/nodeset.c
+++ b/src/nodeset.c
@@ -78,29 +78,37 @@ xmlSecNodeSetCreate(xmlDocPtr doc, xmlNodeSetPtr nodes, xmlSecNodeSetType type)
 void
 xmlSecNodeSetDestroy(xmlSecNodeSetPtr nset) {
     xmlSecNodeSetPtr tmp;
+    xmlDocPtr destroyDoc = NULL;
 
     xmlSecAssert(nset != NULL);
-    	
+
     while((tmp = nset) != NULL) {
 	if((nset->next != NULL) && (nset->next != nset)) {
 	    nset->next->prev = nset->prev;
-	    nset->prev->next = nset->next;	    
+	    nset->prev->next = nset->next;
 	    nset = nset->next;
 	} else {
 	    nset = NULL;
 	}
 	
 	if(tmp->nodes != NULL) {
-    	    xmlXPathFreeNodeSet(tmp->nodes);
+	    xmlXPathFreeNodeSet(tmp->nodes);
 	}
 	if(tmp->children != NULL) {
 	    xmlSecNodeSetDestroy(tmp->children);
 	}
 	if((tmp->doc != NULL) && (tmp->destroyDoc != 0)) {
-	    xmlFreeDoc(tmp->doc);
+	    /* all nodesets should belong to the same doc */
+	    xmlSecAssert((destroyDoc == NULL) || (tmp->doc == destroyDoc));
+	    destroyDoc = tmp->doc; /* can't destroy here because other node sets can refer to it */
 	}
 	memset(tmp, 0,  sizeof(xmlSecNodeSet));
-        xmlFree(tmp);
+	xmlFree(tmp);
+    }
+
+    /* finally, destroy the doc if needed */
+    if(destroyDoc != NULL) {
+	xmlFreeDoc(destroyDoc);
     }
 }
 
@@ -272,11 +280,14 @@ xmlSecNodeSetAdd(xmlSecNodeSetPtr nset, xmlSecNodeSetPtr newNSet,
     if(nset == NULL) {
 	return(newNSet);
     }
-        
+
+    /* all nodesets should belong to the same doc */
+    xmlSecAssert2(nset->doc == newNSet->doc, NULL);
+
     newNSet->next = nset;
     newNSet->prev = nset->prev;
     nset->prev->next = newNSet;
-    nset->prev 	     = newNSet;
+    nset->prev       = newNSet;
     return(nset);
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]