Browse Source

Ticket #48226 - In MMR, double free coould occur under some special condition

Description: commit a0f8e0f981a046882db299a7a6d6d1c01bc19571 introduced
a memory leak in the case of resolve_attribute_state_present_to_deleted.
In the case, csnset is not consumed.  Thus, it has to be freed by csnset_
free.

https://fedorahosted.org/389/ticket/48226

Reviewed by [email protected] (Thank you, Mark!!)
Noriko Hosoi 10 years ago
parent
commit
b26ec6762f
2 changed files with 12 additions and 11 deletions
  1. 11 11
      ldap/servers/slapd/entrywsi.c
  2. 1 0
      ldap/servers/slapd/valueset.c

+ 11 - 11
ldap/servers/slapd/entrywsi.c

@@ -1280,23 +1280,23 @@ resolve_attribute_state_present_to_deleted(Slapi_Entry *e, Slapi_Attr *a, Slapi_
 	const CSN *adcsn= attr_get_deletion_csn(a);
 	int i;
 	if ( valuestoupdate != NULL && valuestoupdate[0] != NULL ) {
-	for (i=0;valuestoupdate[i]!=NULL;++i) {
-	/* This call ensures that the value does not contain a deletion_csn
-	 * which is before the presence_csn or distinguished_csn of the value.
-	 */ 
-	    purge_attribute_state_multi_valued(a, valuestoupdate[i]);
-		vdcsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_DELETED);
-		vucsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_UPDATED);
-		deletedcsn= csn_max(vdcsn, adcsn);
+		for (i=0;valuestoupdate[i]!=NULL;++i) {
+			/* This call ensures that the value does not contain a deletion_csn
+			 * which is before the presence_csn or distinguished_csn of the value.
+			 */ 
+			purge_attribute_state_multi_valued(a, valuestoupdate[i]);
+			vdcsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_DELETED);
+			vucsn= value_get_csn(valuestoupdate[i], CSN_TYPE_VALUE_UPDATED);
+			deletedcsn= csn_max(vdcsn, adcsn);
 			if(csn_compare(vucsn,deletedcsn)<0) 
 			{
-	        		if(!value_distinguished_at_csn(e, a, valuestoupdate[i], deletedcsn))
+				if(!value_distinguished_at_csn(e, a, valuestoupdate[i], deletedcsn))
 				{
 					entry_present_value_to_deleted_value(a,valuestoupdate[i]);
 				}
 			}
-		valuestoupdate[i]->v_csnset = NULL;
-	}
+			csnset_free(&valuestoupdate[i]->v_csnset);
+		}
 	}
 }
 

+ 1 - 0
ldap/servers/slapd/valueset.c

@@ -1416,6 +1416,7 @@ valueset_update_csn_for_valuearray_ext(Slapi_ValueSet *vs, const Slapi_Attr *a,
 			{
 				value_update_csn(v,t,csn);
 				if (csnref_updated) {
+					csnset_free(&valuestoupdate[i]->v_csnset);
 					valuestoupdate[i]->v_csnset = csnset_dup(value_get_csnset(v));
 				}
 				valuearrayfast_add_value_passin(&vaf_valuesupdated,valuestoupdate[i]);